Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ def main():
)
print(" Added tubing event on 2024-01-01 (MD 0-2500m)")

# Add first perforation event
# Add first perforation event.
# completion_number assigns the perforation to a completion group, which makes
# the schedule emit a COMPLUMP keyword lumping these connections into group 1.
_perf_event1 = timeline.add_perf_event(
event_date="2024-02-01",
well_path=well_path,
Expand All @@ -61,10 +63,11 @@ def main():
diameter=0.1,
skin_factor=0.5,
state="OPEN",
completion_number=1,
)
print(" Added perforation event on 2024-02-01 (MD 2000-2200m)")
print(" Added perforation event on 2024-02-01 (MD 2000-2200m, completion 1)")

# Add second perforation event (later)
# Add second perforation event (later), assigned to a different completion group.
_perf_event2 = timeline.add_perf_event(
event_date="2024-04-01",
well_path=well_path,
Expand All @@ -73,8 +76,9 @@ def main():
diameter=0.1,
skin_factor=0.3,
state="OPEN",
completion_number=2,
)
print(" Added perforation event on 2024-04-01 (MD 2400-2600m)")
print(" Added perforation event on 2024-04-01 (MD 2400-2600m, completion 2)")

# Add valve event (requires existing perforation)
_valve_event = timeline.add_valve_event(
Expand Down Expand Up @@ -168,6 +172,27 @@ def main():
)
print(" Added GRUPTREE event on 2024-01-01 (group tree definition)")

# Example 6: TUNING - Time stepping / convergence control.
# TUNING is a multi-record keyword: items are distributed into the record that
# defines them (record 1: TSINIT/TSMAXZ/TMAXWC, record 3: NEWTMX..MXWPIT), so the
# generated keyword has three records, each terminated by its own '/'.
_tuning_event = timeline.add_keyword_event(
event_date="2024-01-01",
keyword_name="TUNING",
keyword_data={
"TSINIT": 1,
"TSMAXZ": 30,
"TMAXWC": 1,
"NEWTMX": 12,
"NEWTMN": 1,
"LITMAX": 50,
"LITMIN": 1,
"MXWSIT": 50,
"MXWPIT": 50,
},
)
print(" Added TUNING event on 2024-01-01 (time stepping / convergence control)")

# Apply events up to March 15, 2024
# This should create:
# - Tubing interval (Jan 1)
Expand Down Expand Up @@ -206,8 +231,11 @@ def main():
case = cases[0]
print(f" Using Eclipse case: {case.name}")

# Generate schedule text
schedule_text = timeline.generate_schedule_text(eclipse_case=case)
# Generate schedule text. Pass the wells that should get multi-segment-well
# keywords (WELSEGS, COMPSEGS, WSEGVALV, WSEGAICD); an empty list omits them.
schedule_text = timeline.generate_schedule_text(
eclipse_case=case, export_msw_for_wells=[well_path]
)

if schedule_text:
print(f"\n Generated schedule text ({len(schedule_text)} characters)")
Expand All @@ -224,11 +252,14 @@ def main():
"DATES",
"WELSEGS",
"COMPSEGS",
"COMPDAT",
"COMPLUMP",
"WCONHIST",
"WELTARG",
"WRFTPLT",
"RPTRST",
"GRUPTREE",
"TUNING",
]
found_keywords = [kw for kw in expected_keywords if kw in schedule_text]

Expand All @@ -247,6 +278,9 @@ def main():
if "COMPSEGS" in schedule_text:
print(" ✓ COMPSEGS keyword generated (completion segments)")

if "COMPLUMP" in schedule_text:
print(" ✓ COMPLUMP keyword generated (perforation completion groups)")

if "WSEGVALV" in schedule_text:
print(" ✓ WSEGVALV keyword generated (segment valves)")
# Extract valve parameters
Expand All @@ -265,12 +299,14 @@ def main():
print(f" - DATES entries: {schedule_text.count('DATES')}")
print(f" - WELSEGS entries: {schedule_text.count('WELSEGS')}")
print(f" - COMPSEGS entries: {schedule_text.count('COMPSEGS')}")
print(f" - COMPLUMP entries: {schedule_text.count('COMPLUMP')}")
print(f" - WSEGVALV entries: {schedule_text.count('WSEGVALV')}")
print(f" - WCONHIST entries: {schedule_text.count('WCONHIST')}")
print(f" - WELTARG entries: {schedule_text.count('WELTARG')}")
print(f" - WRFTPLT entries: {schedule_text.count('WRFTPLT')}")
print(f" - RPTRST entries: {schedule_text.count('RPTRST')}")
print(f" - GRUPTREE entries: {schedule_text.count('GRUPTREE')}")
print(f" - TUNING entries: {schedule_text.count('TUNING')}")

# Save to file
output_file = "generated_schedule.sch"
Expand Down Expand Up @@ -320,8 +356,12 @@ def main():
print(" keyword_data={'BASIC': 2, 'FREQ': 1}")
print(" )")
print("- timeline.set_timestamp(timestamp='2024-06-01') # Apply events up to date")
print("- schedule_text = timeline.generate_schedule_text(eclipse_case=case)")
print(" # Generate Eclipse schedule text")
print(
"- schedule_text = timeline.generate_schedule_text(eclipse_case=case, export_msw_for_wells=[well_path])"
)
print(
" # Generate Eclipse schedule text (export_msw_for_wells enables MSW keywords)"
)


if __name__ == "__main__":
Expand Down
14 changes: 8 additions & 6 deletions docs/rips/generated/generated_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3752,6 +3752,7 @@ class WellEventPerf(WellEvent):
WellEventPerf

Attributes:
completion_number (int): Completion Number
diameter (float): Diameter
end_md (float): End MD
skin_factor (float): Skin Factor
Expand All @@ -3761,6 +3762,7 @@ class WellEventPerf(WellEvent):
__custom_init__ = None #: Assign a custom init routine to be run at __init__

def __init__(self, pb2_object: Optional[PdmObject_pb2.PdmObject]=None, channel: Optional[grpc.Channel]=None) -> None:
self.completion_number: int = 0
self.diameter: float = 2.160000000000000e-01
self.end_md: float = 0.000000000000000e+00
self.skin_factor: float = 0.000000000000000e+00
Expand Down Expand Up @@ -3833,7 +3835,7 @@ def add_keyword_event_internal(self, event_date: str="2024-01-01", keyword_name:
return self._call_pdm_method_return_value("AddKeywordEventInternal", KeywordEvent, event_date=event_date, keyword_name=keyword_name, item_names=item_names, item_types=item_types, item_values=item_values)


def add_perf_event(self, event_date: str="2024-01-01", well_path: Optional[WellPath]=None, start_md: float=0.000000000000000e+00, end_md: float=0.000000000000000e+00, diameter: float=2.160000000000000e-01, skin_factor: float=0.000000000000000e+00, state: State=State.OPEN) -> WellEventPerf:
def add_perf_event(self, event_date: str="2024-01-01", well_path: Optional[WellPath]=None, start_md: float=0.000000000000000e+00, end_md: float=0.000000000000000e+00, diameter: float=2.160000000000000e-01, skin_factor: float=0.000000000000000e+00, state: State=State.OPEN, completion_number: int=0) -> WellEventPerf:
"""
Add a perforation event to the timeline

Expand All @@ -3845,10 +3847,11 @@ def add_perf_event(self, event_date: str="2024-01-01", well_path: Optional[WellP
diameter (float): Diameter [m]
skin_factor (float): Skin Factor
state (State): One of [OPEN, SHUT]
completion_number (int): Completion Number (for COMPLUMP, 0 = none)
Returns:
WellEventPerf
"""
return self._call_pdm_method_return_value("AddPerfEvent", WellEventPerf, event_date=event_date, well_path=well_path, start_md=start_md, end_md=end_md, diameter=diameter, skin_factor=skin_factor, state=state)
return self._call_pdm_method_return_value("AddPerfEvent", WellEventPerf, event_date=event_date, well_path=well_path, start_md=start_md, end_md=end_md, diameter=diameter, skin_factor=skin_factor, state=state, completion_number=completion_number)


def add_state_event(self, event_date: str="2024-01-01", well_path: Optional[WellPath]=None, well_state: WellState=WellState.OPEN) -> WellEventState:
Expand Down Expand Up @@ -3931,18 +3934,17 @@ def events(self) -> List[WellEvent]:
return self.children("Events", WellEvent)


def generate_schedule(self, eclipse_case: Optional[Reservoir]=None, include_welsegs: bool=True, include_compsegs: bool=True) -> DataContainerString:
def generate_schedule(self, eclipse_case: Optional[Reservoir]=None, export_msw_for_wells: List[WellPath]=[]) -> DataContainerString:
"""
Generate Eclipse schedule text for all wells in the collection

Arguments:
eclipse_case (Optional[Reservoir]): Eclipse Case
include_welsegs (bool): Include WELSEGS keyword in the exported schedule
include_compsegs (bool): Include COMPSEGS keyword in the exported schedule
export_msw_for_wells (List[WellPath]): Wells for which multi-segment-well keywords (WELSEGS, COMPSEGS, WSEGVALV, WSEGAICD) are exported
Returns:
DataContainerString
"""
return self._call_pdm_method_return_value("GenerateSchedule", DataContainerString, eclipse_case=eclipse_case, include_welsegs=include_welsegs, include_compsegs=include_compsegs)
return self._call_pdm_method_return_value("GenerateSchedule", DataContainerString, eclipse_case=eclipse_case, export_msw_for_wells=export_msw_for_wells)


def set_timestamp(self, timestamp: str="2024-01-01") -> None:
Expand Down
Loading