From 920ed4090e5ec221a0d699af8e5887ca156e6601 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 6 Apr 2026 14:19:02 +0200 Subject: [PATCH 1/5] #855 Remove dynamic_cast on Rim type from RifMultipleSummaryReaders Add virtual isCalculated() to RifSummaryReaderInterface (defaults false), override in RifCalculatedSummaryCurveReader to return true. Replace dynamic_cast checks with isCalculated(), removing the Rim header dependency from RifMultipleSummaryReaders. --- .../FileInterface/RifMultipleSummaryReaders.cpp | 10 +++++----- .../FileInterface/RifSummaryReaderInterface.h | 2 ++ .../Summary/RimCalculatedSummaryCurveReader.h | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ApplicationLibCode/FileInterface/RifMultipleSummaryReaders.cpp b/ApplicationLibCode/FileInterface/RifMultipleSummaryReaders.cpp index c36d9ce7413..8619db9e133 100644 --- a/ApplicationLibCode/FileInterface/RifMultipleSummaryReaders.cpp +++ b/ApplicationLibCode/FileInterface/RifMultipleSummaryReaders.cpp @@ -18,7 +18,7 @@ #include "RifMultipleSummaryReaders.h" -#include "RimCalculatedSummaryCurveReader.h" +#include "cvfAssert.h" //-------------------------------------------------------------------------------------------------- /// @@ -39,8 +39,8 @@ void RifMultipleSummaryReaders::addReader( std::unique_ptr( first.get() ) != nullptr; - bool isSecondCalc = dynamic_cast( second.get() ) != nullptr; + bool isFirstCalc = first->isCalculated(); + bool isSecondCalc = second->isCalculated(); if ( isFirstCalc && !isSecondCalc ) return true; if ( !isFirstCalc && isSecondCalc ) return false; return first->serialNumber() < second->serialNumber(); @@ -153,8 +153,8 @@ void RifMultipleSummaryReaders::createAndSetAddresses() auto nativeReaderFirst = []( const auto& first, const auto& second ) { - bool isFirstCalc = dynamic_cast( first ) != nullptr; - bool isSecondCalc = dynamic_cast( second ) != nullptr; + bool isFirstCalc = first->isCalculated(); + bool isSecondCalc = second->isCalculated(); if ( isFirstCalc && !isSecondCalc ) return false; if ( !isFirstCalc && isSecondCalc ) return true; return first->serialNumber() < second->serialNumber(); diff --git a/ApplicationLibCode/FileInterface/RifSummaryReaderInterface.h b/ApplicationLibCode/FileInterface/RifSummaryReaderInterface.h index a05f488c701..8fcbde4038d 100644 --- a/ApplicationLibCode/FileInterface/RifSummaryReaderInterface.h +++ b/ApplicationLibCode/FileInterface/RifSummaryReaderInterface.h @@ -52,6 +52,8 @@ class RifSummaryReaderInterface virtual std::string unitName( const RifEclipseSummaryAddress& resultAddress ) const = 0; virtual RiaDefines::EclipseUnitSystem unitSystem() const = 0; + virtual bool isCalculated() const { return false; } + virtual void createAndSetAddresses(); void createAddressesIfRequired(); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.h b/ApplicationLibCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.h index a425ce2dcd8..64775a984c7 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.h @@ -39,6 +39,8 @@ class RifCalculatedSummaryCurveReader : public RifSummaryReaderInterface void createAndSetAddresses() override; + bool isCalculated() const override { return true; } + RiaDefines::EclipseUnitSystem unitSystem() const override; private: From a85381f1426133e8dd286ac2667d0f1e10246f3c Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 6 Apr 2026 14:25:58 +0200 Subject: [PATCH 2/5] #855 A6: RifThermalFractureTemplateSurfaceExporter: take RigThermalFractureDefinition directly Remove RimThermalFractureTemplate dependency by accepting const RigThermalFractureDefinition& instead. Caller extracts fractureDefinition() before calling the exporter. --- .../RifThermalFractureTemplateSurfaceExporter.cpp | 10 ++++------ .../RifThermalFractureTemplateSurfaceExporter.h | 6 ++---- .../RimcThermalFractureTemplate.cpp | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.cpp b/ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.cpp index 654de8ae591..b4a4a52e1a6 100644 --- a/ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.cpp +++ b/ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.cpp @@ -19,7 +19,6 @@ #include "RifThermalFractureTemplateSurfaceExporter.h" #include "RigThermalFractureDefinition.h" -#include "RimThermalFractureTemplate.h" #include #include @@ -27,12 +26,11 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifThermalFractureTemplateSurfaceExporter::writeToFile( gsl::not_null thermalFractureTemplate, - int timeStepIndex, - const QString& filePath ) +bool RifThermalFractureTemplateSurfaceExporter::writeToFile( const RigThermalFractureDefinition& fractureDefinition, + int timeStepIndex, + const QString& filePath ) { - auto fractureData = thermalFractureTemplate->fractureDefinition(); - CAF_ASSERT( fractureData ); + const RigThermalFractureDefinition* fractureData = &fractureDefinition; auto numNodes = fractureData->numNodes(); auto numTimeSteps = fractureData->numTimeSteps(); diff --git a/ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.h b/ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.h index c9749b6ec93..0eae63d2d08 100644 --- a/ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.h +++ b/ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.h @@ -18,9 +18,7 @@ #pragma once -#include - -class RimThermalFractureTemplate; +class RigThermalFractureDefinition; class QString; //================================================================================================== @@ -29,5 +27,5 @@ class QString; class RifThermalFractureTemplateSurfaceExporter { public: - static bool writeToFile( gsl::not_null thermalFractureTemplate, int timeStep, const QString& filePath ); + static bool writeToFile( const RigThermalFractureDefinition& fractureDefinition, int timeStep, const QString& filePath ); }; diff --git a/ApplicationLibCode/ProjectDataModelCommands/RimcThermalFractureTemplate.cpp b/ApplicationLibCode/ProjectDataModelCommands/RimcThermalFractureTemplate.cpp index f02e069f2a0..0c855658d4d 100644 --- a/ApplicationLibCode/ProjectDataModelCommands/RimcThermalFractureTemplate.cpp +++ b/ApplicationLibCode/ProjectDataModelCommands/RimcThermalFractureTemplate.cpp @@ -47,7 +47,7 @@ std::expected RimcThermalFractureTemplate_export { RimThermalFractureTemplate* thermalFracture = self(); if ( thermalFracture && thermalFracture->fractureDefinition() ) - RifThermalFractureTemplateSurfaceExporter::writeToFile( thermalFracture, m_timeStep(), m_filePath() ); + RifThermalFractureTemplateSurfaceExporter::writeToFile( *thermalFracture->fractureDefinition(), m_timeStep(), m_filePath() ); return nullptr; } From 10f26091895d07a98119470ea057309cfb072632 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 6 Apr 2026 14:28:26 +0200 Subject: [PATCH 3/5] #855 A1-A3+A5: Remove RimStimPlanModel dependency from StimPlan FRK exporters AsymmetricFrkExporter: accept 5 primitives instead of RimStimPlanModel*. DeviationFrkExporter: accept const RigWellPath* and use RigWellPath overload. PerfsFrkExporter: accept primitives + const RigWellPath*; computeMeasuredDepthForPosition and calculateTopAndBottomMeasuredDepth now take RigWellPath* directly. StimPlanModelExporter (orchestrator): extracts data from RimStimPlanModel and passes to updated sub-exporters. RimWellPath dependency reduced to orchestrator only. --- .../RifStimPlanModelAsymmetricFrkExporter.cpp | 17 +++++----- .../RifStimPlanModelAsymmetricFrkExporter.h | 9 ++++-- .../RifStimPlanModelDeviationFrkExporter.cpp | 13 +++----- .../RifStimPlanModelDeviationFrkExporter.h | 4 +-- .../RifStimPlanModelExporter.cpp | 22 +++++++++++-- .../RifStimPlanModelGeologicalFrkExporter.cpp | 5 ++- .../RifStimPlanModelPerfsFrkExporter.cpp | 31 ++++++++----------- .../RifStimPlanModelPerfsFrkExporter.h | 9 +++--- 8 files changed, 60 insertions(+), 50 deletions(-) diff --git a/ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.cpp b/ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.cpp index aa8f4d9be1d..6376f312928 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.cpp +++ b/ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.cpp @@ -20,15 +20,18 @@ #include "RiaEclipseUnitTools.h" -#include "RimStimPlanModel.h" - #include #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifStimPlanModelAsymmetricFrkExporter::writeToFile( RimStimPlanModel* stimPlanModel, const QString& filepath ) +bool RifStimPlanModelAsymmetricFrkExporter::writeToFile( double formationDip, + bool hasBarrier, + double distanceToBarrier, + double barrierDip, + int wellPenetrationLayer, + const QString& filepath ) { QFile data( filepath ); if ( !data.open( QFile::WriteOnly | QFile::Truncate ) ) @@ -39,13 +42,7 @@ bool RifStimPlanModelAsymmetricFrkExporter::writeToFile( RimStimPlanModel* stimP QTextStream stream( &data ); appendHeaderToStream( stream ); - double bedDipDeg = stimPlanModel->formationDip(); - bool hasBarrier = stimPlanModel->hasBarrier(); - double distanceToBarrier = stimPlanModel->distanceToBarrier(); - double barrierDip = stimPlanModel->barrierDip(); - int wellPenetrationLayer = stimPlanModel->wellPenetrationLayer(); - - appendBarrierDataToStream( stream, bedDipDeg, hasBarrier, RiaEclipseUnitTools::meterToFeet( distanceToBarrier ), barrierDip, wellPenetrationLayer ); + appendBarrierDataToStream( stream, formationDip, hasBarrier, RiaEclipseUnitTools::meterToFeet( distanceToBarrier ), barrierDip, wellPenetrationLayer ); appendFooterToStream( stream ); diff --git a/ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.h b/ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.h index 57a3b3553df..18bf7c13362 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.h +++ b/ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.h @@ -18,8 +18,6 @@ #pragma once -class RimStimPlanModel; - class QString; class QTextStream; @@ -29,7 +27,12 @@ class QTextStream; class RifStimPlanModelAsymmetricFrkExporter { public: - static bool writeToFile( RimStimPlanModel* stimPlanModel, const QString& filepath ); + static bool writeToFile( double formationDip, + bool hasBarrier, + double distanceToBarrier, + double barrierDip, + int wellPenetrationLayer, + const QString& filepath ); private: static void appendHeaderToStream( QTextStream& stream ); diff --git a/ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.cpp b/ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.cpp index c2d5aa88f3b..59bfebfde8d 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.cpp +++ b/ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.cpp @@ -20,9 +20,7 @@ #include "RiaEclipseUnitTools.h" -#include "RimStimPlanModel.h" -#include "RimWellPath.h" - +#include "Well/RigWellPath.h" #include "Well/RigWellPathGeometryExporter.h" #include @@ -31,9 +29,8 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifStimPlanModelDeviationFrkExporter::writeToFile( RimStimPlanModel* stimPlanModel, const QString& filepath ) +bool RifStimPlanModelDeviationFrkExporter::writeToFile( const RigWellPath* wellPath, const QString& filepath ) { - RimWellPath* wellPath = stimPlanModel->wellPath(); if ( !wellPath ) { return false; @@ -48,13 +45,13 @@ bool RifStimPlanModelDeviationFrkExporter::writeToFile( RimStimPlanModel* stimPl QTextStream stream( &data ); appendHeaderToStream( stream ); - bool showTextMdRkb = false; - double mdStepSize = 5.0; + double mdStepSize = 5.0; + double rkbOffset = 0.0; std::vector xValues; std::vector yValues; std::vector tvdValues; std::vector mdValues; - RigWellPathGeometryExporter::computeWellPathDataForExport( wellPath, mdStepSize, xValues, yValues, tvdValues, mdValues, showTextMdRkb ); + RigWellPathGeometryExporter::computeWellPathDataForExport( *wellPath, mdStepSize, rkbOffset, xValues, yValues, tvdValues, mdValues ); convertFromMeterToFeet( mdValues ); convertFromMeterToFeet( tvdValues ); diff --git a/ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.h b/ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.h index 05edbc04e56..be7b97a90dc 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.h +++ b/ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.h @@ -20,7 +20,7 @@ #include -class RimStimPlanModel; +class RigWellPath; class QString; class QTextStream; @@ -30,7 +30,7 @@ class QTextStream; class RifStimPlanModelDeviationFrkExporter { public: - static bool writeToFile( RimStimPlanModel* stimPlanModel, const QString& filepath ); + static bool writeToFile( const RigWellPath* wellPath, const QString& filepath ); static void fixupDepthValuesForExport( const std::vector& tvdValues, const std::vector& mdValues, diff --git a/ApplicationLibCode/FileInterface/RifStimPlanModelExporter.cpp b/ApplicationLibCode/FileInterface/RifStimPlanModelExporter.cpp index 6b08eb727c9..461b4898e54 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanModelExporter.cpp +++ b/ApplicationLibCode/FileInterface/RifStimPlanModelExporter.cpp @@ -24,14 +24,30 @@ #include "RifStimPlanModelPerfsFrkExporter.h" #include "RimStimPlanModel.h" +#include "RimWellPath.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RifStimPlanModelExporter::writeToDirectory( RimStimPlanModel* stimPlanModel, bool useDetailedFluidLoss, const QString& directoryPath ) { + RimWellPath* wellPath = stimPlanModel->wellPath(); + + bool isTransverse = ( stimPlanModel->fractureOrientation() == RimStimPlanModel::FractureOrientation::TRANSVERSE_WELL_PATH || + stimPlanModel->fractureOrientation() == RimStimPlanModel::FractureOrientation::AZIMUTH ); + return RifStimPlanModelGeologicalFrkExporter::writeToFile( stimPlanModel, useDetailedFluidLoss, directoryPath + "/Geological.frk" ) && - RifStimPlanModelDeviationFrkExporter::writeToFile( stimPlanModel, directoryPath + "/Deviation.frk" ) && - RifStimPlanModelPerfsFrkExporter::writeToFile( stimPlanModel, directoryPath + "/Perfs.frk" ) && - RifStimPlanModelAsymmetricFrkExporter::writeToFile( stimPlanModel, directoryPath + "/Asymmetric.frk" ); + RifStimPlanModelDeviationFrkExporter::writeToFile( wellPath ? wellPath->wellPathGeometry() : nullptr, + directoryPath + "/Deviation.frk" ) && + RifStimPlanModelPerfsFrkExporter::writeToFile( isTransverse, + stimPlanModel->perforationLength(), + stimPlanModel->anchorPosition(), + wellPath ? wellPath->wellPathGeometry() : nullptr, + directoryPath + "/Perfs.frk" ) && + RifStimPlanModelAsymmetricFrkExporter::writeToFile( stimPlanModel->formationDip(), + stimPlanModel->hasBarrier(), + stimPlanModel->distanceToBarrier(), + stimPlanModel->barrierDip(), + stimPlanModel->wellPenetrationLayer(), + directoryPath + "/Asymmetric.frk" ); } diff --git a/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp b/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp index f782733fdd0..016c0265395 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp +++ b/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp @@ -28,6 +28,7 @@ #include "RimStimPlanModel.h" #include "RimStimPlanModelCalculator.h" +#include "RimWellPath.h" #include "caf.h" @@ -156,7 +157,9 @@ bool RifStimPlanModelGeologicalFrkExporter::writeToFile( RimStimPlanModel* stimP values["dpthend"] = depthEnd; auto [perforationTop, perforationBottom] = - RifStimPlanModelPerfsFrkExporter::calculateTopAndBottomMeasuredDepth( stimPlanModel, stimPlanModel->wellPath() ); + RifStimPlanModelPerfsFrkExporter::calculateTopAndBottomMeasuredDepth( stimPlanModel->wellPath()->wellPathGeometry(), + stimPlanModel->perforationLength(), + stimPlanModel->anchorPosition() ); values["perfs"] = createPerforationValues( depthStart, depthEnd, diff --git a/ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.cpp b/ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.cpp index 8193d6a07fb..5392d8bccbc 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.cpp +++ b/ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.cpp @@ -21,9 +21,6 @@ #include "RiaEclipseUnitTools.h" #include "RiaLogging.h" -#include "RimStimPlanModel.h" -#include "RimWellPath.h" - #include "Well/RigWellPath.h" #include "Well/RigWellPathGeometryTools.h" @@ -37,9 +34,12 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifStimPlanModelPerfsFrkExporter::writeToFile( RimStimPlanModel* stimPlanModel, const QString& filepath ) +bool RifStimPlanModelPerfsFrkExporter::writeToFile( bool isTransverse, + double perforationLength, + const cvf::Vec3d& anchorPosition, + const RigWellPath* wellPath, + const QString& filepath ) { - RimWellPath* wellPath = stimPlanModel->wellPath(); if ( !wellPath ) { return false; @@ -54,13 +54,10 @@ bool RifStimPlanModelPerfsFrkExporter::writeToFile( RimStimPlanModel* stimPlanMo QTextStream stream( &data ); appendHeaderToStream( stream ); - bool isTransverse = ( stimPlanModel->fractureOrientation() == RimStimPlanModel::FractureOrientation::TRANSVERSE_WELL_PATH || - stimPlanModel->fractureOrientation() == RimStimPlanModel::FractureOrientation::AZIMUTH ); - appendFractureOrientationToStream( stream, isTransverse ); // Unit: meter - auto [topMD, bottomMD] = calculateTopAndBottomMeasuredDepth( stimPlanModel, wellPath ); + auto [topMD, bottomMD] = calculateTopAndBottomMeasuredDepth( wellPath, perforationLength, anchorPosition ); appendPerforationToStream( stream, 1, RiaEclipseUnitTools::meterToFeet( topMD ), RiaEclipseUnitTools::meterToFeet( bottomMD ) ); appendFooterToStream( stream ); @@ -110,12 +107,11 @@ void RifStimPlanModelPerfsFrkExporter::appendFooterToStream( QTextStream& stream //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RifStimPlanModelPerfsFrkExporter::computeMeasuredDepthForPosition( const RimWellPath* wellPath, const cvf::Vec3d& position ) +double RifStimPlanModelPerfsFrkExporter::computeMeasuredDepthForPosition( const RigWellPath* wellPath, const cvf::Vec3d& position ) { - const RigWellPath* wellPathGeometry = wellPath->wellPathGeometry(); - const std::vector& mdValuesOfWellPath = wellPathGeometry->measuredDepths(); - const std::vector& tvdValuesOfWellPath = wellPathGeometry->trueVerticalDepths(); + const std::vector& mdValuesOfWellPath = wellPath->measuredDepths(); + const std::vector& tvdValuesOfWellPath = wellPath->trueVerticalDepths(); const double targetTvd = -position.z(); std::vector tvDepthValues; @@ -154,12 +150,11 @@ double RifStimPlanModelPerfsFrkExporter::computeMeasuredDepthForPosition( const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::pair RifStimPlanModelPerfsFrkExporter::calculateTopAndBottomMeasuredDepth( RimStimPlanModel* stimPlanModel, - RimWellPath* wellPath ) +std::pair RifStimPlanModelPerfsFrkExporter::calculateTopAndBottomMeasuredDepth( const RigWellPath* wellPath, + double perforationLength, + const cvf::Vec3d& anchorPosition ) { - double perforationLength = stimPlanModel->perforationLength(); - - double anchorPositionMD = computeMeasuredDepthForPosition( wellPath, stimPlanModel->anchorPosition() ); + double anchorPositionMD = computeMeasuredDepthForPosition( wellPath, anchorPosition ); double topMD = anchorPositionMD - ( perforationLength / 2.0 ); double bottomMD = anchorPositionMD + ( perforationLength / 2.0 ); diff --git a/ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.h b/ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.h index fda314f77b3..675ab630ca8 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.h +++ b/ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.h @@ -22,8 +22,7 @@ #include -class RimStimPlanModel; -class RimWellPath; +class RigWellPath; class QString; class QTextStream; @@ -34,11 +33,11 @@ class QTextStream; class RifStimPlanModelPerfsFrkExporter { public: - static bool writeToFile( RimStimPlanModel* stimPlanModel, const QString& filepath ); + static bool writeToFile( bool isTransverse, double perforationLength, const cvf::Vec3d& anchorPosition, const RigWellPath* wellPath, const QString& filepath ); - static std::pair calculateTopAndBottomMeasuredDepth( RimStimPlanModel* stimPlanModel, RimWellPath* wellPath ); + static std::pair calculateTopAndBottomMeasuredDepth( const RigWellPath* wellPath, double perforationLength, const cvf::Vec3d& anchorPosition ); - static double computeMeasuredDepthForPosition( const RimWellPath* wellPath, const cvf::Vec3d& position ); + static double computeMeasuredDepthForPosition( const RigWellPath* wellPath, const cvf::Vec3d& position ); private: static void appendHeaderToStream( QTextStream& stream ); From 0be98b0596be79870bf2a585b585f117e10bdf13 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 6 Apr 2026 14:30:41 +0200 Subject: [PATCH 4/5] #855 C1: RifReaderRegularGridModel: accept Rig types instead of RimEclipseCase writeCache takes RigCaseCellResultsData* and RigEclipseCaseData* directly. ensureDataIsReadFromCache takes RigCaseCellResultsData* directly. Caller (RimRegularGridCase) extracts the Rig objects before calling. --- .../FileInterface/RifReaderRegularGridModel.cpp | 16 ++++------------ .../FileInterface/RifReaderRegularGridModel.h | 7 ++++--- .../ProjectDataModel/RimRegularGridCase.cpp | 6 ++++-- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.cpp b/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.cpp index 97f6c678595..d1a46b3c8a3 100644 --- a/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.cpp @@ -30,17 +30,15 @@ #include "RigEclipseCaseData.h" #include "RigEclipseResultAddress.h" -#include "RimEclipseCase.h" - #include #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifReaderRegularGridModel::writeCache( const QString& fileName, RimEclipseCase* eclipseCase ) +void RifReaderRegularGridModel::writeCache( const QString& fileName, RigCaseCellResultsData* rigCellResults, RigEclipseCaseData* eclipseCaseData ) { - if ( !eclipseCase ) return; + if ( !rigCellResults || !eclipseCaseData ) return; QFileInfo storageFileInfo( fileName ); if ( storageFileInfo.exists() ) @@ -58,9 +56,6 @@ void RifReaderRegularGridModel::writeCache( const QString& fileName, RimEclipseC return; } - auto rigCellResults = eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL ); - if ( !rigCellResults ) return; - auto resultNames = rigCellResults->resultNames( RiaDefines::ResultCatType::GENERATED ); std::vector keywords; @@ -70,7 +65,7 @@ void RifReaderRegularGridModel::writeCache( const QString& fileName, RimEclipseC } const bool writeEchoKeywords = false; - if ( !RifEclipseInputFileTools::exportKeywords( fileName, eclipseCase->eclipseCaseData(), keywords, writeEchoKeywords ) ) + if ( !RifEclipseInputFileTools::exportKeywords( fileName, eclipseCaseData, keywords, writeEchoKeywords ) ) { RiaLogging::error( "Error detected when writing the cache file : " + fileName ); } @@ -79,11 +74,8 @@ void RifReaderRegularGridModel::writeCache( const QString& fileName, RimEclipseC //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifReaderRegularGridModel::ensureDataIsReadFromCache( const QString& fileName, RimEclipseCase* eclipseCase ) +void RifReaderRegularGridModel::ensureDataIsReadFromCache( const QString& fileName, RigCaseCellResultsData* rigCellResults ) { - if ( !eclipseCase ) return; - - auto rigCellResults = eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL ); if ( !rigCellResults ) return; // Early return if we have already read the data from the cache diff --git a/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h b/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h index 08b5067afd3..4f414a74b0f 100644 --- a/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h +++ b/ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h @@ -20,11 +20,12 @@ #include -class RimEclipseCase; +class RigCaseCellResultsData; +class RigEclipseCaseData; namespace RifReaderRegularGridModel { -void writeCache( const QString& fileName, RimEclipseCase* eclipseCase ); -void ensureDataIsReadFromCache( const QString& fileName, RimEclipseCase* eclipseCase ); +void writeCache( const QString& fileName, RigCaseCellResultsData* rigCellResults, RigEclipseCaseData* eclipseCaseData ); +void ensureDataIsReadFromCache( const QString& fileName, RigCaseCellResultsData* rigCellResults ); }; // namespace RifReaderRegularGridModel diff --git a/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp b/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp index c49771ea524..3f047cd7166 100644 --- a/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp @@ -18,6 +18,8 @@ #include "RimRegularGridCase.h" +#include "RiaDefines.h" + #include "RifReaderRegularGridModel.h" #include "RigCaseCellResultsData.h" @@ -113,7 +115,7 @@ void RimRegularGridCase::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder void RimRegularGridCase::setupBeforeSave() { auto fileName = cacheFileName(); - RifReaderRegularGridModel::writeCache( fileName, this ); + RifReaderRegularGridModel::writeCache( fileName, results( RiaDefines::PorosityModelType::MATRIX_MODEL ), eclipseCaseData() ); } //-------------------------------------------------------------------------------------------------- @@ -137,7 +139,7 @@ bool RimRegularGridCase::openEclipseGridFile() } auto fileName = cacheFileName(); - RifReaderRegularGridModel::ensureDataIsReadFromCache( fileName, this ); + RifReaderRegularGridModel::ensureDataIsReadFromCache( fileName, results( RiaDefines::PorosityModelType::MATRIX_MODEL ) ); return true; } From da8409c53521bee316a31db13a7b9e0e8ede5fef Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 6 Apr 2026 14:35:11 +0200 Subject: [PATCH 5/5] #855 C3: RifReaderEnsembleStatisticsRft: take RifReaderRftInterface* vector instead of RimSummaryEnsemble* Store pre-collected RFT readers instead of the ensemble. All iteration methods now operate on m_rftReaders directly, removing the RimSummaryCase and RimSummaryEnsemble dependencies from the Rif class. The Rim caller (RimWellRftEnsembleCurveSet) extracts non-null readers before constructing. --- .../RifReaderEnsembleStatisticsRft.cpp | 89 +++++-------------- .../RifReaderEnsembleStatisticsRft.h | 10 ++- .../Flow/RimWellRftEnsembleCurveSet.cpp | 12 ++- 3 files changed, 41 insertions(+), 70 deletions(-) diff --git a/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp b/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp index 05f8517d480..7889aca2f1e 100644 --- a/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp @@ -24,17 +24,13 @@ #include "Well/RigEclipseWellLogExtractor.h" #include "Well/RigWellPath.h" -#include "RimSummaryCase.h" -#include "RimSummaryEnsemble.h" -#include "RimTools.h" - #include "cafAssert.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifReaderEnsembleStatisticsRft::RifReaderEnsembleStatisticsRft( const RimSummaryEnsemble* summaryCaseCollection, RimEclipseCase* eclipseCase ) - : m_summaryCaseCollection( summaryCaseCollection ) +RifReaderEnsembleStatisticsRft::RifReaderEnsembleStatisticsRft( std::vector rftReaders, RimEclipseCase* eclipseCase ) + : m_rftReaders( std::move( rftReaders ) ) , m_eclipseCase( eclipseCase ) { } @@ -44,16 +40,11 @@ RifReaderEnsembleStatisticsRft::RifReaderEnsembleStatisticsRft( const RimSummary //-------------------------------------------------------------------------------------------------- std::set RifReaderEnsembleStatisticsRft::eclipseRftAddresses() { - if ( !m_summaryCaseCollection ) return {}; - std::set allAddresses; - for ( auto summaryCase : m_summaryCaseCollection->allSummaryCases() ) + for ( auto reader : m_rftReaders ) { - if ( summaryCase->rftReader() ) - { - std::set addresses = summaryCase->rftReader()->eclipseRftAddresses(); - allAddresses.insert( addresses.begin(), addresses.end() ); - } + std::set addresses = reader->eclipseRftAddresses(); + allAddresses.insert( addresses.begin(), addresses.end() ); } std::set statisticsAddresses; @@ -84,7 +75,7 @@ std::set RifReaderEnsembleStatisticsRft::eclipseRftAddress //-------------------------------------------------------------------------------------------------- void RifReaderEnsembleStatisticsRft::values( const RifEclipseRftAddress& rftAddress, std::vector* values ) { - if ( !m_summaryCaseCollection ) return; + if ( m_rftReaders.empty() ) return; auto it = m_cachedValues.find( rftAddress ); if ( it == m_cachedValues.end() ) @@ -102,16 +93,11 @@ void RifReaderEnsembleStatisticsRft::values( const RifEclipseRftAddress& rftAddr //-------------------------------------------------------------------------------------------------- std::set RifReaderEnsembleStatisticsRft::availableTimeSteps( const QString& wellName ) { - if ( !m_summaryCaseCollection ) return {}; - std::set allTimeSteps; - for ( auto summaryCase : m_summaryCaseCollection->allSummaryCases() ) + for ( auto reader : m_rftReaders ) { - if ( summaryCase->rftReader() ) - { - std::set timeSteps = summaryCase->rftReader()->availableTimeSteps( wellName ); - allTimeSteps.insert( timeSteps.begin(), timeSteps.end() ); - } + std::set timeSteps = reader->availableTimeSteps( wellName ); + allTimeSteps.insert( timeSteps.begin(), timeSteps.end() ); } return allTimeSteps; } @@ -122,16 +108,11 @@ std::set RifReaderEnsembleStatisticsRft::availableTimeSteps( const QS std::set RifReaderEnsembleStatisticsRft::availableTimeSteps( const QString& wellName, const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName ) { - if ( !m_summaryCaseCollection ) return {}; - std::set allTimeSteps; - for ( auto summaryCase : m_summaryCaseCollection->allSummaryCases() ) + for ( auto reader : m_rftReaders ) { - if ( summaryCase->rftReader() ) - { - std::set timeSteps = summaryCase->rftReader()->availableTimeSteps( wellName, wellLogChannelName ); - allTimeSteps.insert( timeSteps.begin(), timeSteps.end() ); - } + std::set timeSteps = reader->availableTimeSteps( wellName, wellLogChannelName ); + allTimeSteps.insert( timeSteps.begin(), timeSteps.end() ); } return allTimeSteps; } @@ -143,16 +124,11 @@ std::set RifReaderEnsembleStatisticsRft::availableTimeSteps( const QString& wellName, const std::set& relevantChannels ) { - if ( !m_summaryCaseCollection ) return {}; - std::set allTimeSteps; - for ( auto summaryCase : m_summaryCaseCollection->allSummaryCases() ) + for ( auto reader : m_rftReaders ) { - if ( summaryCase->rftReader() ) - { - std::set timeSteps = summaryCase->rftReader()->availableTimeSteps( wellName, relevantChannels ); - allTimeSteps.insert( timeSteps.begin(), timeSteps.end() ); - } + std::set timeSteps = reader->availableTimeSteps( wellName, relevantChannels ); + allTimeSteps.insert( timeSteps.begin(), timeSteps.end() ); } return allTimeSteps; } @@ -162,17 +138,11 @@ std::set //-------------------------------------------------------------------------------------------------- std::set RifReaderEnsembleStatisticsRft::availableWellLogChannels( const QString& wellName ) { - if ( !m_summaryCaseCollection ) return {}; - std::set allWellLogChannels; - for ( auto summaryCase : m_summaryCaseCollection->allSummaryCases() ) + for ( auto reader : m_rftReaders ) { - if ( summaryCase->rftReader() ) - { - std::set wellLogChannels = - summaryCase->rftReader()->availableWellLogChannels( wellName ); - allWellLogChannels.insert( wellLogChannels.begin(), wellLogChannels.end() ); - } + std::set wellLogChannels = reader->availableWellLogChannels( wellName ); + allWellLogChannels.insert( wellLogChannels.begin(), wellLogChannels.end() ); } return allWellLogChannels; } @@ -182,16 +152,11 @@ std::set RifReaderEnsembleStatistic //-------------------------------------------------------------------------------------------------- std::set RifReaderEnsembleStatisticsRft::wellNames() { - if ( !m_summaryCaseCollection ) return {}; - std::set allWellNames; - for ( auto summaryCase : m_summaryCaseCollection->allSummaryCases() ) + for ( auto reader : m_rftReaders ) { - if ( summaryCase->rftReader() ) - { - std::set wellNames = summaryCase->rftReader()->wellNames(); - allWellNames.insert( wellNames.begin(), wellNames.end() ); - } + std::set wellNames = reader->wellNames(); + allWellNames.insert( wellNames.begin(), wellNames.end() ); } return allWellNames; } @@ -201,7 +166,7 @@ std::set RifReaderEnsembleStatisticsRft::wellNames() //-------------------------------------------------------------------------------------------------- void RifReaderEnsembleStatisticsRft::calculateStatistics( const QString& wellName, const QDateTime& timeStep ) { - if ( !m_summaryCaseCollection ) return; + if ( m_rftReaders.empty() ) return; using ChannelType = RifEclipseRftAddress::RftWellLogChannelType; RifEclipseRftAddress pressAddress = RifEclipseRftAddress::createAddress( wellName, timeStep, ChannelType::PRESSURE ); @@ -218,11 +183,8 @@ void RifReaderEnsembleStatisticsRft::calculateStatistics( const QString& wellNam RiaCurveMerger curveMerger( RiaCurveDefines::InterpolationMethod::LINEAR ); RiaWeightedMeanCalculator dataSetSizeCalc; - for ( RimSummaryCase* summaryCase : m_summaryCaseCollection->allSummaryCases() ) + for ( auto reader : m_rftReaders ) { - auto reader = summaryCase->rftReader(); - if ( !reader ) continue; - std::vector pressures; reader->values( pressAddress, &pressures ); @@ -246,11 +208,8 @@ void RifReaderEnsembleStatisticsRft::calculateStatistics( const QString& wellNam RiaWeightedMeanCalculator dataSetSizeCalc; RifEclipseRftAddress tvdAddress = RifEclipseRftAddress::createAddress( wellName, timeStep, ChannelType::TVD ); - for ( RimSummaryCase* summaryCase : m_summaryCaseCollection->allSummaryCases() ) + for ( auto reader : m_rftReaders ) { - auto reader = summaryCase->rftReader(); - if ( !reader ) continue; - std::vector pressures; reader->values( pressAddress, &pressures ); diff --git a/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.h b/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.h index b5d42e385e3..a12d13b689b 100644 --- a/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.h +++ b/ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.h @@ -23,14 +23,16 @@ #include "RiaCurveMerger.h" #include "RiaWeightedMeanCalculator.h" -class RimSummaryEnsemble; +#include + +class RifReaderRftInterface; class RimEclipseCase; class RigWellPath; class RifReaderEnsembleStatisticsRft : public RifReaderRftInterface { public: - RifReaderEnsembleStatisticsRft( const RimSummaryEnsemble* summaryCaseCollection, RimEclipseCase* eclipseCase ); + RifReaderEnsembleStatisticsRft( std::vector rftReaders, RimEclipseCase* eclipseCase ); std::set eclipseRftAddresses() override; void values( const RifEclipseRftAddress& rftAddress, std::vector* values ) override; @@ -56,8 +58,8 @@ class RifReaderEnsembleStatisticsRft : public RifReaderRftInterface void clearCache( const QString& wellName, const QDateTime& timeStep ); private: - const RimSummaryEnsemble* m_summaryCaseCollection; - RimEclipseCase* m_eclipseCase; + std::vector m_rftReaders; + RimEclipseCase* m_eclipseCase; std::map> m_cachedValues; }; diff --git a/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftEnsembleCurveSet.cpp b/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftEnsembleCurveSet.cpp index 51df83e81ef..b8d55c09a3c 100644 --- a/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftEnsembleCurveSet.cpp +++ b/ApplicationLibCode/ProjectDataModel/Flow/RimWellRftEnsembleCurveSet.cpp @@ -19,6 +19,7 @@ #include "RimWellRftEnsembleCurveSet.h" #include "RifReaderEnsembleStatisticsRft.h" +#include "RifReaderRftInterface.h" #include "Appearance/RimCurveSetAppearance.h" #include "RimEclipseCase.h" @@ -132,7 +133,16 @@ void RimWellRftEnsembleCurveSet::updatePlot( const SignalEmitter* emitter ) //-------------------------------------------------------------------------------------------------- void RimWellRftEnsembleCurveSet::clearEnsembleStatistics() { - m_statisticsEclipseRftReader = std::make_unique( m_ensemble(), m_eclipseCase() ); + std::vector rftReaders; + if ( m_ensemble() ) + { + for ( auto summaryCase : m_ensemble()->allSummaryCases() ) + { + if ( auto reader = summaryCase->rftReader() ) + rftReaders.push_back( reader ); + } + } + m_statisticsEclipseRftReader = std::make_unique( std::move( rftReaders ), m_eclipseCase() ); } //--------------------------------------------------------------------------------------------------