Commit Graph
189 Commits
Author SHA1 Message Date
Kristian Bendiksen 3eb63c0b8e #14772 Python: Add Case.replace_grid and forward replaceCase to it
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.
2026-09-22 14:19:23 +02:00
Kristian Bendiksen ef1ad39723 Python: Reject overwriting source summary vectors 2026-09-16 11:37:59 +02:00
Kristian Bendiksen dc1cc8e243 #14667 Python: Update tubing event interval test 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
Kristian Bendiksen 71c5b5a97d #14612 Simulator Events: Remove Orion project naming 2026-09-09 13:01:26 +02:00
Kristian Bendiksen 5ed45b8f19 #14648 Python: Support strings containing commas in list arguments
Lists sent from Python over gRPC are serialized as text, and the list parser split on every comma, also commas inside a string. A category name like "Coal,Calcite" was therefore split in two, and set_discrete_property_category_names() failed with "CategoryValues and CategoryNames must have matching sizes".

The list parser is now quote-aware, and ignores commas inside quoted strings and inside nested brackets and parentheses. A quoted item is parsed as a quoted string also when the surrounding text is unquoted, as is the case for text coming from Python. The Python client quotes and escapes strings in lists and tuples when they contain separator characters.

Add unit tests for the field serialization and a Python test for the category names.
2026-09-09 11:19:44 +02:00
Kristian Bendiksen 2e5a3a3d17 #14683 Python: Preserve positional heartbeat callback 2026-09-07 18:58:05 +02:00
Kristian Bendiksen 35614d160e #14683 Serve liveness requests on the gRPC server thread
Requests are queued by the completion queue thread and processed from the main
thread. A long running request, or an open progress dialog in the GUI, therefore
left every request unanswered for as long as that operation lasted, including
the liveness checks a client uses to decide whether ResInsight is still there.

Let a callback declare that it touches no application state, and serve those
directly on the completion queue thread instead of queueing them. GetVersion is
the only such callback, since it reads compile-time constants only. Everything
that touches the project or the data model is still processed on the main
thread, so no request can observe or modify the data model while another one is
running.

The allocated callback list is now used from both threads and is guarded by a
mutex. Shutdown takes a lock before flagging that it is in progress, so that it
waits for any dispatch already running on the completion queue thread and no new
request handler can be registered on a queue that is about to be shut down.

During a blocking call of 3.25 s, 65 pings were answered with a maximum latency
of 6.2 ms. Before this change none of them were answered until the call
completed.
2026-09-07 18:58:05 +02:00
Kristian Bendiksen b0496f82d6 #14683 Python: Do not treat a busy ResInsight as a dead one
ResInsight serves gRPC requests from its main thread, so a long running call
leaves the heartbeat pings unanswered for as long as that call runs. The
heartbeat counted those timeouts as connection failures and closed the channel,
which aborted the very call the user was waiting for. The client reported
"RipsError: Channel closed!" while the ResInsight process was alive and well.

Classify a ping that fails with DEADLINE_EXCEEDED or RESOURCE_EXHAUSTED as a
busy server and never count it towards the failure threshold. Only failures
that indicate a broken connection declare the connection lost. A new
busy_warning_sec argument controls when a warning is logged for a server that
has been unresponsive for a while, so long operations are visible without being
killed.

Keep the process handle from Instance.launch so the heartbeat can check whether
ResInsight actually exited. A dead process is now detected immediately and
reported with its exit code instead of a bare channel error, and check_alive()
repeats that diagnosis.
2026-09-07 18:58:05 +02:00
Kristian Bendiksen 4e0abb456f Fix crash when deleting a sub plot of a multi plot in console mode
RimMultiPlot::recreatePlotWidgets() dereferenced the viewer unconditionally. The viewer does not exist in console mode, so deleting a summary plot from Python through the generic PdmObject delete() crashed ResInsight in onChildDeleted(). Return early when there is no viewer, matching the other viewer accesses in RimMultiPlot.

Add Python regression tests for deleting a single summary plot inside a multi plot and for deleting a whole multi plot, and an example showing how project tree objects are removed with delete().
2026-09-07 14:11:02 +02:00
Kristian Bendiksen 7867205468 #14639 Orion Events: Allow signed operand in date arithmetic
A term operand had to be an unsigned integer or a DURATION variable, so
"DATE STARTUP = 2026-08-28 + -2" was rejected as a malformed declaration
instead of subtracting two days.

Accept an optional sign on the operand in date and duration expressions, and
share one pattern between the terms of a date expression and the UNTIL terms
of INSERT_DATE so the two cannot drift apart.

Fractional day offsets are still unsupported.
2026-09-01 11:56:59 +02:00
Kristian Bendiksen 98e39bc02f #14636 Orion Events: List COMMENT as valid item name
COMMENT is accepted on all keywords and is stored on the event instead of
being passed as keyword data, so it is not part of the item names reported
by opm-common. The validation error listed only the opm-common items, giving
no hint that COMMENT is allowed when a user mistyped it as COMMENTS.

Append COMMENT to the list of valid item names in the error message. Only the
diagnostic is affected, COMMENT is still handled as event metadata.
2026-09-01 11:56:59 +02:00
Kristian Bendiksen 1336eba81d #14635 Orion Events: Use well name alias for generic keywords 2026-09-01 11:56:59 +02:00
Kristian Bendiksen 3117b69069 #14637 Orion Events: Use perforation diameter 2026-09-01 11:56:59 +02:00
Kristian Bendiksen ebf0ef0cc0 #14637 #14641 Orion Events: Emit END first after date 2026-09-01 11:56:59 +02:00
Kristian Bendiksen d226e10e89 #14637 Orion Events: Rename report date directive 2026-09-01 11:56:59 +02:00
Kristian Bendiksen 753cd65672 #14637 Orion Events: Remove date prefix 2026-09-01 11:56:59 +02:00
Kristian Bendiksen b00471dce2 #14614 Orion Events: Add menu item for importing events from file
Add RicImportOrionEventsFeature to File -> Import -> Well Data and the well
path collection context menu. The feature opens a file dialog and launches
the Python interpreter asynchronously with the new --apply mode of the
rips.orion_events CLI, which connects back to the running instance through
RESINSIGHT_GRPC_PORT and applies the events to the well event timeline.
Output is shown in the Process Monitor panel.
2026-08-28 13:22:33 +02:00
Kristian Bendiksen 0cbb5f5935 #14615 Orion Events: Preserve historical keyword values 2026-08-27 10:14:27 +02:00
Kristian Bendiksen f88136eb6a #14573 Orion Events: Add recurring report dates 2026-08-26 14:28:42 +02:00
Kristian Bendiksen 74ffc822f2 #14538 Well path: Preserve renamed file well name
The renamed well path name is serialized correctly, but reopening the project reloads the source well path file and overwrites the saved name with the name from that file. The reload flag only protected the completion export name, despite the loader also updating the displayed well path name.

Only initialize the well path and export names from the source file during first import. Subsequent data reloads preserve the names stored in the project while continuing to refresh geometry and metadata.

Add an RMS well round-trip test that renames an imported well, saves and reopens the project, and verifies that the custom name is retained.
2026-08-25 08:25:20 +02:00
Kristian Bendiksen 41b7df5a20 #14571 Orion Events: Preserve post-processed events during merge 2026-08-24 13:26:19 +02:00
Kristian Bendiksen 64317dfad7 #14575 Orion Events: Rename WELLSPEC event to WELSPECS 2026-08-24 13:26:19 +02:00
Kristian Bendiksen 0adf471a5d #14514 Orion Events: Include report dates in schedule 2026-08-24 13:26:19 +02:00
Kristian Bendiksen 15adbeb9a1 #14575 Orion Events: Add context to validation errors 2026-08-24 13:26:19 +02:00
Kristian Bendiksen e1b192ff86 #14570 Orion Events: Fix schedule user metadata 2026-08-24 13:26:19 +02:00
Kristian Bendiksen d6878ea562 #14513 Orion Events: Add raw schedule text events 2026-08-24 13:26:19 +02:00
Kristian Bendiksen 2ef4814257 #13672 Python: Add APIs to arrange and link views 2026-08-24 12:43:44 +02:00
Kristian Bendiksen 51aa090668 Python: Restore WellTypeForExport enum export 2026-08-21 11:42:34 +02:00
Kristian Bendiksen ce12272721 #14557 Orion Events: Rename tubing event to segment 2026-08-20 11:02:55 +02:00
Kristian Bendiksen db1c1f1f13 #14554 Orion Events: Add WELLSPEC event 2026-08-20 11:02:55 +02:00
Kristian Bendiksen 27b45353ea Orion Events: Add restart schedule cutoff 2026-08-20 11:02:55 +02:00
Kristian Bendiksen 1278ee2404 Orion Events: Add group member events 2026-08-20 11:02:55 +02:00
Kristian Bendiksen c94d00a02a Orion Events: Merge matching dated events 2026-08-20 11:02:55 +02:00
Kristian Bendiksen 61f615ac4c Orion Events: Preserve event comments 2026-08-20 11:02:55 +02:00
Kristian Bendiksen c41e74b706 Orion Events: Verify aligned schedule columns 2026-08-20 11:02:55 +02:00
Kristian Bendiksen a362f868c3 Orion Events: Generate COMPORD for new wells 2026-08-20 11:02:55 +02:00
Kristian Bendiksen 0b7ce2252c Orion Events: Add schedule generation metadata 2026-08-20 11:02:55 +02:00
Kristian Bendiksen d57abe525d #14533 Orion events: Add group sections 2026-08-19 10:28:35 +02:00
Kristian Bendiksen 3932ac4519 #14535 Orion events: Parse boolean keyword values 2026-08-19 10:28:35 +02:00
Kristian Bendiksen 98147c5c9a #14535 Orion events: Validate keyword field names 2026-08-19 10:28:35 +02:00
Kristian Bendiksen afb13508dc #14514 Remove PERFID and DSHIFT from the ORIONEVENTS format
They are not planned as part of the file format. PERFID on a completion event is now an unknown-attribute error like any other unrecognized key, and DSHIFT on keyword events is forwarded unchanged instead of being stripped with a warning. FILTER keeps its ignore-with-warning behavior outside PERFORATION events.
2026-08-19 10:28:35 +02:00
Kristian Bendiksen b3d0256941 #14514 Add option to include list of dates into schedule file
GenerateSchedule gains an AdditionalDates parameter (ISO date strings). The dates are merged, deduplicated and sorted with the event dates and each becomes a DATES keyword even when no events fall on it, ensuring a summary report at that date in Eclipse/Flow. They are deliberately not filtered by the last applied timestamp.

The ORIONEVENTS 2.0 format gains a top-level REPORT <date-expr> directive (date variables and day arithmetic supported). Parsed dates are collected on OrionDocument.report_dates and surfaced by the applier as sorted ISO strings on ApplyReport.report_dates, ready to pass to generate_schedule_text(additional_dates=...).
2026-08-19 10:28:35 +02:00
Kristian Bendiksen 8c3df6076d #14366 Python: Add per-view surface controls 2026-08-19 10:14:59 +02:00
Kristian Bendiksen 56fb7a660b #14367 Python: Add per-view polygon visibility API 2026-08-19 10:14:59 +02:00
Kristian Bendiksen a95c3f7ab9 #14484 Orion Events: parse and apply data filter
Add a typed FILTER declaration to the ORIONEVENTS 2.0 grammar, e.g.
FILTER POROPERM = "PORO > 0.4 AND PERMX > 100.0". A PERFORATION event
references it with FILTER=POROPERM or supplies an inline quoted
expression. When applied, each used filter is materialized as a
case-level combined data filter (one property filter per term, one-sided
inclusive bounds, AND/OR combine mode) and attached to the perforation.

Unqualified result names are searched in STATIC_NATIVE, DYNAMIC_NATIVE
then GENERATED results; a TYPE. qualifier restricts the search. Missing
results raise before any event is applied. apply_orion_document gains an
optional case= parameter defaulting to the project's first case.

RimWellEventPerf carries a RimCellFilter ptr-field with scriptable
AddFilter/cell_filter methods, and the filter is copied onto the
RimPerforationInterval when the timeline materializes completions.
2026-08-10 14:41:36 +02:00
Kristian Bendiksen de942cc8aa Python: Extend ORIONEVENTS with completion events, SCHEDULE block and datetimes
Extend the 2.0 format to cover the full WellEventTimeline API demonstrated
by well_event_schedule.py.

Add built-in TUBING, VALVE and STATE event types mapping to
add_tubing_event, add_valve_event (including the AICD parameters) and
add_state_event, validated with the same required/unknown-attribute
handling as PERFORATION.

Pass any other event type inside a WELL block through generically as an
Eclipse well keyword via add_well_keyword_event with the well name
injected, so WRFTPLT, WCONPROD and the rest work without enumeration.
Event types that closely resemble a misspelled built-in are handled by
the on_unknown_event policy with a did-you-mean hint instead of being
passed through.

Add a SCHEDULE block: a bare SCHEDULE line opens a block of well-less
keyword events (RPTRST, GRUPTREE, TUNING, ...) applied through
add_keyword_event; completion events in a SCHEDULE block are rejected.
Parsed schedule events live in OrionDocument.schedule_events.

Accept ISO datetimes in event dates (@2024-05-15T14:45:30.500); the
time-of-day survives into the generated DATES keyword's TIME field with
millisecond precision. Day-offset arithmetic applies to datetimes too.

Ship well_event_schedule_orion.py, an ORIONEVENTS counterpart to
well_event_schedule.py, and extend the test suite from 55 to 70 tests
including an integration test that applies every event kind and verifies
the generated schedule text.
2026-08-07 14:34:35 +02:00
Kristian Bendiksen 03236ee737 Python: Redesign ORIONEVENTS grammar as version 2.0 with typed declarations
Replace the 1.0 grammar with a version 2.0 designed to be easier to parse
and easier to write. Variables are now typed: DATE, DURATION (whole days)
and WELL alias declarations replace the untyped SET, and using a variable
of the wrong type produces an error citing both the use and declaration
site. Well blocks open with an explicit WELL keyword (alias or
double-quoted literal name), quoting is double quotes throughout, and
date arithmetic accepts signed chains of integers and DURATION variables
such as @START + RAMP - 2. ORIONEVENTS 1.x headers are rejected with a
migration message.

FILTER and PERFID are no longer parse errors; any KEY=VALUE attribute
parses and the applier warns and ignores the not-yet-supported keys
(FILTER, PERFID, DSHIFT) while still applying the rest of the event.

The parser now recovers per line and reports every error in one pass via
OrionParseError.errors, unknown variables, event types and keywords get
difflib-based did-you-mean hints, and a stdlib-only validator CLI runs as
python3 -m rips.orion_events <file>. The eager orion_events import in
rips/__init__.py is replaced by a PEP 562 lazy import so the -m entry
point does not trigger runpy's double-import warning.

Update the shipped sample file and example script to the 2.0 syntax and
extend the test suite from 27 to 55 tests covering typed declarations,
offset arithmetic, alias resolution, multi-error diagnostics and the CLI.
2026-08-07 14:34:35 +02:00
Kristian Bendiksen 1f346d28fd Python: Add ORIONEVENTS well-event-timeline parser
Add a pure-Python parser (rips.orion_events) that reads an ORIONEVENTS
text file into a structured representation, plus an applier that drives
the existing WellEventTimeline API to create perforation, WCONHIST and
WELTARG events.

The parser is split into a stdlib-only Layer A (parse_orion_events ->
OrionDocument) that is unit-testable without a running ResInsight, and a
Layer B applier (apply_orion_document) that maps the document onto
add_perf_event/add_well_keyword_event and resolves well names via the
project. RADIUS is mapped to diameter, dated SET variables support '+ N'
day arithmetic, and FILTER/PERFID are reserved but currently raise a
located error while DSHIFT is ignored with a warning.

Ship a documented grammar in the module docstring, a clean sample input
(example_input_files/well_events.orion), a runnable example
(import_orion_events.py), and tests covering parsing, mapping and an
end-to-end integration test against a loaded case.
2026-08-07 14:34:35 +02:00
Magne Sjaastad ebf75c09a1 #14411 Enforce name uniqueness for surfaces, polygons and folders
* #14411 Enforce name uniqueness for surfaces, polygons and folders

Names must be unique among siblings sharing the same parent folder. Items in different folders may keep identical names, and comparison is case sensitive.

Siblings are the objects held by the same caf::PdmChildArrayField. Items and folders live in two distinct child arrays in caf::PdmNestedCollection, so a folder and an item may share a name under the same parent.

The Python API gets an OnNameConflict flag on AddFolder, CreatePolygon, ImportSurface and NewRegularSurface, supporting FAIL (default), AUTO_RENAME and OVERWRITE. NewSurface is left out, as grid case surfaces derive their tree label from the case and K index and carry no name of their own.
2026-08-07 08:34:58 +02:00