Pile Result Script Example#

Download the RS3_Result_Scripting_Example folder for this example.

from rs3.RS3Modeler import RS3Modeler
from rs3.results.ResultEnums import PileInterfaceDataType, BeamsDataType
from rs3.Geometry import Point, Cube
import os

Get the current folder directory.

current_dir = os.path.dirname(os.path.abspath(""))

Specify a port number that is not in use and start the RS3 program.

port = 60505
RS3Modeler.startApplication(port)
2026-03-13 17:11:20,877 - Rocscience.RS3 - INFO - Attempting to start the application at C:\Program Files\Rocscience\RS3\RS3 and binding server to port 60505...

Connect with the RS3 Modeler.

modeler = RS3Modeler(port)

For the demonstration purposes only, the model is copied for reuse. You may change the model path to your own model path.

model = modeler.openFile(rf"{current_dir}\example_models\RS3_Result_Scripting_Example\RS3_Result_Scripting_Example.rs3v3")

1. Get Node Results#

1.1 Define a box region to filter pile elements (optional)#

A cube region is defined by two corners. Only mesh nodes inside or intersecting the box will be returned. If you omit the region in the next step, all nodes in the model would be returned.

In this example, we want to query the pile under the middle of the foundation.

pile_query_region = Cube(
    corner1=Point(x=17.0, y=14.5, z=-11.0),
    corner2=Point(x=18.0, y=15.5, z=1.0),
)

1.2 Get the pile results object for the desired stage(s)#

getPileForepoleResults returns a list: one entry per stage requested. Here we request only stage 5, so the list has one element at index 0.

pile_results_list = model.Results.getPileForepoleResults(stageNumber=[5])
pile_results_stage_5 = pile_results_list[0]

1.3 Get all pile node results for this stage#

The region is defined for the central pile only, so only the node results related to this pile will be returned.

pile_node_results_list = pile_results_stage_5.getPileForepoleNodeResults(region=pile_query_region)

Build a lookup: NodeID -> nodal result object. This is used later to get coordinates for each node attached to an element.

pile_node_by_id = {nr.NodeID: nr for nr in pile_node_results_list}

1.4 Get pile element results within the region#

pile_element_results_list = pile_results_stage_5.getPileForepoleElementResults(region=pile_query_region)

1.5 Take one element and read its per-node result values#

Each element has attached nodes. getResults(…) returns a list of values, one per node of the element (in the same order as AttachedNodeIDs).

element_index = 0
selected_pile_element = pile_element_results_list[element_index]
pile_attached_node_ids = selected_pile_element.AttachedNodeIDs
# Interface total displacement (e.g. relative displacement at pile–soil interface).
pile_interface_disp_per_node = selected_pile_element.getNodeResult(
    PileInterfaceDataType.DISPLACEMENT_TOTAL,
)
# Beam total displacement (displacement of the pile beam itself).
pile_beam_disp_per_node = selected_pile_element.getNodeResult(
    BeamsDataType.DISPLACEMENT_TOTAL,
)

print(
    f"Pile element PileID={selected_pile_element.PileID} "
    f"(BeamID={selected_pile_element.BeamID}, InterfaceID={selected_pile_element.InterfaceID}), nodal results:"
)
for i in range(len(pile_attached_node_ids)):
    node_id = pile_attached_node_ids[i]
    nodal_result = pile_node_by_id[node_id]
    print(
        f"  Node {node_id} (PileID {nodal_result.PileID}): (x, y, z, Interface Total Disp., Beam Total Disp.) = "
        f"({nodal_result.XCoordinate}, {nodal_result.YCoordinate}, {nodal_result.ZCoordinate}, "
        f"{pile_interface_disp_per_node[i]}, {pile_beam_disp_per_node[i]})"
    )
Pile element PileID=3 (BeamID=88233, InterfaceID=88258), nodal results:
  Node 15585 (PileID 3): (x, y, z, Interface Total Disp., Beam Total Disp.) = (17.5, 15.0, 1.734723475976807e-18, 0.07092518500510456, 0.017067301965327904)
  Node 15586 (PileID 3): (x, y, z, Interface Total Disp., Beam Total Disp.) = (17.5, 15.0, -0.16711709414160175, 0.07053305172810298, 0.017065342359394702)

Since accessing results doesn’t change the model, close the model without saving.

model.close(False)

Close the program.

modeler.closeProgram()

Full Script#

# Pile Result Script Example
# Download the [RS3_Result_Scripting_Example folder](https://github.com/Rocscience/rs3-scripting/tree/main/docs/example_code/example_models/RS3_Result_Scripting_Example) for this example.
from rs3.RS3Modeler import RS3Modeler
from rs3.results.ResultEnums import PileInterfaceDataType, BeamsDataType
from rs3.Geometry import Point, Cube
import os
# Get the current folder directory.
current_dir = os.path.dirname(os.path.abspath(""))
# Specify a port number that is not in use and start the RS3 program.
port = 60505
RS3Modeler.startApplication(port)
# Connect with the RS3 Modeler.
modeler = RS3Modeler(port)
# For the demonstration purposes only, the model is copied for reuse. 
# You may change the model path to your own model path.
model = modeler.openFile(rf"{current_dir}\example_models\RS3_Result_Scripting_Example\RS3_Result_Scripting_Example.rs3v3")

# 1. Get Node Results
# 1.1 Define a box region to filter pile elements (optional)
# A cube region is defined by two corners. Only mesh nodes inside or intersecting 
# the box will be returned. If you omit the region in the next step, all nodes in 
# the model would be returned.
# In this example, we want to query the pile under the middle of the foundation.
pile_query_region = Cube(
    corner1=Point(x=17.0, y=14.5, z=-11.0),
    corner2=Point(x=18.0, y=15.5, z=1.0),
)

# 1.2 Get the pile results object for the desired stage(s)
# getPileForepoleResults returns a list: one entry per stage requested. Here we 
# request only stage 5, so the list has one element at index 0.
pile_results_list = model.Results.getPileForepoleResults(stageNumber=[5])
pile_results_stage_5 = pile_results_list[0]

# 1.3 Get all pile node results for this stage
# The region is defined for the central pile only, so only the node results related 
# to this pile will be returned.
pile_node_results_list = pile_results_stage_5.getPileForepoleNodeResults(region=pile_query_region)
# Build a lookup: NodeID -> nodal result object. This is used later to get coordinates 
# for each node attached to an element.
pile_node_by_id = {nr.NodeID: nr for nr in pile_node_results_list}

# 1.4 Get pile element results within the region
pile_element_results_list = pile_results_stage_5.getPileForepoleElementResults(region=pile_query_region)

# 1.5 Take one element and read its per-node result values
# Each element has attached nodes. getResults(...) returns a list of values, one per 
# node of the element (in the same order as AttachedNodeIDs).
element_index = 0
selected_pile_element = pile_element_results_list[element_index]
pile_attached_node_ids = selected_pile_element.AttachedNodeIDs
# Interface total displacement (e.g. relative displacement at pile–soil interface).
pile_interface_disp_per_node = selected_pile_element.getNodeResult(
    PileInterfaceDataType.DISPLACEMENT_TOTAL,
)

# Beam total displacement (displacement of the pile beam itself).
pile_beam_disp_per_node = selected_pile_element.getNodeResult(
    BeamsDataType.DISPLACEMENT_TOTAL,
)
print(
    f"Pile element PileID={selected_pile_element.PileID} "
    f"(BeamID={selected_pile_element.BeamID}, InterfaceID={selected_pile_element.InterfaceID}), nodal results:"
)
for i in range(len(pile_attached_node_ids)):
    node_id = pile_attached_node_ids[i]
    nodal_result = pile_node_by_id[node_id]
    print(
        f"  Node {node_id} (PileID {nodal_result.PileID}): (x, y, z, Interface Total Disp., Beam Total Disp.) = "
        f"({nodal_result.XCoordinate}, {nodal_result.YCoordinate}, {nodal_result.ZCoordinate}, "
        f"{pile_interface_disp_per_node[i]}, {pile_beam_disp_per_node[i]})"
    )
    
# Since accessing results doesn't change the model, close the model without saving.
model.close(False)
2026-03-13 17:12:17,093 - Rocscience.RS3 - INFO - Attempting to start the application at C:\Program Files\Rocscience\RS3\RS3 and binding server to port 60505...
Pile element PileID=3 (BeamID=88233, InterfaceID=88258), nodal results:
  Node 15585 (PileID 3): (x, y, z, Interface Total Disp., Beam Total Disp.) = (17.5, 15.0, 1.734723475976807e-18, 0.07092518500510456, 0.017067301965327904)
  Node 15586 (PileID 3): (x, y, z, Interface Total Disp., Beam Total Disp.) = (17.5, 15.0, -0.16711709414160175, 0.07053305172810298, 0.017065342359394702)