How to Compute the Deflection and Axial Forces of a Truss Bridge in Python

Written by kamalsamaila | Published 2022/09/16
Tech Story Tags: structural-engineering | finite-element-method | python-programming | python-tutorials | opensees | physics | python | software-engineering | web-monetization

TLDRThis article is important because analysis of a structure like a truss is time-consuming and students in the field of structural engineering are bound to make errors. It helps you to compute the stresses and displacements in structural elements. We will be using a python library called [anastruct] for the structural analysis of our structure. This is implemented by importing systemElements class from the anastruct library and instantiating the structure object. Then we can access all the structure objects states, including elements, materials and forces. We use the [anaStruct library for the implementation of the 2D Finite Element method for structures.via the TL;DR App

Introduction

I wrote a python program that calculates a truss bridge’s axial stresses and deflection by implementing the virtual work principle. To compute the deflection of a truss structure at any nodal point, we first have to compute the axial forces due to the external loads applied to the structure. Then, remove the external loads and replace them with a unit virtual load where the deflection is to be obtained.

We will be using a python library called anastruct for the structural analysis of our structure. Anastrcut is a python library for the implementation of the 2D Finite Element method for structures. It allows you to do a structural analysis of frames and trusses. It helps you to compute the stresses and displacements in structural elements.

This article is important because analysis of a structure like a truss is time-consuming and students in the field of structural engineering are bound to make errors. Hence, developing programs like this will help them in validating their answers

Supplies

  1. Personal computer
  2. Google colab for writing and running code
  3. Install the anaStruct library
  4. pandas library
  5. Question from structville website: as shown from the picture above, we are asked to compute the deflection at point c using the virtual work method

Step 1: Start Building Model by Adding Truss Elements or Members

To start building the model, we need to install the anaStruct library.

pip install anastruct

Then we build our Truss model by instantiating the structure object. This is implemented by importing systemElements class from the anastruct library and instantiating it.

Then we can access all the structure objects states, including elements, materials and forces.

#lets import the systemElemnts from the anastruct library
from anastruct import SystemElements
#instatiate the SystemElement object
ss = SystemElements()

#lets add truss members at node using add_truss_element method and passing coordinate loaction as argument to 
#define length of each member
ss.add_truss_element(location=[[0, 0], [3, 0]])
ss.add_truss_element(location=[[0, 0], [3, 3]])
ss.add_truss_element(location=[[3, 3], [3, 0]]) 
ss.add_truss_element(location=[[3, 0], [6, 3]])
ss.add_truss_element(location=[[3, 0], [6, 0]])
ss.add_truss_element(location=[[3, 3], [6, 3]])
ss.add_truss_element(location=[[6, 3], [6, 0]])
ss.add_truss_element(location=[[6, 3], [9, 3]])
ss.add_truss_element(location=[[6, 0], [9, 3]])
ss.add_truss_element(location=[[6, 0], [9, 0]])
ss.add_truss_element(location=[[9, 0], [9, 3]])

#this method plot our assemble structure
ss.show_structure()

Step 2: Add Support Conditions to the Model

What this code will be doing is adding support conditions to our truss model

# Add support condition
#the add_support_hinged function is used to specify hinge support
#the node_id argument is the nodal position at which the  support is placed which is an interger
ss.add_support_hinged(node_id=1) 
#the add_support_roll method is used to specify roller support
ss.add_support_roll(node_id=7)

Step 3: Add External Load to Nodes of the Model

okay let's add some point and horizontal loads to our model

# Add loadings
#the point_load method indicate it is a point load 
#the argument fy indicate it is a vertical force and negative sign indicate downard acting at node 4
ss.point_load(Fy=-6, node_id=3) 
#acting at node 4
ss.point_load(Fy=-4, node_id=4)
#Fx is a horizontal force acting in the positive direction at node 6
ss.point_load(Fx=+10, node_id=6)

Step 4: Compute and Plot the Axial Forces in Members Due to External Load

let’s calculate our axial forces in the members due to external load and plot the result

#this method compute all the reaction forces and axial forces in the model
ss.solve()
#this method plot the computed axial forces of the truss elements or members  
ss.show_axial_force()

Step 5: Plot the Reaction Forces Due to External Load

#this method plot the computed reaction forces at the support
ss.show_reaction_force()

Step 6: Plot Displacement of the Truss Bridge Due to External Loads

#this method plot the computed displacement of the entire model.
ss.show_displacement(factor=15)

Step 7: Remove External Load and Replace With Virtual Unit Load

we are replacing all external load and placing a virtual unit load at node 2 which is equivalent to node c from the original question

# we are creating another model and giving it a virtual
#this method reset the structure and remove the external applied loads
ss.remove_loads()
ss = SystemElements()
ss.add_truss_element(location=[[0, 0], [3, 0]])
ss.add_truss_element(location=[[0, 0], [3, 3]])
ss.add_truss_element(location=[[3, 3], [3, 0]])
ss.add_truss_element(location=[[3, 0], [6, 3]])
ss.add_truss_element(location=[[3, 0], [6, 0]])
ss.add_truss_element(location=[[3, 3], [6, 3]])
ss.add_truss_element(location=[[6, 3], [6, 0]])
ss.add_truss_element(location=[[6, 3], [9, 3]])
ss.add_truss_element(location=[[6, 0], [9, 3]])
ss.add_truss_element(location=[[6, 0], [9, 0]])
ss.add_truss_element(location=[[9, 0], [9, 3]])


#dd suupport
ss.add_support_hinged(node_id=1)
ss.add_support_roll(node_id=7)


#Add method add the  virtual unit load at node2
ss.point_load(Fy=-1, node_id=2)
ss.show_structure()
#we compute our member axial forces and reactions forces due to virtual unit load
ss.solve()

Step 8: Save Your Computation Results

we are saving our computation from the returned type of the get_element_result method which is a python list of dictionary

#this method store our calculation result of our elements or members in list of dictionary
list_ext=ss.get_element_results(element_id=0)

#this method returns a list of dictionary with our computed forces due to virtual load and we pass it to variable
list_vir=ss.get_element_results(element_id=0)

Step 9: Use Pandas to Create a Data Frame of Your Results

We are using the pandas data frame to store our results

# we import pandas and create a table for all our computed results
import pandas as pd
#we create an empty dataframe for storing our computed result due to external loads
df=pd.DataFrame()


#we create an empty dataframe for storing our computed result due to virtual unit load
pf=pd.DataFrame()


#we store our computed result due to external loads that return as a list of dictionary into a dataframe
df = df.append(list_ext, ignore_index=True, sort=False)
#we drop the 'alpha' and 'u' column
df.drop(['alpha', 'u'], axis = 1, inplace = True)
#we rename our dataframe columns 
df.rename(columns={'length': 'L(m)',
                   'N': 'N(kN)',
                   'id':'Members'},
          inplace=True, errors='raise')



#we store our computed result due to virtual unit load that return as a list of dictionary into another dataframe
pf = pf.append(list_vir,ignore_index=True, sort=False)
#we drop or delete 'alpha', 'u','length'columns
pf.drop(['alpha', 'u','length'], axis = 1, inplace = True) 


#we rename column'N' to 'n' 
pf.rename(columns={'N': 'n'},
          inplace=True, errors='raise')
#we use the concat method to combine our two dataframe 
df1= pd.concat([df, pf], axis=1, join='inner')
#we move columns
new_cols = ["Members","n","N(kN)","L(m)"]
df1=df1[new_cols]
#we multipy column n, N and L and create column nNL/AE
df1["nNL/AE"]= (df1["n"] * df1["N(kN)"] * df1["L(m)"])


#we use the display method to show our final dataframe table
display(df1.round(3))

Step 10: Compare Your Table and the Computed Deflection

The first table above is the author’s solution from the structville website and the second table is my program computed table

Let’s finally compute our deflection and compare it with one from the example

#we compute deflection at node 2
deflection = df1["nNL/AE"].sum()


print("The vertical deflection at node 2 is :",deflection.round(3),"/AE meters")

#output from the program
87.255/AE meters

#result from the example in the article
86.904/AE meters

Conclusion

From this article, it is possible to use the virtual force method to compute the deflection of a truss bridge using python programming. This is very important for students taking structural analysis courses to be able to verify their assignment answers. You can run the code here

My future work will be focusing on creating a user interface for drawing the truss, frames and beams in 2d as the input for the structural analysis programs.

Also published at here


Written by kamalsamaila | A technology advocate with passion in writing programs related to finite element method for engineering analysis
Published by HackerNoon on 2022/09/16