Commit Graph
2511 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 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 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 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 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
Magne Sjaastad 016ee07dca #14775 Input Property: rename Generated and refresh Data Sources 2026-09-24 08:17:17 +02:00
Magne Sjaastad 8f9b828ac4 Make filter collection and filter names read-only in tree view 2026-09-22 16:16:23 -04: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 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
Magne Sjaastad 3437cf9b94 #14778 Fix crashes from unguarded pointer and index accesses
* Skip deleted plot widgets in RiuMultiPlotBook::visiblePlotWidgets
* Guard missing calculation in detectCyclicCalculation
* Guard invalid node index in RigFemPart node lookups
* Guard null well path in RimWellLogExtractionCurve::extractGeomData
* Guard unopened case in RimGridCalculation::removeDependentObjects
* Guard empty subset in createLateralAtMeasuredDepth
2026-09-22 08:23:00 +02:00
Kristian Bendiksen 0eba9e8ef7 #14752 Well Target Mapping: use view-independent data filters 2026-09-18 12:36:43 +02:00
JJ e0c1f23e6e Support for ensemble jobs (#14773)
Initial support for running well planning opm flow jobs for ensembles
2026-09-17 14:03:54 +02:00
Magne Sjaastad 044454b9b1 Auto-assign Y-axis for ensemble curve sets based on unit/vector match
Extends the existing single-curve auto axis assignment (unit and summary vector matching, then alternating left/right) to also cover RimEnsembleCurveSet. Previously ensemble curve sets were always placed on the default left axis, so e.g. FOPT and FOPR ensembles ended up on the same axis despite differing units.

- Add RimEnsembleCurveSet::unitNameY(), looked up from the first available summary case reader in the ensemble.
- Move X and Y axis assignment from RimSummaryPlot to new RimSummaryPlotTools. Y-axis assignment takes a RiaSummaryAddressModifier::CurveAddressProvider, and compares against both curves and curve sets in the plot.
- RimEnsembleCurveSetCollection::addCurveSet gains an autoAssignPlotAxis flag (default true, matching addCurveAndUpdate for single curves).

Also fixes a bug in the summary plot editor where ensemble curve sets manually assigned to different Y-axes collapsed onto the same axis when clicking OK. The PdmPtrField axis reference does not resolve across the cloned preview and target plots. Add RimEnsembleCurveSet::findOrAssignLeftOrRightAxisY() to capture and re-apply the axis explicitly.

Add RimSummaryPlot-Test.cpp with unit tests for axis auto-assignment of curves and ensemble curve sets.

Fixes #14728
2026-09-16 06:28:50 -04:00
Kristian Bendiksen ef1ad39723 Python: Reject overwriting source summary vectors 2026-09-16 11:37:59 +02:00
Kristian Bendiksen 52e212e24f #14667 Completions: Simplify segment interval properties 2026-09-16 11:35:13 +02:00
Kristian Bendiksen 63bcc22485 #14667 Completions: Move MSW settings to segments 2026-09-16 11:35:13 +02:00
Magne Sjaastad cfb9e5765e #14761 Find summary data files when file name contains multiple dots
QFileInfo::baseName() truncates at the first dot, so the ESMRY and h5 files were not found for realizations like CASE.V2-0.SMSPEC. Without an UNSMRY file the realization was opened as an empty summary case. Use completeBaseName() to strip only the extension.
2026-09-16 05:06:47 -04:00
Magne Sjaastad 3414fee046 #14345 Ensure reservoir case is open for destination ensemble grid calculations
Also open the reservoir case when the calculation's destination ensemble is set, not only when additional cases type is ENSEMBLE.
2026-09-16 10:53:31 +02:00
Kristian Bendiksen 26314940a3 #14345 Property Filter: Use view case for ensemble filters 2026-09-16 10:53:31 +02:00
Kristian Bendiksen 42d46cf1a8 #14345 Property Filter: Allow bounds without result limits 2026-09-16 10:53:31 +02:00
Kristian Bendiksen 99ce6daf58 #14345 Grid Calculation: Fix additional ensemble selection 2026-09-16 10:53:31 +02:00
Kristian Bendiksen 0ba20f0b65 #14345 Grid Calculation: Add destination ensemble 2026-09-16 10:53:31 +02:00
Kristian Bendiksen 8cbc81fe98 #14345 Grid Calculation: Close cases opened during calculation 2026-09-16 10:53:31 +02:00
Kristian Bendiksen bc9f64af92 #14345 Propagate LGR parent visibility for index-based data filters
The grid calculation data filter evaluated index filters (polygon, user
defined) directly on every grid. An INDEX_K polygon evaluated on a fine
LGR can select no cells, so refined cells whose parent host cell is
inside the polygon were dropped from the aggregation. This gave a lower
sum than the histogram of visible cells in the 3d view, which renders
LGR cells following their parent grid cell.

Hoist the parent grid visibility propagation out of the range filter
branch so it also runs for index filters. Property filters are evaluated
per cell against their own result values and are left untouched.
2026-09-16 10:53:31 +02:00
Kristian Bendiksen b62738ff8a #14345 Restore view visibility for the cell filter view filter type
The cell filter view filter type was changed to use the cell filter
geometry to include cells inside the filters that are inactive in the
view's case, at the cost of ignoring property filters in the view. That
use case is now covered by the data filter type, which evaluates the
filters per calculation case. Restore the original visible cells
semantics for the cell filter view filter type, so property filters in
the view affect the calculation again.
2026-09-16 10:53:31 +02:00
Kristian Bendiksen 5a7e043837 #14345 Add Data Filters to grid ensembles
Add a data filter collection to RimReservoirGridEnsemble, so filters
can be defined once for the ensemble instead of per realization. The
filters are bound to the main case of the ensemble for configuration,
and evaluated per case as elsewhere.

The filter creation commands are available from a Data Filters submenu
on the ensemble node, and the collection node is hidden while empty,
matching the case-level behavior. The grid calculation data filter
options include the filters of the ensemble the destination case
belongs to.
2026-09-16 10:53:31 +02:00
Kristian Bendiksen 996e18426c #14345 Grid Calculation: add filtering with view-independent data filters
Add a filter type option to the grid calculation: None, Cell Filter
View or Data Filter. In data filter mode a single filter from the
destination case's Data Filters collection is selected, and the filter
is evaluated per calculation case and time step using each case's own
active cells and result values. Property based filtering of ensemble
calculations then uses each realization's own property values, which is
not possible with view based filtering.

Old projects with a cell filter view are migrated to the cell filter
view mode. Complex filtering is composed with a combined filter (AND/OR)
in the Data Filters collection.
2026-09-16 10:53:31 +02:00
Kristian Bendiksen e9b28c1b02 #14345 Add per-case cell filter evaluation with source case override
Add a sourceCaseOverride parameter to RimCellFilter::applyToCellVisibility.
When set, property filters evaluate against the override case's result
values instead of the case the filter is bound to, allowing the same
filter definition to be evaluated against each case in an ensemble.
Combined filters forward the override to their children, and geometry
based filters ignore it.

Add RimCellFilterTools::computeReservoirCellVisibility, which evaluates
a cell filter against a given case for all grids and returns the
visibility indexed by reservoir cell index. Range filters propagate the
parent grid visibility into LGR cells, matching the filtered geometry
of a 3d view.

Also add RimCellFilter::setFilterMode.
2026-09-16 10:53:31 +02:00
Kristian Bendiksen da28ffe613 #14345 Use cell filter geometry for grid calculation visibility
The visibility mask for 'filter by view' was taken from the view's
visible cells, which are limited to the active cells of the view's
case. When applying the calculation to additional cases with different
ACTNUM, cells inside the filter geometry that are inactive in the
view's case were excluded from the aggregation for cases where they are
active, giving too low sums.

Build the mask from the cell filter geometry (RANGE_FILTERED +
RANGE_FILTERED_INACTIVE) instead, so each calculation case contributes
its own active cells inside the filters. Property filters in the view
no longer affect the calculation. The result filtering now uses the
same mask as the input filtering, also when the visibility filter is
provided by the caller.
2026-09-16 10:53:31 +02:00
Kristian Bendiksen be9969d5b4 #14345 Add debug logging of value counts used in aggregations and histogram statistics
Log at debug level, for each case and time step, how many input values
contribute to a grid calculation aggregation and how many were replaced
with the default value (non-visible cells and undefined values). Also
log the sum and number of values used when computing visible cells
statistics, to allow comparison with the histogram sum in the 3d view.
2026-09-16 10:53:31 +02:00
Kristian Bendiksen 0ad61a004a #14345 Grid Calculation: replace undefined values with default value in aggregations
Aggregation functions like sum() in the expression parser include all
values in the input vector. Undefined values (HUGE_VAL) could leak into
the aggregation input when a grid case group member has fewer time steps
on disk than the main case it inherits result meta data from, or when a
cell is active in the calculation case but has no value in the source
data. This produced infinite sums for some realizations, while the
histogram statistics ignore undefined values.

Replace undefined values in the aggregation input with the default value
0.0, matching the histogram semantics, and log a warning per case and
variable when values were replaced.
2026-09-16 10:53:31 +02:00
Magne Sjaastad 0579dbb468 Move time-step control and grid-only hooks from Rim3dView to RimGridView
* #14760 Move time-step control and grid-only hooks from Rim3dView to RimGridView
* #14760 Store named 3D visualization models in a shared collection instead of per-model fields
2026-09-16 08:44:00 +02:00
Magne Sjaastad 64361c2f78 #14746 Fix duplicate AppEnum serialization text and detect it in addItem
RimGridCalculation::AdditionalCasesType::ALL_CASES and
RimIntersectionFilterEnum::INTERSECT_FILTER_BETWEEN both reused the
serialization text of a sibling enum value (NONE and
INTERSECT_SHOW_BELOW respectively), so they would silently round-trip
as the wrong value when read back from a project file.

AppEnumMapperBase::addItem only asserted alias uniqueness, not text
uniqueness, so this class of bug went undetected. Add a CAF_ASSERT
checking that a new enum value's serialization text does not match an
existing value's text or aliases.

Found while investigating the AppEnum alias-duplication note in #14654.
2026-09-14 08:14:19 -04:00
Magne Sjaastad 90a4282783 #14727 Fix ensemble filter by summary value for oscillating rate vectors
RimEnsembleCurveFilter::applyFilter() (SUMMARY_VALUE mode) only compared
the value at the last time step inside the selected time range against
the filter's value range, discarding the result of every earlier time
step. For monotonically increasing cumulative vectors (e.g. FOPT) this
coincidentally matched user expectations, but for rate vectors (e.g.
FOPR) that oscillate at high frequency between zero and a non-zero
value, the outcome depended arbitrarily on whether the last time step
happened to land on zero or not.

The filter now excludes a realization if any time step inside the
selected time range has a value outside the selected value range, i.e.
all time steps in range must be inside the value range for the
realization to be kept. This makes the behavior consistent between
FOPT and FOPR style vectors.

Added a regression test reproducing the oscillating-rate scenario, and
updated the existing performance test to describe and exercise the new
semantics.
2026-09-14 03:10:24 -04:00
Magne Sjaastad 8776a2e2bf #14703 Grid statistics: Fix missing results for computed dynamic results like riPORV*SOIL
RimEclipseStatisticsCaseEvaluator::addNamedResult() sized the destination
statistics containers (MEAN/P10/P50/P90/etc.) using the time step count of
an arbitrary first result found in the source case (existingResults()[0]).

Results computed by ResInsight, such as riPORV*SOIL and riPORV*SGAS, do not
have their own time step info populated until they are actually computed,
so existingResults()[0] can end up being an unrelated result, including a
static one (e.g. PORV) with only a single time step. Using its size to
size the destination containers collapsed the statistics for all dynamic
results to a single time step, silently dropping the results for every
other time step, i.e. no results were shown for riPORV*SOIL / riPORV*SGAS.

Fix by using RigCaseCellResultsData::maxTimeStepCount() to find the source
result with the most time steps, and use its time step info both for the
destination time step metadata and for sizing the destination containers,
instead of depending on an arbitrary source result.

Added a unit test reproducing the ensemble statistics computation for
riPORV*SOIL across two source cases.
2026-09-12 04:53:16 -04:00
Magne Sjaastad b922fd96a7 #14737 Add reordering support to case collections
Add caf::PdmFieldReorderCapability to the child array fields holding
RimCase objects:
- RimEclipseCaseCollection::cases (grid models in Project Tree)
- RimCaseCollection::reservoirs (statistics case groups)
- RimGeoMechModels::m_cases (geomechanical models)

This enables the built-in move up/down tree item controls for
reordering cases, matching the pattern already used for e.g.
RimSurfaceCollection and RimMultiPlot.
2026-09-12 04:11:57 -04:00
Magne Sjaastad 3ec1a2659c #14690 Restore Close context menu command for cases
RicCloseCaseFeature::isCommandEnabled() was updated to require
RimCase::isDeletable() to be true, but no case type ever set this
flag to true by default. As a result, the 'Close' context menu item
disappeared for all grid models.

Set setDeletable( true ) as the default in the RimCase constructor.
Special cases that should not be closed directly by the user (e.g.
the generated ensemble grid case in RimWellTargetMapping) already
opt out by calling setDeletable( false ) explicitly.
2026-09-12 04:10:14 -04:00
Magne Sjaastad 055fbb60fa #14709 RimReservoirGridEnsemble: Auto-import per-realization formation zone files 2026-09-12 04:05:24 -04:00