Bolt Spacing Study#
Download Parametric Study of Bolt Spacing for Wall folder for this example.
from rs2.modeler.RS2Modeler import RS2Modeler
from rs2.modeler.properties.PropertyEnums import *
from rs2.interpreter.RS2Interpreter import RS2Interpreter
from rs2.interpreter.InterpreterEnums import *
from rs2.interpreter.InterpreterGraphEnums import *
import os
import pandas as pd
import matplotlib.pyplot as plt
'''
This script demonstrates how to generate multiple models with different bolt spacing for
analyzing designs of an anchored sheet pile wall. In this script you have
control if you want to create models (create_new_models=True), analyze results (analyze_results=True) or both.
For model creation:
- tieback bolt spacing is varied for three cases and saved to new model files
For analysis:
- horizontal displacement along a created query line is outputted to an excel xlsx file
- horizontal displacement, axial force, shear force and bending moment diagrams over the depth of wall (liner) are generated
and this data is outputted to a csv file as well as to png image files
NOTE: User is guided on how to install openpyxl library to the Rocsript Python environment to output to xlsx format
'''
# Current directory
current_dir = os.path.dirname(os.path.abspath(__file__))
# Create output folder
output_dir = rf'{current_dir}\Bolt Spacing Study'
os.makedirs(output_dir, exist_ok=True)
# Bolt spacing values to test
spacings = [1, 2, 3] # metres
# Create new model file paths: [s=1.fez, s=2.fez, s=3.fez]
new_model_paths = []
for spacing in spacings:
filename = f's={spacing}m.fez'
output_path = os.path.join(output_dir, filename)
new_model_paths.append(output_path)
# Test Controls to conveniently modify a process without needing to run all processes
# You can also consider creating different functions for each process, which is handy for calling a process multiple times
create_new_models = True
analyze_results = True
# Modelling #################################################################################
if create_new_models:
# Start RS2 Modeler
RS2Modeler.startApplication(port=60054)
modeler = RS2Modeler(port=60054)
# Open model
model = modeler.openFile(rf"{current_dir}\Anchored Sheet Pile Wall Parametric Study (Initial).fez")
# Modify spacing and create new model, then extract data
for test_num in range(len(spacings)):
# Set new bolt spacing
for bolt in model.getAllBoltProperties():
bolt.Tieback.setOutofPlaneSpacing(spacings[test_num])
# Create new model
model.saveAs(new_model_paths[test_num])
# Compute model
model.compute()
# Open to view all new models
for new_model_path in new_model_paths:
model = modeler.openFile(new_model_path)
# Result Interpretation #######################################################################
if analyze_results:
# Let's examine stage 5 results
# Open RS2 Interpreter
RS2Interpreter.startApplication(port=60055)
interpreter = RS2Interpreter(port=60055)
# Here is how you can store all opened model result files and use them multiple times
all_model_results = [interpreter.openFile(new_model_path) for new_model_path in new_model_paths]
# Analysis stage
stage_number = 5
# Results Part I:
# Extract horizontal displacement data at stage 5 along the sheet pile wall (material queries)
# Generate 11 evenly-spaced points from top to bottom of wall: (10,18) to (10,8)
point_along_wall = [[10, 18 - i] for i in range(11)]
depths = [(18 - y) for [x, y] in point_along_wall]
# Create an empty distionary for the material queries data frame
mat_que_dict = {"Depth": depths}
for test_num in range(len(all_model_results)):
# Current model results file
model_results = all_model_results[test_num]
# Setting results to solid horizontal displacement
model_results.SetResultType(ExportResultType.SOLID_DISPLACEMENT_HORIZONTAL_DISPLACEMENT)
# Set model to stage 5
model_results.SetActiveStage(stage_number)
# Add a material query line along the wall
query_along_wall_id = model_results.AddMaterialQuery(points=point_along_wall)
# Get material query results for active stage
# Method 1: only one query line, so use index 0 (first and only query)
query_results = model_results.GetMaterialQueryResults()[0]
# Method 2: use the query unique id
for material_query_results in model_results.GetMaterialQueryResults():
if material_query_results.GetUniqueIdentifier() == query_along_wall_id:
query_results = material_query_results
break
spacing = spacings[test_num]
series_label = f"s = {spacing} m"
mat_que_dict[series_label] = []
for query_point in query_results.GetAllValues():
# Add data to the dictionary
mat_que_dict[series_label].append(query_point.GetValue())
# Convert the dictionary to data frame
mat_que_df = pd.DataFrame(mat_que_dict)
# Save the data frame to a csv
mat_que_df.to_csv(rf"{output_dir}\horiz disp to depth at stage 5.csv", index=False)
# Results Part II:
# Extract and plot axial force, shear force, and bending moment results at stage 5 for the liner
liner_results_dfs = [] # list of data frames to store liner results
for model_results in all_model_results:
# read liner axial force, shear force, and bending moment
liner_results = model_results.GetLinerResults(stages =[stage_number]) # output liner results on stage 5
all_stage_liner_results = liner_results[stage_number] # output a list of all liner results at stage 5
stage_liner_results = all_stage_liner_results[0] # get the one and only liner in this model
# Create a distionary for the data frame and fill with first node data
liner_first_node = stage_liner_results.liner_element_results[0]
liner_dict = {"Depth (m)":[18 - liner_first_node.start_y], # calculate depth from top of wall
"Horizontal Displacement (m)":[liner_first_node.displacement_x1],
"Axial Force (kN)":[liner_first_node.axial_force1],
"Shear Force (kN)":[liner_first_node.shear_force1],
"Bending Moment (kNm)":[liner_first_node.moment1]
}
for liner_node in stage_liner_results.liner_element_results:
# Add remaining data to the liner results dictionary
liner_dict["Depth (m)"].append(18 - liner_node.end_y) # calculate depth from top of wall
liner_dict["Horizontal Displacement (m)"].append(liner_node.displacement_x2)
liner_dict["Axial Force (kN)"].append(liner_node.axial_force2)
liner_dict["Shear Force (kN)"].append(liner_node.shear_force2)
liner_dict["Bending Moment (kNm)"].append(liner_node.moment2)
# Convert the dictionary to data frame
liner_results_dfs.append(pd.DataFrame(liner_dict))
# Uncomment to try using Pandas to save each case as a tab in excel as a xls file,
# Remember to install openpyxl!
# Open RS2 application: Scripting > Manage Python Environment
# Type "pip install openpyxl" and hit Enter
# To uninstall, repeat the above steps, but type "pip uninstall openpyxl"
'''
with pd.ExcelWriter(rf"{output_dir}\liner results at stage 5.xlsx") as writer:
for test_num in range(len(liner_results_dfs)):
liner_results_dfs[test_num].to_excel(writer, sheet_name=f"s = {spacings[test_num]} m", index=False)
'''
# Using Matplotlib library to plot data
# define a function to format plot
def format_plot():
plt.gca().spines['bottom'].set_position(('data',0)) # move x-axis to y=0
plt.gca().xaxis.set_label_position('top') # set x-axis label position to the top
plt.gca().invert_yaxis() # invert y-axis
plt.gca().spines['left'].set_position(('data',0)) # move y-axis to x=0
plt.gca().spines['top'].set_visible(False) # hide the top spine
plt.gca().spines['right'].set_visible(False) # hide the right spine
# Plot Liner Horizontal Displacement
plt.figure()
plt.xlabel("Horizontal Displacement (m)")
plt.ylabel("Depth (m)")
plt.title("Liner Horizontal Displacement at Stage 5")
for test_num in range(len(liner_results_dfs)):
liner_results_df = liner_results_dfs[test_num]
plt.plot(liner_results_df["Horizontal Displacement (m)"], liner_results_df["Depth (m)"], label=f"s = {spacings[test_num]} m")
# format plot display
plt.legend()
format_plot()
plt.gca().yaxis.set_label_position('right') # set y-axis label position to the right
plt.gca().spines['left'].set_position(('data',-0.03)) # move y-axis to x=-0.03
# save plot
plt.savefig(rf"{output_dir}\liner horizontal displacement at stage 5.png")
# Plot Liner Axial Force
plt.figure()
plt.xlabel("Axial Force (kN)")
plt.ylabel("Depth (m)")
plt.title("Liner Axial Force at Stage 5")
for test_num in range(len(liner_results_dfs)):
liner_results_df = liner_results_dfs[test_num]
plt.plot(liner_results_df["Axial Force (kN)"], liner_results_df["Depth (m)"], label=f"s = {spacings[test_num]} m")
# format plot display
plt.legend()
format_plot()
plt.gca().yaxis.set_label_position('left') # set y-axis label position to the left
# save plot
plt.savefig(rf"{output_dir}\liner axial force at stage 5.png")
# Plot Liner Shear Force Diagram
plt.figure()
plt.xlabel("Shear Force (kN)")
plt.ylabel("Depth (m)")
plt.title("Liner Shear Force at Stage 5")
for test_num in range(len(liner_results_dfs)):
liner_results_df = liner_results_dfs[test_num]
plt.plot(liner_results_df["Shear Force (kN)"], liner_results_df["Depth (m)"], label=f"s = {spacings[test_num]} m")
# format plot display
plt.legend()
format_plot()
plt.gca().yaxis.set_label_position('right')
# save plot
plt.savefig(rf"{output_dir}\liner shear force at stage 5.png")
# Plot Liner Bending Moment
plt.figure()
plt.xlabel("Bending Moment (kNm)")
plt.ylabel("Depth (m)")
plt.title("Liner Bending Moment at Stage 5")
# Extract data for Liner Bending Moment Diagram
for test_num in range(len(liner_results_dfs)):
liner_results_df = liner_results_dfs[test_num]
plt.plot(liner_results_df["Bending Moment (kNm)"], liner_results_df["Depth (m)"], label=f"s = {spacings[test_num]} m")
# format plot display
plt.legend()
format_plot()
plt.gca().yaxis.set_label_position('right')
# save plot
plt.savefig(rf"{output_dir}\liner bending moment at stage 5.png")
plt.show()
# close the figure windows to finish the script