Skip to content
Merged
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
56 changes: 56 additions & 0 deletions docs/rips/PythonExamples/geomech/read_geomech_results.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
######################################################################
# This script loads a geomechanical case (.odb, .inp or VTK .pvd) and
# reads time steps, result names and result values into Python lists.
#
# Usage: python read_geomech_results.py <path to geomech case (.odb, .inp or VTK .pvd)>
######################################################################
import math
import sys

import rips

if len(sys.argv) < 2:
print("Usage: read_geomech_results.py <path to geomech case>")
sys.exit(1)

try:
resinsight = rips.Instance.find()
case = resinsight.project.load_case(sys.argv[1])
except Exception as exc:
print(f"Failed to load geomechanical case: {exc}")
sys.exit(1)

if not isinstance(case, rips.GeoMechCase):
print("The file is not a geomechanical case")
sys.exit(1)

time_steps = case.time_step_strings()
print("Time steps:", time_steps)

# Result names are "FIELD:COMPONENT", or "FIELD" for results without components
for position in rips.GeoMechResultPosition:
if position in (
rips.GeoMechResultPosition.WELLPATH_DERIVED,
rips.GeoMechResultPosition.DIFFERENTIALS,
):
continue
print(position, case.result_names(position))

# Print statistics for every result with defined values at one position.
# A negative frame_index (the default) selects the last frame of the time step.
position = rips.GeoMechResultPosition.NODAL
for name in case.result_names(position):
field_name, _, component_name = name.partition(":")
for time_step, label in enumerate(time_steps):
values = case.result_values(
field_name,
component_name,
time_step=time_step,
result_position=position,
)
finite = [v for v in values if math.isfinite(v)]
if finite:
print(
f"{name}, {label}: {len(values)} values, "
f"min={min(finite):.4g}, max={max(finite):.4g}"
)
71 changes: 71 additions & 0 deletions docs/rips/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
Case as Case,
EclipseCase as EclipseCase,
GeoMechCase as GeoMechCase,
GeoMechResultPosition as GeoMechResultPosition,
PorosityModelType as PorosityModelType,
PropertyDataType as PropertyDataType,
PropertyType as PropertyType,
Expand Down Expand Up @@ -303,6 +304,76 @@ def time_steps(self) -> List[Case_pb2.TimeStepDate]:
return self.__case_stub.GetTimeSteps(self.__request()).dates


@add_method(GeoMechCase)
def time_step_strings(self: GeoMechCase) -> List[str]:
"""Get the time step strings of this geomechanical case

Returns:
A list of time step strings, one per time step. The list index
matches the time_step argument of result_values().
"""
return self.time_step_strings_internal().values


@add_method(GeoMechCase)
def result_names(
self: GeoMechCase,
result_position: GeoMechResultPosition = GeoMechResultPosition.ELEMENT_NODAL,
) -> List[str]:
"""Get the result names of this geomechanical case

Arguments:
result_position(GeoMechResultPosition): Result position, for example
GeoMechResultPosition.NODAL or GeoMechResultPosition.ELEMENT_NODAL.

Returns:
A list of names on the form "FIELD:COMPONENT", or "FIELD" for results
without components.
"""
return self.result_names_internal(result_position=result_position).values


@add_method(GeoMechCase)
def result_values(
self: GeoMechCase,
field_name: str,
component_name: str = "",
time_step: int = 0,
result_position: GeoMechResultPosition = GeoMechResultPosition.ELEMENT_NODAL,
frame_index: int = -1,
) -> List[float]:
"""Read the values of a geomechanical result

Arguments:
field_name(str): Result field name, e.g. "ST" or "POR-Bar".
component_name(str): Result component name, e.g. "S1". Empty for results without components.
time_step(int): Zero-based time step index.
result_position(GeoMechResultPosition): Result position of the result.
frame_index(int): Zero-based frame index. Negative selects the last frame of the time step.

Returns:
The values of all parts, in the order used by ResInsight for the result position.
Values are NaN where the result is not defined.
"""
project = self.ancestor(Project)
if project is None:
raise RipsError("Could not find parent project")

key = f"{uuid.uuid4()}_geomech_result"
try:
self.read_result_values_internal(
result_position=result_position,
field_name=field_name,
component_name=component_name,
time_step=time_step,
frame_index=frame_index,
key=key,
)
return project.key_values(key) # type: ignore[attr-defined]
finally:
project.remove_key_values(key) # type: ignore[attr-defined]


@add_method(Case)
def reservoir_boundingbox(self) -> Case_pb2.BoundingBox:
"""Get the reservoir bounding box
Expand Down
Loading