mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-24 22:27:55 -05:00
#14684 Simulator Events: Allow schedule generation without a grid case
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.
This commit is contained in:
1 parent
4770abda8e
commit
360c3c69db
9 files changed
+256
-53
No files matched your search
@@ -3107,3 +3107,74 @@ class TestScheduleKeywordEvents:
|
||||
), f"flag {flag!r} missing from RPTRST output: {rptrst_block!r}"
|
||||
# False-valued flag must be omitted entirely.
|
||||
assert "OBSOLETE" not in rptrst_block
|
||||
|
||||
|
||||
class TestScheduleGenerationWithoutCase:
|
||||
"""Schedule generation without a grid case emits only grid-independent keywords."""
|
||||
|
||||
@pytest.fixture
|
||||
def project_with_well(self, rips_instance, initialize_test):
|
||||
case_root = dataroot.PATH + "/TEST10K_FLT_LGR_NNC"
|
||||
project = rips_instance.project
|
||||
project.import_well_paths(well_path_files=[case_root + "/wellpath_a.dev"])
|
||||
well_path_coll = project.descendants(rips.WellPathCollection)[0]
|
||||
return project, project.well_paths()[0], well_path_coll.event_timeline()
|
||||
|
||||
def test_wconhist_without_case(self, project_with_well):
|
||||
project, well_path, timeline = project_with_well
|
||||
assert not project.cases()
|
||||
|
||||
for event_date, rate in (("2024-01-01", 1000.0), ("2024-02-01", 2000.0)):
|
||||
timeline.add_well_keyword_event(
|
||||
event_date=event_date,
|
||||
well_path=well_path,
|
||||
keyword_name="WCONHIST",
|
||||
keyword_data={
|
||||
"WELL": well_path.name,
|
||||
"STATUS": "OPEN",
|
||||
"CMODE": "ORAT",
|
||||
"ORAT": rate,
|
||||
},
|
||||
)
|
||||
|
||||
schedule = timeline.generate_schedule_text()
|
||||
|
||||
assert schedule.count("WCONHIST") == 2
|
||||
assert "DATES" in schedule
|
||||
assert "WELSPECS" not in schedule
|
||||
assert "COMPDAT" not in schedule
|
||||
assert "WARNING" not in schedule
|
||||
|
||||
def test_perforation_without_case_is_skipped_with_warning(self, project_with_well):
|
||||
project, well_path, timeline = project_with_well
|
||||
|
||||
timeline.add_perf_event(
|
||||
event_date="2024-01-01",
|
||||
well_path=well_path,
|
||||
start_md=2000.0,
|
||||
end_md=2200.0,
|
||||
diameter=0.1,
|
||||
state="OPEN",
|
||||
)
|
||||
timeline.add_well_keyword_event(
|
||||
event_date="2024-01-01",
|
||||
well_path=well_path,
|
||||
keyword_name="WCONHIST",
|
||||
keyword_data={"WELL": well_path.name, "STATUS": "OPEN"},
|
||||
)
|
||||
timeline.set_timestamp(timestamp="2024-12-31")
|
||||
|
||||
schedule = timeline.generate_schedule_text(
|
||||
eclipse_case=None, export_msw_for_wells=[well_path]
|
||||
)
|
||||
|
||||
assert "WCONHIST" in schedule
|
||||
for keyword in ("WELSPECS", "COMPDAT", "WELSEGS", "COMPSEGS"):
|
||||
assert f"\n{keyword}\n" not in schedule
|
||||
warnings = [
|
||||
line for line in schedule.splitlines() if line.startswith("-- WARNING:")
|
||||
]
|
||||
export_name = well_path.completion_settings().well_name_for_export
|
||||
assert any("COMPDAT" in w and export_name in w for w in warnings)
|
||||
assert any("WELSPECS" in w for w in warnings)
|
||||
assert any("WELSEGS" in w for w in warnings)
|
||||
@@ -6,7 +6,7 @@ in a timeline-based event system. Events can be perforation events, valve events
|
||||
segment changes, well state changes, and production/injection control changes.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List
|
||||
from typing import Any, Dict, List, Optional
|
||||
from datetime import date, datetime
|
||||
|
||||
from .pdmobject import add_method
|
||||
@@ -330,7 +330,7 @@ def add_insert_date_event(
|
||||
@add_method(WellEventTimeline)
|
||||
def generate_schedule_text(
|
||||
self: WellEventTimeline,
|
||||
eclipse_case: EclipseCase,
|
||||
eclipse_case: Optional[EclipseCase] = None,
|
||||
export_msw_for_wells: List[WellPath] = [],
|
||||
first_date_as_comment: bool = True,
|
||||
align_columns: bool = False,
|
||||
@@ -345,7 +345,14 @@ def generate_schedule_text(
|
||||
text directly instead of a DataContainerString.
|
||||
|
||||
Arguments:
|
||||
eclipse_case (EclipseCase): Eclipse case to use for schedule generation.
|
||||
eclipse_case (Optional[EclipseCase]): Grid case used for the
|
||||
grid-dependent keywords. Any Eclipse-type case works, including
|
||||
Roff and corner point cases. When None (the default), the
|
||||
keywords that need grid geometry (WELSPECS, COMPORD, COMPDAT,
|
||||
COMPLUMP, WELSEGS, COMPSEGS, WSEGVALV, WSEGAICD) are skipped. Each
|
||||
well with skipped keywords gets a "-- WARNING:" comment line in the
|
||||
schedule header. DATES, well controls (WCONHIST, WCONINJH, WELTARG,
|
||||
...), schedule keywords and raw text are still emitted.
|
||||
export_msw_for_wells (List[WellPath]): Wells for which the
|
||||
multi-segment-well keywords (WELSEGS, COMPSEGS, WSEGVALV, WSEGAICD)
|
||||
are exported. Wells not in the list get no MSW keywords. An empty
|
||||
|
||||
Reference in new issue
Block a user