Look up POR and the tensor components with find(), and POR only for S.
Reading E on a model without node pressure no longer made S and the
derived results available. Use per-element node offsets instead of
assuming eight nodes per element, clear the element nodes when the parts
are read again, require the complete stress tensor for derived results,
and document the Biot coefficient of 1.
List only the S_VTK/E_VTK components that have data, and require the
complete tensor for the derived S/E results. Guard against too few
values in the tensor rows. Add tests for strain and partial data.
Build, copy and edit taskmaestro workflows in ResInsight and save them as
standard workflow.yaml + input.yaml.
- Python helper: catalog, load, save and export-registered subcommands,
and run --registered for installed workflows
- C++ definition model with pure edit operations, port type checks,
config field derivation, static validation and undo/redo
- Installed folder listing registered workflows (read-only, runnable,
can be duplicated)
- Graph editor dock with task palette, drag-to-connect, context menus,
automatic layout and debounced live validation
- New/Duplicate/Save/Save As/Rescan commands; unsaved edits run from a
temporary folder and prompt before being discarded
- Update the design document and the user README
Move EDITNNC, AQU* and COMPDAT/COMPSEGS processing into RigSimulationInput{Nnc,Aquifer,Connection}Tools, and move their tests into matching test files.
When several perforation intervals cut the same cell, the completion number
was taken from the first contribution, which depended on the order events
were applied. Unrelated event changes (e.g. group tree members) could then
change COMPLUMP numbers on boundary cells.
Pick the number with the largest summed MD overlap in the cell, with ties
going to the lowest number. Also use stable_sort for same-date events so
they keep file order.
Only END_IJK denotes a cell range, DIRECTION alone is a single cell and the MD
interval is split. A defaulted start MD is zero. Without an end MD the record is
copied to each sub-cell so all refined COMPDAT connections are attached to a segment.
Lateral refinement reduces the Peaceman pressure equivalent radius r0 of the
completed center sub-cell. Explicit CF is scaled by
(ln(r0_old/rw)+S)/(ln(r0_new/rw)+S), and an explicit PR item is updated to r0_new.
r0_old is taken from PR, or computed from the original cell size and permeability.
COMPDAT and COMPSEGS cells were mapped to the center refined sub-cell only,
so with K refinement only every other refined layer was completed, and the
original connection factor was copied unchanged.
Along the connection penetration direction (COMPDAT DIR) all sub-cells are
now completed, with explicit CF and KH scaled by the sub-cell length
fraction. COMPSEGS records are split the same way with the MD interval
divided between the sub-cells. Perpendicular directions still use the
center sub-cell.
Add event date and well queries with date, owner and event type/keyword
filters to SimulatorEventsDocument and WellEventTimeline, including
latest_event_date() and wells_with_msw_events() for building the
export_msw_for_wells list.
Grid-dependent keywords (WELSPECS, COMPORD, COMPDAT, COMPLUMP, WELSEGS, COMPSEGS, WSEGVALV, WSEGAICD) are skipped and reported as WARNING comments in the schedule header, so production-data-only setups can still generate DATES and well control keywords.
When a SEGMENT event is applied (SIMEVENTS mapping or timeline
set_timestamp), set the segment collection Reference MD Type to User
Defined and the reference MD to the start MD of the first segment
interval, so WELSEGS TOP_LENGTH matches the first segment.
Add FIXED_SEGMENT_LENGTH, MIN_SEGMENT_LENGTH and MAX_SEGMENT_LENGTH to
SIMEVENTS SEGMENT events. The lengths are stored on RimWellEventSegment
(new AddSegmentEvent arguments, 0 = not set) and applied to the segment
interval when the timeline is applied. Invalid combinations (fixed with
min/max, min > max, non-positive values) are reported as parse errors.
Move Pressure Drop and Length and Depth from the segment collection to
the well path completion settings. PRESSURE_COMPONENTS is now a dated
WELSPECS attribute used for the WELSEGS header at export, and is
rejected on SEGMENT events.
Rename RimWellEventTubing to RimWellEventSegment (keyword WellEventSegment),
EventType::TUBING to SEGMENT, and the scripting method AddTubingEvent to
AddSegmentEvent (Python: add_segment_event). Update the project tree label,
schedule comments, Python helpers, examples, tests and docs.
Well connections read from the restart file referenced the original refined
cells in the main grid. These cells are hidden after reconstruction, but the
well cell visualization does not check the invalid flag, so they were still
drawn. Re-point well connections and well heads to the corresponding LGR cells
and recompute the well cells per grid.
Add AvoidFaults option that blocks cluster growth across fault faces and
fault NNCs, and generate a WELL_TARGET_FAULT_FACES result with the number
of fault faces per cell.
Wells sharing an export name now produce one WELSPECS/COMPORD record,
one set of MSW keywords, and no duplicate COMPDAT/COMPLUMP connections.
Events on any well in the group trigger the group's keywords.
Connections in cells shared by several well paths of a group are combined
into one record. MSW keywords are exported for the well tree of the first
group member selected for MSW export.
Fixes#14870
VALVE events no longer trigger WELSPECS, COMPORD, WELSEGS and COMPSEGS.
WELSEGS/COMPSEGS are only regenerated for tubing and perforation events.
Fixes#14873
For nested hybrid grids, IJK range filters (I/J/K slices and IJK filters)
now refer exclusively to the original (coarse) grid IJK. Nested-grid local
IJK values are no longer offered, and every cell, including cells in all
refinement levels, is mapped to the original IJK of its top-most parent.
- Add RigNestedHybridGridLayout describing how original cells are embedded
in the flat grid, shared by the LGR reconstruction and the IJK mapping
- RigMainGrid: store the layout and compute the original IJK of any cell on
demand by following the parent cell chain, without per-cell storage
- Range filter UI: slider limits, clamping, defaults and active cell range
use the original grid dimensions; grid selection is hidden
- Evaluate range filters on all grids using the original IJK in the 3D view,
combined filters and data filters
- 3D view context menu slices use the original IJK of the picked cell
- Add unit tests for the layout, the IJK mapping against OLDIJK, and slice
filtering across refinement levels
Replace the rips.taskmaestro_helper introspect subcommand with
`python -m taskmaestro workflow describe --json`. RimWorkflowDescribeTools
converts the describe output (JSON schemas, depends_on, config_values)
into the workflow graph used by the Workflow UI. This also adds support
for collect dependencies and maps rips.Reservoir to EclipseCase pickers.
Register a 'workflows' experimental feature and gate the taskmaestro Workflows
UI behind it, following the registry pattern from #14081. The Workflows tree
collection is only added in RimProject::defineUiTreeOrdering when the feature is
enabled, and RimWorkflowCollection::rescanWorkflows() skips the eager discovery
scan (and its per-workflow Python introspection) when disabled.
Discover taskmaestro workflows under ~/.taskmaestro/workflows/ and surface
them as a "Workflows" collection in the project tree alongside Scripts.
Each workflow's task input schema is auto-generated by introspecting the
Pydantic models via a Python helper (rips.taskmaestro_helper) and rendered
as PDM field bindings - scalars for str/int/float/bool, and PdmPtrField
pickers for fields typed as rips.Case / rips.WellPath / rips.View.
The Run button on a RimWorkflow writes input.yaml from current bindings
(rips object references serialized as __resinsight_ref__ maps), spawns
the helper's run subcommand, and streams output to a modeless log dialog.
The helper resolves __resinsight_ref__ markers back to live rips objects
via the running ResInsight's gRPC server before driving taskmaestro.
- Return std::expected from RimSurfaceCollection::importSurfacesFromFiles
with a message naming the files that could not be imported
- Return specific errors from ImportSurface and NewSurface scripting
methods instead of nullptr
- Import before deleting the surface to overwrite, so a failed overwrite
keeps the existing surface
- Catch surfio exceptions in RifSurfio to avoid a crash on corrupt files
- Include the method name in the generic "no result" gRPC error
- Add Python tests for import_surface error handling
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.
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".
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.
INSERT_DATE is now a SCHEDULE event using KEY=VALUE attributes, and the file
format version is bumped to SIMEVENTS 1.2:
<date-expr> INSERT_DATE [EVERY=<duration>] [UNTIL=<date-expr>]
- EVERY takes a duration literal, DURATION variable or expression
(EVERY=1mon, EVERY=30d, EVERY=12mon, EVERY=12h) and must be positive.
Occurrence n is start + n months (clamped), then + n times the fixed part,
which preserves the dates of the previous DAY/MONTH/YEAR recurrences.
- UNTIL is an inclusive end date and requires EVERY; quote values with spaces.
- COMMENT is accepted and ignored; other attributes are rejected.
- SIMEVENTS 1.1 files and old-style INSERT_DATE lines are rejected with a
migration hint showing the rewritten line.
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.
Increase the time resolution of the SIMEVENTS format and replace whole-day
integer offsets with Go-style duration literals.
- All DATE values are now datetimes with second resolution. A date-only
literal means midnight; a time-of-day requires the 'T' separator and
fractional seconds are rounded to the nearest second.
- DURATION values and offset terms are Go-style literals such as 5d,
12h30m, 1.5h, 3mon and -3d. Units (mon, d, h, m, s) are mandatory, must
appear in strictly descending order without repeats, and a fraction is
allowed only on the last component (never on mon or s). Unitless numbers
and the legacy DAYS suffix are rejected with hints.
- New Duration type keeps calendar months separate from the fixed
timedelta part; adding months clamps to the end of shorter months, and
str() renders the Go-style form.
- Header version bumped to 1.1; 1.0 files are rejected with a migration
hint.
- Update tests, sample .events file, example script and
docs/simulatorEvents.md.
The legacy computeCaseGroupStatistics command could not distinguish an unset list from an
empty one, so [] meant all statistics cases. Keep that in the deprecation shim.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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().
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.
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.
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.
RimEclipseCase_createMultipleFractures takes WellPath objects and a
FractureTemplate object instead of names and ids. The
MultipleFractures::Action enum is moved from the Ricf header to
RicCreateMultipleFracturesFeature.h so the object method does not
depend on CommandFileInterface, and is registered as the Python
StrEnum MultipleFracturesAction.
Add RicfForwarding::findFractureTemplate(). RicfCreateMultipleFractures
resolves names/ids and forwards to the object method.
The hand-written Case.create_multiple_fractures(template_id=...,
well_path_names=...) Python wrapper is removed: the generated
Reservoir method has the same name and shadows it. The test is updated
to the object based signature.
RicfExportLgrForCompletions resolves well path names and the LGRS
export folder from the command file executor and forwards to the
object method. Add Python tests for both LGR object methods.
RimEclipseCase_createLgrForCompletions and
RimEclipseCase_exportLgrForCompletions take WellPath objects and
expose refinement and split type. Lgr::SplitType is registered as the
Python StrEnum LgrSplitType. RicfCreateLgrForCompletions forwards to
the create method. Case.create_lgr_for_completion() in Python is kept
and emits a DeprecationWarning.
RimEclipseCase_exportMswCompletions takes WellPath objects and an
explicit export folder. RicfExportMsw resolves the well path name and
export folder and forwards to it. Case.export_msw() in Python is kept
and emits a DeprecationWarning.
RimEclipseCase_exportCompletions takes WellPath objects (empty list
means all visible well paths) and an explicit export folder, and
exposes all completion export settings. The existing enums
ExportSplit, CompdatExport and PressureDepletionWBHPSource are
registered as Python StrEnums CompletionExportSplit,
CompdatExportType and TransScalingWbhpSource.
RicfExportWellPathCompletions resolves well path names to objects and
the export folder from the command file executor, then forwards to the
object method. Case.export_well_path_completions() in Python is kept
and emits a DeprecationWarning.
RimEclipseView_exportVisibleCells writes a FLUXNUM/MULTNUM/ACTNUM
keyword based on cell visibility in the view and requires an explicit
export file. The export keyword reuses
RicSaveEclipseInputVisibleCellsUi::ExportKeyword, registered as the
Python StrEnum VisibleCellsExportKeyword.
RicSaveEclipseInputVisibleCellsFeature::exportVisibleCells() is split
out of executeCommand() to return errors via std::expected instead of
only logging them.
RicfExportVisibleCells resolves the export folder from the command file
executor's CELLS export path and forwards to the object method. The
hand-written View.export_visible_cells() wrapper is removed since the
generated EclipseView method shadows it.
RimEclipseView_exportCurrentProperty exports the cell result shown in
the view at its current time step to a GRDECL style text file, and
requires an explicit export file. RicfExportPropertyInViews selects the
views by id/name, resolves the default file names from the command file
executor's PROPERTIES export folder, and forwards to it for each view.
The method is named exportCurrentProperty rather than exportProperty to
avoid shadowing the legacy View.export_property() wrapper (different
signature) in the generated Python class hierarchy. The legacy wrapper
is kept and emits a DeprecationWarning.
RimEclipseCase_exportProperty writes a cell property to a GRDECL style
text file and requires an explicit export file. RicfExportProperty
resolves the default file name from the command file executor's
PROPERTIES export folder and forwards to it.
The hand-written Case.export_property() wrapper is removed. The
generated Reservoir.export_property() has the same argument names and
shadows the base class wrapper anyway, so a deprecation shim would
never be reached.
- Add RimViewWindow_exportSnapshot on RimViewWindow (3D views and
plots) with explicit ExportFolder, Prefix, Width, Height and
FileFormat parameters. Generated as ViewWindow.export_snapshot().
- Add RimProject_exportSnapshots for exporting all views and/or plots
with a ContentType parameter. Generated as Project.export_snapshots().
- Add RiaDefines::SnapshotFileFormat and SnapshotContentType enums,
registered as Python StrEnums.
- Extract single-item exportSnapshotOfView()/exportSnapshotOfPlot()
from the RicSnapshotAll*ToFileFeature loops so the object methods
and the legacy loops share the implementation.
- RicfExportSnapshots resolves the export folder from the command file
executor and forwards to the object methods.
Python: the hand-written ViewWindow.export_snapshot() wrapper is
removed (generated method is compatible). PlotWindow.export_snapshot()
and Project.export_snapshots() keep their legacy argument names
(file_prefix, output_format, snapshot_type, plot_format) as deprecated
aliases. Case.export_snapshots_of_all_views() is deprecated in favor
of View.export_snapshot().
Also fix Case.views(), which compared the view id to the case id and
therefore never returned any views.
Rim3dView_setTimeStep validates the time step against the owner case
and updates the view. RicfSetTimeStep forwards to it, looping over all
views of the case when viewId is -1. The hand-written Python
View.set_time_step() wrapper is removed since the generated method has
the same name and signature.
Also fix the argument description of the new Rimc methods: the whatsThis
text is the third variadic argument of CAF_PDM_InitScriptableField.
Rim3dView_clone copies an Eclipse or GeoMech view into the same case
and returns the new view. RicfCloneView forwards to it. Add a
project-wide RicfForwarding::findView(viewId) helper. The hand-written
Python View.clone() wrapper is removed since the generated method has
the same name and signature.
RimCase_createView creates a 3D view in an Eclipse or GeoMech case and
returns it. RicfCreateView forwards to it and wraps the view id in the
legacy createViewResult. The hand-written Python create_view() wrapper
is removed since the generated method has the same name and signature.
First step in modernizing the command file interface: move the
implementation of legacy Ricf commands into object-oriented Rimc
methods, and let the Ricf command forward to them.
- Add RimCase_replaceGrid (PdmVoidObjectMethod on RimCase) with
NewGridFile and optional ProjectFile parameters. Works for both
Eclipse result cases and GeoMech cases. Generated in Python as
Case.replace_grid().
- Add RicfCommandForwarding helpers for resolving ids to objects and
converting std::expected results to PdmScriptResponse.
- RicfSingleCaseReplace::execute() now resolves the case and the
executor's last project path, then forwards to RimCase_replaceGrid.
Command file syntax and Commands.proto are unchanged.
- Case.replace() in Python is kept as a thin wrapper over
replace_grid() and emits a DeprecationWarning.
RigStatisticsCalculator::mobileVolumeWeightedMean() accumulated into a sum
from an out-parameter that callees were not required to write. Every
implementation of the per time step overload has early-return paths that
leave the value untouched, as does RigWeightedMeanCalc::weightedMeanOverCells,
so indeterminate stack memory could be summed and presented in the UI.
Return std::optional<double> from the computation layer instead of using an
out-parameter, making "value not available" explicit and impossible to ignore:
- RigWeightedMeanCalc::weightedMeanOverCells
- RigStatisticsCalculator::mobileVolumeWeightedMean and all overrides
Time steps without a computable mean no longer contribute to the accumulated
sum, and are excluded from the divisor. Previously they would either add
garbage or, with a naive zero initialisation, bias the average towards zero.
RigStatisticsDataCache keeps the existing HUGE_VAL marker on its public API
via value_or(), so behaviour seen by RigHistogramData and the overlay info
is unchanged apart from the fix.
Also:
- Set m_isVolumeWeightedMeanCalculated in the per time step cache, which was
never assigned, so the cached value was recomputed on every call.
- Remove a duplicated ensureKnownResultLoaded() call in
RigEclipseNativeVisibleCellsStatCalc.
Fixes#14766
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.
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.
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.
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.