mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 15:10:22 -05:00
Python: Add first_date_as_comment option to generate_schedule_text
Some commercial simulators reject a DATES keyword whose value equals the simulation start date. The earliest event date is, by construction, that start date, so generate_schedule_text now emits it as a comment line (e.g. "-- Date: 1 JAN 2024") instead of a DATES keyword by default. The new first_date_as_comment parameter (default True) threads from the Python wrapper through the GenerateSchedule scriptable method into RicScheduleDataGenerator. Only the first/earliest date is affected; later dates are always emitted as DATES keywords. Pass first_date_as_comment=False to restore the previous behavior.
This commit is contained in:
1 parent
c722aa83e5
commit
cb9274ecd6
6 files changed
+122
-18
No files matched your search
@@ -296,9 +296,11 @@ class TestScheduleGeneration:
|
||||
# Apply events to create actual completions
|
||||
timeline.set_timestamp(timestamp="2024-12-31")
|
||||
|
||||
# Generate schedule text
|
||||
# Generate schedule text (keep the first date as a DATES keyword for this assertion)
|
||||
schedule_text = timeline.generate_schedule_text(
|
||||
eclipse_case=case, export_msw_for_wells=project.well_paths()
|
||||
eclipse_case=case,
|
||||
export_msw_for_wells=project.well_paths(),
|
||||
first_date_as_comment=False,
|
||||
)
|
||||
|
||||
# Verify schedule text contains expected keywords
|
||||
@@ -348,9 +350,11 @@ class TestScheduleGeneration:
|
||||
# Apply events to create actual completions
|
||||
timeline.set_timestamp(timestamp="2024-12-31")
|
||||
|
||||
# Generate schedule text
|
||||
# Generate schedule text (keep the first date as a DATES keyword for this assertion)
|
||||
schedule_text = timeline.generate_schedule_text(
|
||||
eclipse_case=case, export_msw_for_wells=project.well_paths()
|
||||
eclipse_case=case,
|
||||
export_msw_for_wells=project.well_paths(),
|
||||
first_date_as_comment=False,
|
||||
)
|
||||
|
||||
# Verify we have schedule text with completions and controls
|
||||
@@ -401,6 +405,62 @@ class TestScheduleGeneration:
|
||||
assert "DATES" in schedule_text, "Schedule should contain DATES keyword"
|
||||
assert "2024" in schedule_text, "Schedule should contain event dates"
|
||||
|
||||
def test_first_date_as_comment(self, project_with_case_and_well):
|
||||
"""Test that the first (earliest) date can be emitted as a comment.
|
||||
|
||||
The first date equals the simulation start date, which some commercial
|
||||
simulators reject as a DATES entry. With first_date_as_comment (the
|
||||
default), the earliest date becomes a comment line while later dates
|
||||
remain real DATES keywords.
|
||||
"""
|
||||
project, case, timeline = project_with_case_and_well
|
||||
|
||||
well_paths = project.well_paths()
|
||||
well_path_a = [wp for wp in well_paths if "A" in wp.name][0]
|
||||
|
||||
# Two distinct dates: earliest 2024-01-01, later 2024-06-01
|
||||
timeline.add_perf_event(
|
||||
event_date="2024-01-01",
|
||||
well_path=well_path_a,
|
||||
start_md=1800.0,
|
||||
end_md=2000.0,
|
||||
diameter=0.1,
|
||||
state="OPEN",
|
||||
)
|
||||
timeline.add_perf_event(
|
||||
event_date="2024-06-01",
|
||||
well_path=well_path_a,
|
||||
start_md=2000.0,
|
||||
end_md=2200.0,
|
||||
diameter=0.1,
|
||||
state="OPEN",
|
||||
)
|
||||
|
||||
timeline.set_timestamp(timestamp="2024-12-31")
|
||||
|
||||
# Default (first_date_as_comment=True): first date is a comment, later date a DATES keyword
|
||||
default_text = timeline.generate_schedule_text(
|
||||
eclipse_case=case, export_msw_for_wells=project.well_paths()
|
||||
)
|
||||
assert default_text, "Schedule text should not be empty"
|
||||
assert "-- Date: 1 JAN 2024" in default_text, (
|
||||
"First date should be emitted as a comment"
|
||||
)
|
||||
assert default_text.count("DATES") == 1, (
|
||||
"Only the later date should be a DATES keyword"
|
||||
)
|
||||
|
||||
# Explicit False: both dates emitted as DATES keywords (legacy behavior)
|
||||
legacy_text = timeline.generate_schedule_text(
|
||||
eclipse_case=case,
|
||||
export_msw_for_wells=project.well_paths(),
|
||||
first_date_as_comment=False,
|
||||
)
|
||||
assert "-- Date:" not in legacy_text, (
|
||||
"No date comment should be present when first_date_as_comment is False"
|
||||
)
|
||||
assert legacy_text.count("DATES") == 2, "Both dates should be DATES keywords"
|
||||
|
||||
def test_timestamp_filters_wells_in_schedule_output(
|
||||
self, project_with_case_and_well
|
||||
):
|
||||
@@ -1296,9 +1356,12 @@ class TestScheduleGeneration:
|
||||
is_producer=True,
|
||||
)
|
||||
|
||||
# Control events don't require set_timestamp
|
||||
# Control events don't require set_timestamp. Keep all dates as DATES keywords
|
||||
# so the chronological ordering of the keyword can be verified.
|
||||
schedule_text = timeline.generate_schedule_text(
|
||||
eclipse_case=case, export_msw_for_wells=project.well_paths()
|
||||
eclipse_case=case,
|
||||
export_msw_for_wells=project.well_paths(),
|
||||
first_date_as_comment=False,
|
||||
)
|
||||
|
||||
print(f"\nSchedule text for date ordering test:\n{schedule_text}")
|
||||
@@ -2224,9 +2287,11 @@ class TestScheduleKeywordEvents:
|
||||
},
|
||||
)
|
||||
|
||||
# Generate schedule text
|
||||
# Generate schedule text (keep the first date as a DATES keyword for this assertion)
|
||||
schedule_text = timeline.generate_schedule_text(
|
||||
eclipse_case=case, export_msw_for_wells=project.well_paths()
|
||||
eclipse_case=case,
|
||||
export_msw_for_wells=project.well_paths(),
|
||||
first_date_as_comment=False,
|
||||
)
|
||||
|
||||
print(f"\nSchedule text with RPTRST keyword:\n{schedule_text}")
|
||||
|
||||
@@ -288,6 +288,7 @@ def generate_schedule_text(
|
||||
self: WellEventTimeline,
|
||||
eclipse_case: EclipseCase,
|
||||
export_msw_for_wells: List[WellPath] = [],
|
||||
first_date_as_comment: bool = True,
|
||||
) -> str:
|
||||
"""Generate Eclipse schedule text for all wells in the collection.
|
||||
|
||||
@@ -304,6 +305,11 @@ def generate_schedule_text(
|
||||
multi-segment-well keywords (WELSEGS, COMPSEGS, WSEGVALV, WSEGAICD)
|
||||
are exported. Wells not in the list get no MSW keywords. An empty
|
||||
list (the default) suppresses MSW export for all wells.
|
||||
first_date_as_comment (bool): When True (the default), the first
|
||||
(earliest) date is written as a comment line (e.g. "-- Date: 1 JAN
|
||||
2024") instead of a DATES keyword. This avoids a DATES entry equal
|
||||
to the simulation start date, which some commercial simulators
|
||||
reject. Later dates are always emitted as DATES keywords.
|
||||
|
||||
Returns:
|
||||
str: Eclipse schedule text containing DATES, COMPDAT, WELSEGS, WCONPROD, etc.
|
||||
@@ -346,6 +352,7 @@ def generate_schedule_text(
|
||||
container = self.generate_schedule(
|
||||
eclipse_case=eclipse_case,
|
||||
export_msw_for_wells=export_msw_for_wells,
|
||||
first_date_as_comment=first_date_as_comment,
|
||||
)
|
||||
if container and container.values:
|
||||
return "".join(container.values)
|
||||
|
||||
Reference in new issue
Block a user