mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-31 17:17:50 -05:00
#14063 Well Event: Group records of same keyword across wells
The schedule generator previously concatenated full keyword blocks (`KEYWORD ... /\n/\n`) — one per well — producing verbose output where each WELSPECS / COMPDAT / WCONHIST / WELSEGS / COMPSEGS / etc. block appeared once per contributing well. Eclipse keywords are designed to hold multiple records under a single header; the per-well repetition is syntactically valid but bloats the file and obscures intent. Switch `RicScheduleDataGenerator` to accumulate `std::map<QString, Opm::DeckKeyword>` instead of raw concatenated text. Each per-well helper now returns an `Opm::DeckKeyword`, and a new `mergeKeyword` primitive appends its records into the accumulator entry, creating the entry from the helper's keyword on first encounter. At emission time each accumulated keyword is serialised once. To support this, `RifEventKeywordFormatter` is split: each `format*` QString function now wraps a corresponding `build*` function that returns `std::optional<Opm::DeckKeyword>`. `RimWellEventKeyword` and `RimKeywordEvent` expose a parallel `generateDeckKeyword` accessor. The text-scraping `extractKeywordName` helper becomes dead code and is removed.
This commit is contained in:
1 parent
d2e7bed6b8
commit
6ef024cee9
9 files changed
+249
-177
No files matched your search
@@ -1231,6 +1231,43 @@ class TestScheduleGeneration:
|
||||
assert jan_pos < feb_pos, "January should come before February"
|
||||
assert feb_pos < jun_pos, "February should come before June"
|
||||
|
||||
def test_keywords_grouped_across_wells(self, project_with_case_and_well):
|
||||
"""Regression for #14063: WELSPECS / COMPDAT records for multiple wells on
|
||||
the same date must appear under a single keyword header (not one block per well).
|
||||
"""
|
||||
project, case, timeline = project_with_case_and_well
|
||||
well_paths = project.well_paths()
|
||||
assert len(well_paths) >= 2, (
|
||||
"Test requires at least two well paths in the fixture"
|
||||
)
|
||||
|
||||
for wp in well_paths[:2]:
|
||||
timeline.add_perf_event(
|
||||
event_date="2024-01-01",
|
||||
well_path=wp,
|
||||
start_md=2000.0,
|
||||
end_md=2200.0,
|
||||
diameter=0.1,
|
||||
state="OPEN",
|
||||
)
|
||||
|
||||
timeline.set_timestamp(timestamp="2024-12-31")
|
||||
schedule_text = timeline.generate_schedule_text(eclipse_case=case)
|
||||
print(f"\nSchedule text for multi-well grouping:\n{schedule_text}")
|
||||
|
||||
# Exactly one "WELSPECS\n" header for all wells.
|
||||
welspecs_count = schedule_text.count("WELSPECS\n")
|
||||
assert welspecs_count == 1, (
|
||||
f"WELSPECS should appear once for grouped output; got {welspecs_count}:\n{schedule_text}"
|
||||
)
|
||||
|
||||
# Both well names must appear inside the WELSPECS block (between header and trailing '/' line).
|
||||
welspecs_block = schedule_text.split("WELSPECS\n", 1)[1].split("\n/\n", 1)[0]
|
||||
for wp in well_paths[:2]:
|
||||
assert wp.name.replace(" ", "") in welspecs_block.replace(" ", ""), (
|
||||
f"Well {wp.name!r} missing from grouped WELSPECS block: {welspecs_block!r}"
|
||||
)
|
||||
|
||||
|
||||
class TestKeywordEvents:
|
||||
"""Tests for well keyword event functionality."""
|
||||
|
||||
Reference in new issue
Block a user