Skip to content

Reduce dependencies from Rif to Rim#857

Open
magnesj wants to merge 5 commits into
devfrom
reduce-dependency-on-rim-from-rif
Open

Reduce dependencies from Rif to Rim#857
magnesj wants to merge 5 commits into
devfrom
reduce-dependency-on-rim-from-rif

Conversation

@magnesj

@magnesj magnesj commented Apr 6, 2026

Copy link
Copy Markdown
Owner

No description provided.

magnesj added 5 commits April 6, 2026 14:19
Add virtual isCalculated() to RifSummaryReaderInterface (defaults false),
override in RifCalculatedSummaryCurveReader to return true. Replace
dynamic_cast<RifCalculatedSummaryCurveReader*> checks with isCalculated(),
removing the Rim header dependency from RifMultipleSummaryReaders.
…actureDefinition directly

Remove RimThermalFractureTemplate dependency by accepting const RigThermalFractureDefinition&
instead. Caller extracts fractureDefinition() before calling the exporter.
…xporters

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.
…lipseCase

writeCache takes RigCaseCellResultsData* and RigEclipseCaseData* directly.
ensureDataIsReadFromCache takes RigCaseCellResultsData* directly.
Caller (RimRegularGridCase) extracts the Rig objects before calling.
…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.
@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Reduce Rim dependencies from Rif file interface layer

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Remove Rim dependencies from Rif file interface layer
• Replace dynamic_cast checks with virtual isCalculated() method
• Accept Rig types directly instead of Rim model objects
• Extract data at Rim caller level before passing to Rif exporters
• Simplify RFT reader ensemble to use pre-collected reader vector
Diagram
flowchart LR
  A["Rim Model Objects"] -->|Extract Data| B["Primitive Types & Rig Objects"]
  B -->|Pass to Exporters| C["Rif File Interface"]
  D["RifSummaryReaderInterface"] -->|Virtual Method| E["isCalculated()"]
  E -->|Replace| F["dynamic_cast Checks"]
  G["RimSummaryEnsemble"] -->|Pre-collect| H["RifReaderRftInterface Vector"]
  H -->|Pass to| I["RifReaderEnsembleStatisticsRft"]
Loading

Grey Divider

File Changes

1. ApplicationLibCode/FileInterface/RifMultipleSummaryReaders.cpp ✨ Enhancement +5/-5

Replace dynamic_cast with isCalculated virtual method

ApplicationLibCode/FileInterface/RifMultipleSummaryReaders.cpp


2. ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp ✨ Enhancement +24/-65

Accept RFT reader vector instead of ensemble object

ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp


3. ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.h ✨ Enhancement +6/-4

Change constructor to accept reader vector directly

ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.h


View more (17)
4. ApplicationLibCode/FileInterface/RifReaderRegularGridModel.cpp ✨ Enhancement +4/-12

Accept Rig types instead of RimEclipseCase

ApplicationLibCode/FileInterface/RifReaderRegularGridModel.cpp


5. ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h ✨ Enhancement +4/-3

Update function signatures to use Rig data types

ApplicationLibCode/FileInterface/RifReaderRegularGridModel.h


6. ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.cpp ✨ Enhancement +7/-10

Accept primitive parameters instead of RimStimPlanModel

ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.cpp


7. ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.h ✨ Enhancement +6/-3

Update writeToFile signature with primitive parameters

ApplicationLibCode/FileInterface/RifStimPlanModelAsymmetricFrkExporter.h


8. ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.cpp ✨ Enhancement +5/-8

Accept RigWellPath instead of RimStimPlanModel

ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.cpp


9. ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.h ✨ Enhancement +2/-2

Change parameter from RimStimPlanModel to RigWellPath

ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.h


10. ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.cpp ✨ Enhancement +13/-18

Accept primitives and RigWellPath instead of Rim objects

ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.cpp


11. ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.h ✨ Enhancement +4/-5

Update function signatures to use Rig and primitive types

ApplicationLibCode/FileInterface/RifStimPlanModelPerfsFrkExporter.h


12. ApplicationLibCode/FileInterface/RifStimPlanModelExporter.cpp ✨ Enhancement +19/-3

Extract data from RimStimPlanModel before calling sub-exporters

ApplicationLibCode/FileInterface/RifStimPlanModelExporter.cpp


13. ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp ✨ Enhancement +4/-1

Update call to calculateTopAndBottomMeasuredDepth with new signature

ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp


14. ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.cpp ✨ Enhancement +4/-6

Accept RigThermalFractureDefinition instead of Rim template

ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.cpp


15. ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.h ✨ Enhancement +2/-4

Change parameter to RigThermalFractureDefinition reference

ApplicationLibCode/FileInterface/RifThermalFractureTemplateSurfaceExporter.h


16. ApplicationLibCode/FileInterface/RifSummaryReaderInterface.h ✨ Enhancement +2/-0

Add virtual isCalculated method with default false

ApplicationLibCode/FileInterface/RifSummaryReaderInterface.h


17. ApplicationLibCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.h ✨ Enhancement +2/-0

Override isCalculated to return true

ApplicationLibCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.h


18. ApplicationLibCode/ProjectDataModel/Flow/RimWellRftEnsembleCurveSet.cpp ✨ Enhancement +11/-1

Extract RFT readers before constructing statistics reader

ApplicationLibCode/ProjectDataModel/Flow/RimWellRftEnsembleCurveSet.cpp


19. ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp ✨ Enhancement +4/-2

Extract Rig objects before calling cache functions

ApplicationLibCode/ProjectDataModel/RimRegularGridCase.cpp


20. ApplicationLibCode/ProjectDataModelCommands/RimcThermalFractureTemplate.cpp ✨ Enhancement +1/-1

Pass fractureDefinition directly to exporter

ApplicationLibCode/ProjectDataModelCommands/RimcThermalFractureTemplate.cpp


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Apr 6, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX Issues (0)

Grey Divider


Action required

1. RKB offset dropped 🐞 Bug ≡ Correctness
Description
RifStimPlanModelDeviationFrkExporter::writeToFile hard-codes rkbOffset=0.0 when exporting, so MD
values in Deviation.frk no longer include the airGap/RKB offset that RigWellPathGeometryExporter
applied for RimWellPath exports.
Code

ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.cpp[R48-55]

+    double              mdStepSize = 5.0;
+    double              rkbOffset  = 0.0;
    std::vector<double> xValues;
    std::vector<double> yValues;
    std::vector<double> tvdValues;
    std::vector<double> mdValues;
-    RigWellPathGeometryExporter::computeWellPathDataForExport( wellPath, mdStepSize, xValues, yValues, tvdValues, mdValues, showTextMdRkb );
+    RigWellPathGeometryExporter::computeWellPathDataForExport( *wellPath, mdStepSize, rkbOffset, xValues, yValues, tvdValues, mdValues );
    convertFromMeterToFeet( mdValues );
Evidence
Deviation.frk now calls the RigWellPath overload with a fixed rkbOffset=0.0. The existing
RimWellPath overload of RigWellPathGeometryExporter computes a non-zero rkbOffset from modeled well
path airGap (and sets showTextMdRkb) and forwards it to the RigWellPath overload, which adds it to
the exported MD values.

ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.cpp[32-55]
ApplicationLibCode/ReservoirDataModel/Well/RigWellPathGeometryExporter.cpp[31-67]
ApplicationLibCode/ReservoirDataModel/Well/RigWellPathGeometryExporter.cpp[72-117]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RifStimPlanModelDeviationFrkExporter::writeToFile` currently exports measured depths with `rkbOffset = 0.0`, which changes output for well paths where the RimWellPath-based exporter would apply airGap/RKB.

### Issue Context
`RigWellPathGeometryExporter::computeWellPathDataForExport(gsl::not_null<const RimWellPath*>)` computes `rkbOffset` from the top-level well path (e.g., modeled well path airGap) and applies it by adding it to exported MD values.

### Fix Focus Areas
- ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.{h,cpp}[TBD]
- ApplicationLibCode/FileInterface/RifStimPlanModelExporter.cpp[32-52]

### Proposed fix
- Extend `RifStimPlanModelDeviationFrkExporter::writeToFile(...)` to accept `double rkbOffset` (and optionally a `bool showTextMdRkb` if needed).
- In `RifStimPlanModelExporter::writeToDirectory`, compute `rkbOffset` using `RimWellPath` (replicating the logic from `RigWellPathGeometryExporter`’s RimWellPath overload: use top-level modeled well path airGap; file well paths may also imply MD RKB display) and pass it into the deviation exporter.
- Use that `rkbOffset` when calling `computeWellPathDataForExport(*wellPathGeom, mdStepSize, rkbOffset, ...)`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Null wellPath deref 🐞 Bug ☼ Reliability
Description
RifStimPlanModelGeologicalFrkExporter dereferences stimPlanModel->wellPath() without checking for
null, which can crash during export because wellPath() is optional elsewhere and the exporter
pipeline already passes nullptr to other exporters.
Code

ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp[R159-162]

    auto [perforationTop, perforationBottom] =
-        RifStimPlanModelPerfsFrkExporter::calculateTopAndBottomMeasuredDepth( stimPlanModel, stimPlanModel->wellPath() );
+        RifStimPlanModelPerfsFrkExporter::calculateTopAndBottomMeasuredDepth( stimPlanModel->wellPath()->wellPathGeometry(),
+                                                                              stimPlanModel->perforationLength(),
+                                                                              stimPlanModel->anchorPosition() );
Evidence
Geological export now does stimPlanModel->wellPath()->wellPathGeometry() with no guard. The main
export pipeline explicitly handles a null well path for Deviation/Perfs exports (passes nullptr),
and core StimPlan code shows wellPath() can be null (checked before use).

ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp[159-163]
ApplicationLibCode/FileInterface/RifStimPlanModelExporter.cpp[32-46]
ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModel.cpp[521-529]
ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModel.cpp[640-645]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RifStimPlanModelGeologicalFrkExporter::writeToFile` dereferences `stimPlanModel->wellPath()` unconditionally. If the StimPlan model has no well path (a supported state elsewhere), export will crash.

### Issue Context
Other exporters in the same pipeline already tolerate missing well path by passing `nullptr` and returning `false`. Geological export should fail gracefully in the same scenario.

### Fix Focus Areas
- ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp[159-163]
- ApplicationLibCode/FileInterface/RifStimPlanModelExporter.cpp[32-52]

### Proposed fix
- In `RifStimPlanModelGeologicalFrkExporter::writeToFile`, add:
 - `auto* wp = stimPlanModel->wellPath();`
 - `if (!wp || !wp->wellPathGeometry()) return false;`
 - then pass `wp->wellPathGeometry()` into `calculateTopAndBottomMeasuredDepth(...)`.
- Optionally, add an early `if (!stimPlanModel || !stimPlanModel->wellPath() || !stimPlanModel->wellPath()->wellPathGeometry()) return false;` in `RifStimPlanModelExporter::writeToDirectory` to keep all export steps consistent.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

3. Unenforced non-null readers 🐞 Bug ⚙ Maintainability
Description
RifReaderEnsembleStatisticsRft stores raw RifReaderRftInterface* and dereferences them without null
checks, making its safety depend on callers always providing non-null pointers.
Code

ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp[R44-48]

+    for ( auto reader : m_rftReaders )
    {
-        if ( summaryCase->rftReader() )
-        {
-            std::set<RifEclipseRftAddress> addresses = summaryCase->rftReader()->eclipseRftAddresses();
-            allAddresses.insert( addresses.begin(), addresses.end() );
-        }
+        std::set<RifEclipseRftAddress> addresses = reader->eclipseRftAddresses();
+        allAddresses.insert( addresses.begin(), addresses.end() );
    }
Evidence
The class now holds std::vector<RifReaderRftInterface*> and directly calls reader->... in loops.
The current call site filters nulls, but the constructor/type does not encode that precondition.

ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.h[60-63]
ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp[41-48]
ApplicationLibCode/ProjectDataModel/Flow/RimWellRftEnsembleCurveSet.cpp[134-146]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RifReaderEnsembleStatisticsRft` relies on a caller-enforced precondition that all pointers in `m_rftReaders` are non-null.

### Issue Context
Today one call site filters null pointers, but the class API doesn’t communicate/enforce this and future call sites may accidentally pass null.

### Fix Focus Areas
- ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.h[35-65]
- ApplicationLibCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp[41-102]

### Proposed fix
- Make the contract explicit by either:
 - Changing the constructor parameter type to `std::vector<gsl::not_null<RifReaderRftInterface*>>`, or
 - Adding `CAF_ASSERT(reader)` (or equivalent) at the start of each loop over `m_rftReaders`.
- Optionally add a guard in `values(..., std::vector<double>* values)` to assert/return if `values == nullptr` to match the implicit non-null contract.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +48 to 55
double mdStepSize = 5.0;
double rkbOffset = 0.0;
std::vector<double> xValues;
std::vector<double> yValues;
std::vector<double> tvdValues;
std::vector<double> mdValues;
RigWellPathGeometryExporter::computeWellPathDataForExport( wellPath, mdStepSize, xValues, yValues, tvdValues, mdValues, showTextMdRkb );
RigWellPathGeometryExporter::computeWellPathDataForExport( *wellPath, mdStepSize, rkbOffset, xValues, yValues, tvdValues, mdValues );
convertFromMeterToFeet( mdValues );

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Rkb offset dropped 🐞 Bug ≡ Correctness

RifStimPlanModelDeviationFrkExporter::writeToFile hard-codes rkbOffset=0.0 when exporting, so MD
values in Deviation.frk no longer include the airGap/RKB offset that RigWellPathGeometryExporter
applied for RimWellPath exports.
Agent Prompt
### Issue description
`RifStimPlanModelDeviationFrkExporter::writeToFile` currently exports measured depths with `rkbOffset = 0.0`, which changes output for well paths where the RimWellPath-based exporter would apply airGap/RKB.

### Issue Context
`RigWellPathGeometryExporter::computeWellPathDataForExport(gsl::not_null<const RimWellPath*>)` computes `rkbOffset` from the top-level well path (e.g., modeled well path airGap) and applies it by adding it to exported MD values.

### Fix Focus Areas
- ApplicationLibCode/FileInterface/RifStimPlanModelDeviationFrkExporter.{h,cpp}[TBD]
- ApplicationLibCode/FileInterface/RifStimPlanModelExporter.cpp[32-52]

### Proposed fix
- Extend `RifStimPlanModelDeviationFrkExporter::writeToFile(...)` to accept `double rkbOffset` (and optionally a `bool showTextMdRkb` if needed).
- In `RifStimPlanModelExporter::writeToDirectory`, compute `rkbOffset` using `RimWellPath` (replicating the logic from `RigWellPathGeometryExporter`’s RimWellPath overload: use top-level modeled well path airGap; file well paths may also imply MD RKB display) and pass it into the deviation exporter.
- Use that `rkbOffset` when calling `computeWellPathDataForExport(*wellPathGeom, mdStepSize, rkbOffset, ...)`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 159 to +162
auto [perforationTop, perforationBottom] =
RifStimPlanModelPerfsFrkExporter::calculateTopAndBottomMeasuredDepth( stimPlanModel, stimPlanModel->wellPath() );
RifStimPlanModelPerfsFrkExporter::calculateTopAndBottomMeasuredDepth( stimPlanModel->wellPath()->wellPathGeometry(),
stimPlanModel->perforationLength(),
stimPlanModel->anchorPosition() );

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Null wellpath deref 🐞 Bug ☼ Reliability

RifStimPlanModelGeologicalFrkExporter dereferences stimPlanModel->wellPath() without checking for
null, which can crash during export because wellPath() is optional elsewhere and the exporter
pipeline already passes nullptr to other exporters.
Agent Prompt
### Issue description
`RifStimPlanModelGeologicalFrkExporter::writeToFile` dereferences `stimPlanModel->wellPath()` unconditionally. If the StimPlan model has no well path (a supported state elsewhere), export will crash.

### Issue Context
Other exporters in the same pipeline already tolerate missing well path by passing `nullptr` and returning `false`. Geological export should fail gracefully in the same scenario.

### Fix Focus Areas
- ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp[159-163]
- ApplicationLibCode/FileInterface/RifStimPlanModelExporter.cpp[32-52]

### Proposed fix
- In `RifStimPlanModelGeologicalFrkExporter::writeToFile`, add:
  - `auto* wp = stimPlanModel->wellPath();`
  - `if (!wp || !wp->wellPathGeometry()) return false;`
  - then pass `wp->wellPathGeometry()` into `calculateTopAndBottomMeasuredDepth(...)`.
- Optionally, add an early `if (!stimPlanModel || !stimPlanModel->wellPath() || !stimPlanModel->wellPath()->wellPathGeometry()) return false;` in `RifStimPlanModelExporter::writeToDirectory` to keep all export steps consistent.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant