Skip to content

Commit db8317f

Browse files
committed
Update rips module and Python examples
1 parent 332cd9a commit db8317f

File tree

9 files changed

+239
-3
lines changed

9 files changed

+239
-3
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
###################################################################################
2+
# This example will connect to ResInsight, retrieve a list of
3+
# simulation wells for a case and get the accumulated perforated length for all
4+
# simulation wells per timestep. If a well is closed at a given timestep, the
5+
# accumulated perforated length will be zero.
6+
###################################################################################
7+
8+
# Import the ResInsight Processing Server Module
9+
import rips
10+
import sys
11+
12+
# Connect to ResInsight
13+
resinsight = rips.Instance.find()
14+
if resinsight is None:
15+
sys.exit("ResInsight is not running. Please start ResInsight and try again.")
16+
17+
# Get a list of all wells
18+
cases = resinsight.project.cases()
19+
if len(cases) == 0:
20+
sys.exit("No cases found in the project. Please open a case and try again.")
21+
22+
case = cases[0]
23+
print("Using Case: " + case.name)
24+
25+
timesteps = case.time_steps()
26+
27+
# store results in a dictionary,
28+
# use well name as the key and a list of the wells accumulated perforation
29+
# lengths for each timestep as the value
30+
results = {}
31+
32+
# loop over all available simulation wells
33+
sim_wells = case.simulation_wells()
34+
for sim_well in sim_wells:
35+
acclengths = []
36+
for tidx, timestep in enumerate(timesteps):
37+
acclengths.append(sim_well.accumulated_perforation_length(tidx))
38+
results[sim_well.name] = acclengths
39+
40+
# Print header
41+
header = ["Timestep"]
42+
for tidx, ts in enumerate(timesteps):
43+
header.append("%d/%d/%d" % (ts.day, ts.month, ts.year))
44+
print(";".join(header))
45+
46+
# Print the results
47+
for well_name, lengths in results.items():
48+
line = [well_name]
49+
for idx, length in enumerate(lengths):
50+
line.append(str(length))
51+
print(";".join(line))

docs/rips/PythonExamples/wells_and_fractures/modeled_well_path.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@
6868
completions_settings.well_type_for_export = "GAS"
6969
completions_settings.update() # Commit updates back to ResInsight
7070

71+
# Add diameter roughness intervals for interval-specific configuration
72+
interval1 = completions_settings.add_diameter_roughness_interval(
73+
start_md=3200, end_md=3300, diameter=0.18, roughness_factor=1.5e-5
74+
)
75+
interval2 = completions_settings.add_diameter_roughness_interval(
76+
start_md=3300, end_md=3400, diameter=0.16, roughness_factor=2.0e-5
77+
)
78+
print(
79+
f"Added diameter roughness intervals: {interval1.start_md}-{interval1.end_md}m and {interval2.start_md}-{interval2.end_md}m"
80+
)
81+
7182
# Optionally update the MSW settings
7283
msw_settings = well_path.msw_settings()
7384
msw_settings.custom_values_for_lateral = False

docs/rips/generated/SimulationWell_pb2.py

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/rips/generated/SimulationWell_pb2_grpc.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ def __init__(self, channel):
4949
request_serializer=SimulationWell__pb2.SimulationWellRequest.SerializeToString,
5050
response_deserializer=SimulationWell__pb2.SimulationWellCellInfoArray.FromString,
5151
_registered_method=True)
52+
self.GetPerfLength = channel.unary_unary(
53+
'/rips.SimulationWell/GetPerfLength',
54+
request_serializer=SimulationWell__pb2.SimulationWellRequest.SerializeToString,
55+
response_deserializer=SimulationWell__pb2.SimulationWellPerfLength.FromString,
56+
_registered_method=True)
5257

5358

5459
class SimulationWellServicer(object):
@@ -66,6 +71,12 @@ def GetSimulationWellCells(self, request, context):
6671
context.set_details('Method not implemented!')
6772
raise NotImplementedError('Method not implemented!')
6873

74+
def GetPerfLength(self, request, context):
75+
"""Missing associated documentation comment in .proto file."""
76+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
77+
context.set_details('Method not implemented!')
78+
raise NotImplementedError('Method not implemented!')
79+
6980

7081
def add_SimulationWellServicer_to_server(servicer, server):
7182
rpc_method_handlers = {
@@ -79,6 +90,11 @@ def add_SimulationWellServicer_to_server(servicer, server):
7990
request_deserializer=SimulationWell__pb2.SimulationWellRequest.FromString,
8091
response_serializer=SimulationWell__pb2.SimulationWellCellInfoArray.SerializeToString,
8192
),
93+
'GetPerfLength': grpc.unary_unary_rpc_method_handler(
94+
servicer.GetPerfLength,
95+
request_deserializer=SimulationWell__pb2.SimulationWellRequest.FromString,
96+
response_serializer=SimulationWell__pb2.SimulationWellPerfLength.SerializeToString,
97+
),
8298
}
8399
generic_handler = grpc.method_handlers_generic_handler(
84100
'rips.SimulationWell', rpc_method_handlers)
@@ -142,3 +158,30 @@ def GetSimulationWellCells(request,
142158
timeout,
143159
metadata,
144160
_registered_method=True)
161+
162+
@staticmethod
163+
def GetPerfLength(request,
164+
target,
165+
options=(),
166+
channel_credentials=None,
167+
call_credentials=None,
168+
insecure=False,
169+
compression=None,
170+
wait_for_ready=None,
171+
timeout=None,
172+
metadata=None):
173+
return grpc.experimental.unary_unary(
174+
request,
175+
target,
176+
'/rips.SimulationWell/GetPerfLength',
177+
SimulationWell__pb2.SimulationWellRequest.SerializeToString,
178+
SimulationWell__pb2.SimulationWellPerfLength.FromString,
179+
options,
180+
channel_credentials,
181+
insecure,
182+
call_credentials,
183+
compression,
184+
wait_for_ready,
185+
timeout,
186+
metadata,
187+
_registered_method=True)

docs/rips/generated/generated_classes.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,27 @@ def __init__(self, pb2_object: Optional[PdmObject_pb2.PdmObject]=None, channel:
234234
if DepthSurface.__custom_init__ is not None:
235235
DepthSurface.__custom_init__(self, pb2_object=pb2_object, channel=channel)
236236

237+
class DiameterRoughnessInterval(PdmObjectBase):
238+
"""
239+
DiameterRoughnessInterval
240+
241+
Attributes:
242+
diameter (float): Diameter
243+
end_md (float): End MD
244+
roughness_factor (float): Roughness Factor
245+
start_md (float): Start MD
246+
"""
247+
__custom_init__ = None #: Assign a custom init routine to be run at __init__
248+
249+
def __init__(self, pb2_object: Optional[PdmObject_pb2.PdmObject]=None, channel: Optional[grpc.Channel]=None) -> None:
250+
self.diameter: float = 1.520000000000000e-01
251+
self.end_md: float = 0.000000000000000e+00
252+
self.roughness_factor: float = 1.000000000000000e-05
253+
self.start_md: float = 0.000000000000000e+00
254+
PdmObjectBase.__init__(self, pb2_object, channel)
255+
if DiameterRoughnessInterval.__custom_init__ is not None:
256+
DiameterRoughnessInterval.__custom_init__(self, pb2_object=pb2_object, channel=channel)
257+
237258
class EclipseCase(Reservoir):
238259
"""
239260
The Regular Eclipse Results Case
@@ -1708,6 +1729,7 @@ class MswSettings(PdmObjectBase):
17081729
17091730
Attributes:
17101731
custom_values_for_lateral (bool): Custom Values for Lateral
1732+
diameter_roughness_mode (str): One of [Uniform, Intervals]
17111733
enforce_max_segment_length (bool): Enforce Max Segment Length
17121734
length_and_depth (str): One of [INC, ABS]
17131735
liner_diameter (float): Liner Inner Diameter
@@ -1721,6 +1743,7 @@ class MswSettings(PdmObjectBase):
17211743

17221744
def __init__(self, pb2_object: Optional[PdmObject_pb2.PdmObject]=None, channel: Optional[grpc.Channel]=None) -> None:
17231745
self.custom_values_for_lateral: bool = False
1746+
self.diameter_roughness_mode: str = "Uniform"
17241747
self.enforce_max_segment_length: bool = False
17251748
self.length_and_depth: str = "ABS"
17261749
self.liner_diameter: float = 1.520000000000000e-01
@@ -2783,6 +2806,21 @@ def __init__(self, pb2_object: Optional[PdmObject_pb2.PdmObject]=None, channel:
27832806
if WellPathCompletionSettings.__custom_init__ is not None:
27842807
WellPathCompletionSettings.__custom_init__(self, pb2_object=pb2_object, channel=channel)
27852808

2809+
def add_diameter_roughness_interval(self, start_md: float=0.000000000000000e+00, end_md: float=1.000000000000000e+02, diameter: float=1.520000000000000e-01, roughness_factor: float=1.000000000000000e-05) -> DiameterRoughnessInterval:
2810+
"""
2811+
2812+
2813+
Arguments:
2814+
start_md (float):
2815+
end_md (float):
2816+
diameter (float):
2817+
roughness_factor (float):
2818+
Returns:
2819+
DiameterRoughnessInterval
2820+
"""
2821+
return self._call_pdm_method_return_value("AddDiameterRoughnessInterval", DiameterRoughnessInterval, start_md=start_md, end_md=end_md, diameter=diameter, roughness_factor=roughness_factor)
2822+
2823+
27862824
class WellPathCompletions(PdmObjectBase):
27872825
__custom_init__ = None #: Assign a custom init routine to be run at __init__
27882826

@@ -2989,6 +3027,7 @@ def class_dict() -> Dict[str, Type[PdmObjectBase]]:
29893027
classes['DataContainerTime'] = DataContainerTime
29903028
classes['DepthSurface'] = DepthSurface
29913029
classes['DepthTrackPlot'] = DepthTrackPlot
3030+
classes['DiameterRoughnessInterval'] = DiameterRoughnessInterval
29923031
classes['EclipseCase'] = EclipseCase
29933032
classes['EclipseCaseEnsemble'] = EclipseCaseEnsemble
29943033
classes['EclipseContourMap'] = EclipseContourMap

docs/rips/simulation_well.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,23 @@ def cells(
7777
return self.__simulation_well_stub.GetSimulationWellCells(sim_well_request).data
7878

7979

80+
@add_method(SimulationWell)
81+
def accumulated_perforation_length(self: SimulationWell, timestep: int) -> float:
82+
"""Get accumulated perforation lenght for the given timestep.
83+
If a well is closed the length will be 0.
84+
85+
Arguments:
86+
timestep(int): Time step index
87+
88+
"""
89+
sim_well_request = SimulationWell_pb2.SimulationWellRequest(
90+
case_id=self.case().id, well_name=self.name, timestep=timestep
91+
)
92+
return self.__simulation_well_stub.GetPerfLength(
93+
sim_well_request
94+
).accumulated_length
95+
96+
8097
@add_method(SimulationWell)
8198
def case(self: SimulationWell) -> Optional[Case]:
8299
view = self.ancestor(View)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import rips
2+
3+
4+
def test_diameter_roughness_intervals(rips_instance, initialize_test):
5+
"""Test the new diameter roughness intervals Python GRPC interface"""
6+
7+
# Create a test well
8+
well_path_coll = rips_instance.project.well_path_collection()
9+
well_path = well_path_coll.add_new_object(rips.ModeledWellPath)
10+
well_path.name = "Test Well for Diameter Intervals"
11+
12+
completions_settings = well_path.completion_settings()
13+
assert completions_settings is not None, "Completion settings should not be None"
14+
15+
# Test our new method - create first interval
16+
interval1 = completions_settings.add_diameter_roughness_interval(
17+
start_md=100, end_md=200, diameter=0.15, roughness_factor=1e-5
18+
)
19+
20+
# Assertions to verify the first interval
21+
assert interval1 is not None, "First interval should not be None"
22+
assert interval1.start_md == 100
23+
assert interval1.end_md == 200
24+
assert interval1.diameter == 0.15
25+
assert interval1.roughness_factor == 1e-5
26+
27+
# Test creating a second interval with different values
28+
interval2 = completions_settings.add_diameter_roughness_interval(
29+
start_md=200, end_md=300, diameter=0.12, roughness_factor=2e-5
30+
)
31+
32+
# Assertions to verify the second interval
33+
assert interval2 is not None, "Second interval should not be None"
34+
assert interval2.start_md == 200
35+
assert interval2.end_md == 300
36+
assert interval2.diameter == 0.12
37+
assert interval2.roughness_factor == 2e-5
38+
39+
# Test default values
40+
interval3 = completions_settings.add_diameter_roughness_interval()
41+
42+
assert interval3 is not None, "Third interval with defaults should not be None"
43+
assert interval3.start_md == 0.0
44+
assert interval3.end_md == 100.0
45+
assert interval3.diameter == 0.152
46+
assert interval3.roughness_factor == 1e-5

docs/rips/tests/test_simulation_wells.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sys
22
import os
3+
import math
34

45
sys.path.insert(1, os.path.join(sys.path[0], "../../"))
56

@@ -57,3 +58,19 @@ def test_10k(rips_instance, initialize_test):
5758
+ str(len(cells))
5859
)
5960
assert len(cells) == expected_cell_count[sim_well.name]
61+
62+
63+
def test_10k_acclength(rips_instance, initialize_test):
64+
case_path = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
65+
case = rips_instance.project.load_case(path=case_path)
66+
case.create_view()
67+
sim_wells = case.simulation_wells()
68+
69+
expected_length = {}
70+
expected_length["GP1"] = 4708.0
71+
expected_length["GI1"] = 2132.8
72+
expected_length["GP2"] = 49.0
73+
74+
for sim_well in sim_wells:
75+
length = sim_well.accumulated_perforation_length(1)
76+
assert math.fabs(length - expected_length[sim_well.name]) < 0.1

docs/source/PythonExamples_wells_and_fractures.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ Wells And Fractures
66

77
This page shows Python examples from the **wells_and_fractures** folder.
88

9+
.. _wells_and_fractures_accumulated_perforation_length:
10+
11+
Accumulated Perforation Length
12+
------------------------------
13+
14+
.. literalinclude:: ../rips/PythonExamples/wells_and_fractures/accumulated_perforation_length.py
15+
:language: python
16+
:linenos:
17+
:caption: accumulated_perforation_length.py
18+
919
.. _wells_and_fractures_all_simulation_wells:
1020

1121
All Simulation Wells

0 commit comments

Comments
 (0)