Commit Graph
4249 Commits
Author SHA1 Message Date
Magne Sjaastad 61db518efc Address review feedback: add range validation and input-size assertion
- RimContourMapPeaksCollection: clamp m_peakCount to [1,20] and m_minDistance to >= 0.0

- RigContourMapPeakFinder: assert z.size() matches nx*ny before indexing in computeProminenceAndRegionSize
2026-09-30 16:26:04 +02:00
Magne Sjaastad 64fd63b77b #14797 Hide cells-to-include option for line polygon filters 2026-09-30 16:26:04 +02:00
Magne Sjaastad c6664a3361 #14797 Add command to compute contour map peaks
Available from the contour map context menu for Eclipse, GeoMech and ensemble statistics contour maps.
2026-09-30 16:26:04 +02:00
Magne Sjaastad 503ea3eb74 #14797 Contour map: Compute peaks and show them as markers
Each contour map projection owns a peaks collection. Computed peaks are shown in the project tree and visualized as single-point marker polygons in the global polygon collection. Markers are deleted with their peak, copied views drop peaks sharing markers with the original, and peaks are flagged as outdated when the result, time step or value filter changes.
2026-09-30 16:26:04 +02:00
Magne Sjaastad e0e05bcc6d #14797 Polygons: Add sphere display options and view update helpers
Add setters for line and sphere appearance on RimPolygon. Add RimPolygonCollection::updateViewsAfterPolygonsChanged(), shared with the contour map polygon tools, and a deferred variant that is safe to call from destructors.
2026-09-30 16:26:04 +02:00
Magne Sjaastad b28051e3d5 #14797 Add RigContourMapPeakFinder to find local maxima in contour maps
Union-find sweep from highest to lowest value computes the prominence of each peak. Peaks are filtered on prominence and edge contact, ranked by prominence or value, and thinned by minimum distance. Flat shoulders and plateaus are rejected, and prominence is measured against the minimum of each connected data region.
2026-09-30 16:26:04 +02:00
Magne Sjaastad 6c09ad66d9 Fix macOS build: add missing <iomanip> include for std::setw 2026-09-30 07:25:31 +02:00
Magne Sjaastad ccdde6596d #13807 Add 3D viewer background context menu with Link View, Update Bounding Box, Zoom All and default camera position 2026-09-28 18:35:28 +02:00
Magne Sjaastad 50a587b292 #13807 Improve generic view bounding box computation and add explicit recompute command
- Only consider visible well paths when computing the generic view bounding box.
- Fix polygon visibility filtering so individually hidden polygons no longer contribute to the bounding box.
- The bounding box is no longer implicitly invalidated when object visibility is toggled; it now only changes on initial load or when explicitly recomputed.
- Add RicUpdateGenericViewBoundingBoxFeature, a context menu command on RimGeneric3dView that recomputes the domain bounding box from currently visible objects, updates the grid box geometry, and zooms to fit.
2026-09-28 18:35:28 +02:00
Magne Sjaastad 5c97f97f32 #13807 Rename command text 'New View' to 'New Grid Model View' 2026-09-28 18:35:28 +02:00
Magne Sjaastad 34f5c52ca7 #13807 Add Python scripting support for generic view (surface/polygon visibility)
Based on magnesj/ResInsight#1078:
- Lift surfaceInViewCollection()/polygonInViewCollection() to virtual Rim3dView methods
- Make RimGeneric3dView scriptable as GenericView
- Add Project.create_generic_view() Python method
- RimcGridView surface/polygon methods now work on any Rim3dView
- Add Python tests and example script
2026-09-28 18:35:28 +02:00
Magne Sjaastad 7838290a4d #13807 Add a case-less Data View and merge it with Eclipse views in the tree
- Added RimGeneric3dView, a 3D view that is not tied to any grid case,
  useful for wells, surfaces and other data not requiring a reservoir
  grid. The view supports a custom name.
- Introduced RimGenericViewCollection, a new top-level collection that
  holds both Eclipse views and RimGeneric3dView instances. It overrides
  defineUiTreeOrdering() to display both types as a single flat list
  under the top-level 'Views' node.
- RimOilField now exposes a single genericViewCollection instead of a
  plain eclipseViewCollection field.
- RimEclipseViewCollection is unchanged and continues to be used for
  per-case and ensemble view collections.
- Updated RimEclipseCase::globalViewCollection() and related helpers to
  use RimGenericViewCollection, and added matching overloads in
  RicNewViewFeature for creating eclipse views from the merged
  collection.
- Added RicNewGenericDataViewFeature to create a new generic data view
  from the context menu.
2026-09-28 18:35:28 +02:00
Magne Sjaastad a57e53db05 Fix build: declare explicit destructor for RimEclipseContourMapView
cvf::ref<RivContourMapProjectionPartMgr> requires the type to be complete
at the point the implicit destructor is instantiated. Declaring the
destructor and defining it in the .cpp (where RivContourMapProjectionPartMgr.h
is included) avoids the incomplete-type error on clang/gcc Linux builds.
2026-09-28 10:30:12 +02:00
Magne Sjaastad 64b53b0612 #14710 Show active data filter as overlay text in contour map view
Refresh the label when the filter selection changes and repaint immediately, as this happens outside a display model rebuild.
2026-09-28 10:30:12 +02:00
Magne Sjaastad bb8af7bbbd #14710 Compute per-time-step visible cells for dynamic data filters
A static property with an active dynamic filter now produces a contour map per time step. Adds a synthetic ensemble fixture with unified restart files, as the OPM reader used for statistics does not support per-step restart files.
2026-09-28 10:30:12 +02:00
Magne Sjaastad cf75dbf58e #14710 Warn when loading a project with the obsolete formation filter
Keep the removed formation filter fields as obsolete so old projects still parse, and warn that the filter is no longer applied.
2026-09-28 10:30:12 +02:00
Magne Sjaastad 9911c49d2b #14710 Support ensemble data filters in ensemble contour maps
Replace the built-in formation filter with ensemble data filters. Load ensemble data filters after project read, and parent new views before assigning the case so the ensemble filter collection is resolved correctly.
2026-09-28 10:30:12 +02:00
Magne Sjaastad cdfc10b833 Count qwt axes when removing a plot axis 2026-09-28 09:18:41 +02:00
Magne Sjaastad d3ce3146fd Guard result metadata copy against a main case without results 2026-09-28 09:18:41 +02:00
Magne Sjaastad 0db64b400b Catch roff parse errors when checking for grid data 2026-09-28 09:18:41 +02:00
Magne Sjaastad 17e8c96e00 Use resdata reader for cases with non-unified restart files
The opm-common reader only reads unified restart files (UNRST). When the
opm-common reader was selected in preferences, cases with one restart file per
time step (X0000, X0001, ...) were opened without dynamic results.

- Fall back to the resdata reader when there is no unified restart file but
  non-unified restart files are present.
- Unit tests using dynamic results check that the result and time step exist
  before accessing them, so a missing result fails the test instead of
  crashing the test executable.
2026-09-27 21:13:13 +02:00
Kristian Bendiksen beadb306c2 #14640 Simulator Events: Use one experimental feature flag
The import and schedule export of simulator events are two halves of the same
workflow, so they share the "simulator-events" flag instead of having one
keyword each. Users who enabled "simulator-events-import" have to tick the new
entry once in Preferences -> System -> Experimental Features.
2026-09-25 14:35:45 +02:00
Kristian Bendiksen 9dda0faa3c #14640 Simulator Events: Add menu to export schedule based on events
The schedule generated from the well event timeline can now be written to
file from the GUI, without scripting.

- RicScheduleDataGenerator::generateScheduleForTimeline() collects the dates
  and wells from the timeline (honoring the last applied timestamp, never
  filtering insert-date events). The Python generate_schedule() method now
  calls it, so GUI and Python export the same schedule.
- New RicExportScheduleFeature "Export Schedule from Events" asks only for the
  file name and uses fixed defaults: the Eclipse case of the active view (else
  the first case of the project), MSW keywords for every well with events, the
  first date as a comment and aligned columns.
- Available from the context menu of the well event timeline and the well path
  collection, and from File -> Export, gated by the new experimental feature
  "simulator-events-export".
2026-09-25 14:35:45 +02:00
Kristian Bendiksen 8324af966c #14666 Simulator Events: Expand INSERT_DATE into insert-date events
INSERT_DATE statements are now expanded into one timeline event per
occurrence instead of a list of bare dates, so each generated date keeps
the COMMENT of its statement.

- New RimWellEventInsertDate (EventType::INSERT_DATE): a date-only event
  that generates no keyword, added with
  WellEventTimeline.add_insert_date_event(event_date, comment).
- The schedule generator writes the comment of an insert-date event as
  "--" lines directly below its DATES keyword.
- generate_schedule(_text) no longer takes additional_dates; insert-date
  events are part of the timeline, but keep the previous behavior of not
  being filtered by set_timestamp().
- SimulatorEventsDocument.report_dates and ApplyReport.report_dates are
  replaced by SimulatorEventsDocument.insert_date_events/insert_dates;
  merging files drops insert dates repeating both date and comment.
2026-09-25 14:35:45 +02:00
Kristian Bendiksen cbd3d39a5c #14582 Simulator Events: Merge events from multiple files
Importing several SIMEVENTS files together now merges them into one document
before coalescing, so keyword events with the same owner, type and timestamp
are combined across files, not only within one file.

- Add merge_simulator_events_documents, parse_simulator_events_files and
  apply_simulator_events_files. Source locations carry the file name, so
  conflict warnings and errors identify both files.
- Reject mismatched UNIT, and a second RESTART or duplicate WELSPECS across
  files. Collect parse errors from all files in one pass.
- Warn when files declare the same FILTER name with different expressions,
  and keep each file's filter instead of reusing the first one.
- CLI accepts multiple files; the import dialog allows multi-selection.
2026-09-25 14:35:45 +02:00
Magne Sjaastad 016ee07dca #14775 Input Property: rename Generated and refresh Data Sources 2026-09-24 08:17:17 +02:00
Magne Sjaastad 20a6373104 #14780 Add unit tests for grouping mode None with varied folder structures
Add a test covering a flat 'realization-N/CASE.EXT' folder structure
(no iter-N level) grouped with EnsembleGroupingMode::NONE, verifying
all files end up in a single best-effort ensemble. Also add a test
confirming empty input produces no bogus ensemble entry.
2026-09-24 08:16:29 +02:00
Magne Sjaastad e269893c04 #14780 Create a best effort ensemble instead of nothing for None grouping
RiaEnsembleNameTools::groupFilesByEnsembleName had no branch for
EnsembleGroupingMode::NONE, so it silently returned an empty map and
no ensemble was created for this grouping mode. Add handling that
groups all input files into a single ensemble.

Also surface warning dialogs instead of silently doing nothing when
no ensemble/grid ensemble could be created from the selected files,
in RicImportGridAndSummaryEnsembleFeature and
RicCreateGridCaseEnsemblesFromFilesFeature.
2026-09-24 08:16:29 +02:00
Magne Sjaastad 8f9b828ac4 Make filter collection and filter names read-only in tree view 2026-09-22 16:16:23 -04:00
JJ bafaa596a3 Remove obsolete cmake config - SOURCE_GROUP_HEADER_FILES (#14783) 2026-09-22 14:23:32 +02:00
Kristian Bendiksen 0eff2c193a #14772 exportPropertyInViews: Keep write failures as errors
Only a missing property in a view was a warning in the legacy command; a failed write
aborted with COMMAND_ERROR. The forwarding turned every failure into a warning. Add
RimEclipseView_exportCurrentProperty::hasCurrentProperty() so the Ricf command can
distinguish the two cases without parsing error strings.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 4148e7a5b1 #14772 Create the export folder on demand in exportCompletions and exportMswCompletions
The legacy exportMsw and exportWellPathCompletions commands relied on the export
implementation creating the folder (RicWellPathExportCompletionsFileTools::openFileForExport),
so the default <project>/completions folder worked on a fresh project. The new Rimc methods
rejected a non-existent folder up front. Create it instead, and only fail if that fails.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 7cb5ee4363 #14772 Ricf: Only fall back to the first case/group for replaceCase and replaceSourceCases
RicfForwarding::findCase() and findCaseGroup() resolved a negative id to the first
Eclipse result case / first case group for every legacy command. Only replaceCase and
replaceSourceCases had that behavior; all other commands rejected a missing id. Make the
lookups strict and add explicit findCaseOrFirstEclipseResultCase() / findCaseGroupOrFirst()
for the two replace commands.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen ebf7a061d8 #14772 Python: Add View.export_contour_map_to_text as object method and forward exportContourMapToText to it
Rim3dView_exportContourMapToText exports the contour map of an Eclipse
or GeoMech contour map view. The implementation is extracted from the
RICF_SOURCE_INIT feature RicExportContourMapToTextFeature into a static
helper returning std::expected, used by both the object method and the
legacy command.

The Python EclipseContourMap/GeoMechContourMap.export_to_text() wrappers
are kept as aliases of the generated method.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen b1a822e7ac #14772 Python: Add Project.run_octave_script as object method and forward runOctaveScript to it
RimProject_runOctaveScript takes Case objects (empty means all Eclipse
cases) and runs the script once per case through the existing
multi-case process launcher. RicfRunOctaveScript resolves the case ids
and forwards to it.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 54c5ef7dad #14772 Python: Add GeoMechCase.create_well_bore_stability_plot as object method and forward createWellBoreStabilityPlot to it
RimGeoMechCase_createWellBoreStabilityPlot takes a WellPath object and
a time step and returns the plot. WBS parameters cannot be passed as a
method argument (child objects are not supported as gRPC method
parameters), so the C++ setter is available for the Ricf forwarder and
the Python wrapper copies a WbsParameters object into the created
plot's Parameters child instead.

The Python wrapper moves from Case to GeoMechCase, accepts both a
WellPath object and (deprecated) a well path name, and keeps the
optional parameters argument.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 6a2e7a2a21 #14772 Python: Add WellLogPlot.export_data_as_las/ascii as object methods and forward exportWellLogPlotData to them
RimWellLogPlot_exportDataAsLas and RimWellLogPlot_exportDataAsAscii
return the exported file names. RicfExportWellLogPlotData picks the
method from the exportFormat and forwards to it. Add
RicfForwarding::findWellLogPlot().

The Python wrappers keep their signature and List[str] return value,
now calling the object methods. The misspelled export_tvdrkb argument
is kept as a deprecated alias of export_tvd_rkb.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen e3e09c0d1f #14772 Python: Add WellPath.export_geometry as object method and forward exportWellPaths to it
RimWellPath_exportGeometry writes the well path to a .dev file in an
explicit folder. RicfExportWellPaths resolves the well path names (empty
means all) and the WELLPATHS export folder from the command file
executor, then forwards to it per well path.
Project.export_well_paths() in Python is kept and emits a
DeprecationWarning.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 147a60ceec #14772 Python: Add Project.import_formation_names and Case.set_formation_names as object methods and forward importFormationNames to them
The legacy command combined import and assignment with an applyToCaseId.
This is split into RimProject_importFormationNames (returns the
FormationNames object) and RimCase_setFormationNames (takes the
object). RimFormationNames is made scriptable so it can be returned and
passed. RicfImportFormationNames forwards to both.

Project.import_formation_names() in Python keeps its signature, now
returns the FormationNames object, and gains an apply_to_all_cases
flag (default True, matching the old behavior).
Case.import_formation_names() is kept and emits a DeprecationWarning.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen b60ccf1f83 #14772 Python: Add WellPathCollection.import_well_log_files as object method and forward importWellLogFiles to it
RimWellPathCollection_importWellLogFiles imports LAS files given
explicitly and/or all LAS files in a folder. RicfImportWellLogFiles
forwards to it.

Project.import_well_paths() and Project.import_well_log_files() in
Python now call the object methods on the well path collection. Their
signatures and return values are unchanged, so no deprecation.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 06d6e2da65 #14772 Python: Add WellPathCollection.import_well_paths as object method and forward importWellPaths to it
RimWellPathCollection_importWellPaths imports well path files given
explicitly and/or all well path files in a folder, and returns the
names of the imported well paths. The legacy RicImportWellPaths
command (a RICF_SOURCE_INIT feature in Commands/) forwards to it.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 6548c4f4db #14772 Python: Add Project.create_grid_case_group as object method and forward createGridCaseGroup to it
RimProject_createGridCaseGroup returns the created group object.
RicfCreateGridCaseGroup forwards to it and wraps the group id and name
in the legacy createGridCaseGroupResult. The hand-written Python
wrapper is removed since the generated method has the same signature.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 739f3744f6 #14772 Python: Add Project.load_case as object method and forward loadCase to it
RimProject_loadCase loads a grid case from file and returns the case
object. RicfLoadCase forwards to it and wraps the case id in the legacy
loadCaseResult. The hand-written Python Project.load_case() wrapper is
removed since the generated method has the same signature and returns
the most-derived case class.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen cc1f09b665 #14772 Python: Add EclipseCase.create_saturation_pressure_plots as object method and forward createSaturationPressurePlots to it
RimEclipseResultCase_createSaturationPressurePlots exposes the time step
(the legacy command hardcodes 0) and returns an error when no plots
could be created. It only shows the plot window when a GUI is running;
the legacy code dereferenced RiaGuiApplication::instance()
unconditionally. RicfCreateSaturationPressurePlots resolves the cases
and loops, treating per-case failures as warnings as before.

The hand-written Case.create_saturation_pressure_plots() Python wrapper
is removed since the generated EclipseCase method shadows it.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 3ce81c4eca #14772 Python: Add GridCaseGroup.replace_source_cases as object method and forward replaceSourceCases to it
RimIdenticalGridCaseGroup_replaceSourceCases takes the grid file paths
directly (instead of a list file) and an optional ProjectFile, following
the same design as Case.replace_grid. RicfReplaceSourceCases reads the
list file and the executor's last project path and forwards to it.
Project.replace_source_cases() in Python is kept and emits a
DeprecationWarning.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 1eabb5f5f6 #14772 Forward computeCaseGroupStatistics to RimcEclipseStatisticsCase_computeStatistics
Add an UpdateViews parameter to the existing object method. The legacy
command calls computeStatisticsAndUpdateViews() (which also creates a
view if none exists) while the object method only computes; the default
(false) keeps the object method behavior and the Ricf forwarder passes
true. RicfComputeCaseGroupStatistics resolves the statistics cases and
loops over them.

GridCaseGroup.compute_statistics(case_ids=...) in Python now loops over
statistics_cases() and emits a DeprecationWarning.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 111741b365 #14772 Forward createStatisticsCase to RimcIdenticalGridCaseGroup_createStatisticsCase
Add a PopulateResultSelection parameter to the existing object method.
The legacy command selects all available properties (via
createAndAppendStatisticsCase) while the object method created an
empty selection; the default (false) keeps the object method behavior
and the Ricf forwarder passes true. The created case now gets a case id
assigned in both paths.

Add RicfForwarding::findCaseGroup() and findStatisticsCase().
2026-09-22 14:19:23 +02:00
Kristian Bendiksen 0416bd041e #14772 Python: Add FractureTemplate.set_containment as object method and forward setFractureContainment to it
RimFractureTemplate_setContainment validates the layer range and
updates the template. RicfSetFractureContainment forwards to it.
Project.set_fracture_containment(template_id=...) in Python resolves
the template object and calls the new method, emitting a
DeprecationWarning.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen eda2d73fed #14772 Forward scaleFractureTemplate to RimcFractureTemplate_setScaleFactors
Add a typed setter to the existing RimcFractureTemplate_setScaleFactors
object method and let RicfScaleFractureTemplate forward to it via
RicfForwarding::findFractureTemplate(). Make RimFractureTemplate::m_id
scriptable (read-only) so templates can be looked up by id from Python.

Project.scale_fracture_template(template_id=...) in Python now resolves
the template object and calls FractureTemplate.set_scale_factors(),
emitting a DeprecationWarning.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen dbd9e50f5f #14772 Python: Add EclipseCase.export_flow_characteristics as object method and forward exportFlowCharacteristics to it
RimEclipseResultCase_exportFlowCharacteristics has the same arguments
as the legacy command (lists only, no scalar shorthand).
RicfExportFlowCharacteristics forwards to it.

The hand-written Case.export_flow_characteristics() Python wrapper is
removed: the generated EclipseCase method has the same name and
argument names and shadows it for all cases the command applies to.
2026-09-22 14:19:23 +02:00