Project 511
Project 511
CE 511: Advanced
Structural Analysis and Vibrations – Term Project
Second Semester 2023- (232)
Structural Analysis Program for Truss
In structural engineering, truss structure analysis is important since it is used in the design
and assessment of many different civil engineering projects. Trusses are essential parts of
towers, bridges, roofs, and other load-bearing structures because of their ease of use and
effectiveness in supporting axial loads. It is essential to comprehend how trusses behave
under various loading scenarios in order to maximize design parameters and guarantee
structural integrity.
In this project, we primarily concentrate on the analysis of truss structures using the direct
stiffness method, a popular analytical methodology. Based on the concepts of compatibility
and equilibrium, the stiffness technique provides a methodical way to figure out the internal
forces and deformations in a truss structure. The stiffness technique makes it easier to
formulate equations governing the equilibrium and compatibility of the overall structure by
modeling truss components as linear elastic elements connected at nodal points.
The main goal of this project is to create a Python implementation of the truss analysis
stiffness method. Python is widely recognized for its ease of use, adaptability, and copious
scientific computing libraries, making it a perfect platform for executing intricate engineering
algorithms. Our goal is to develop a user-friendly application that will allow researchers and
engineers to properly and efficiently study truss structures by utilizing Python's computing
power.
Furthermore, the utilization of Python for implementing the stiffness method offers several
advantages over traditional methods. Python's intuitive syntax and extensive ecosystem of
libraries, such as NumPy and SciPy, streamline the implementation process and facilitate
seamless integration with other engineering analysis tools. Additionally, Python's open-
source nature fosters collaboration and knowledge sharing within the engineering
community, enabling practitioners to leverage collective expertise for solving complex
engineering problems. By adopting Python for truss analysis, engineers can benefit from the
platform's versatility, scalability, and accessibility, paving the way for more efficient and
collaborative approaches to structural engineering analysis and design.
In this report, we will use the direct stiffness method in the Python programming language
for the analysis and evaluation of truss structures. Following a few examples, the outcomes
will be compared with computations performed by hand and Mathematica at the conclusion.
Abstract
The Python software that is provided here conducts a thorough analysis of truss
constructions using the Direct Stiffness Method (DSM). The script precisely calculates
internal forces, reactions, and displacements within truss members under various loads by
utilizing the DSM. First, the script defines the geometry of the truss, including material
parameters like Young's modulus and cross-sectional area, as well as nodes coordinates and
members connectivity. Next, using the connectivity and material attributes of each truss
component as a basis, it aggregates the stiffness contributions to create a global stiffness
matrix. The script effectively computes nodal displacements and member forces using matrix
operations after applying boundary conditions and loads. Features for visualization are added
to show the internal force distribution and distorted shape of the truss. Because of its modular
design, the script may be easily integrated with other structural analysis tools and customized
for different engineering applications. This DSM implementation in Python provides
engineers and researchers with a comprehensive and adaptable way to analyze and optimize
truss constructions.
Program Notation
The notation used in this computer program for truss structures is summarized in this section.
Identifier Definition
Identifier Definition
a) By Mathematica
Control 1 2 1
data
a 3 4 6 3 10000
b 1 75 100
2 0 0
3 75 0
Structural data
4 150 0
c 1 2 1 10
2 1 3 10
3 1 4 10
d 2 1 1
3 1 1
4 1 1
a 1 0
b 1 20 10
Load data
c
Output data from Python
#CONTROL DATA
ITS = input("Enter ISN, ITS and NLS: ").split()
NA = int(ITS[2])#FOR INITIALIZATION OF NUMBER OF LOADING SYSTEMS
Z = 1 #FOR INITIALIZATION OF LOOP
if int(ITS[1]) == 2:
MI =(input("Enter M, NJ, NRJ and E : ")).split()
m = int(MI[0])
NJ = int(MI[1])
NRJ = int(MI[2])
E = float(MI[3])
X = [0 for i in range(NJ)]
Y = [0 for i in range(NJ)]
for i in range(NJ):
Joint_Co = input("Enter Joint(K) and Coordinates X(J) and Y(J):
").split()
X[int(Joint_Co[0]) - 1] = float(Joint_Co[1])
Y[int(Joint_Co[0]) - 1] = float(Joint_Co[2])
J = [0 for i in range(m)]
K = [0 for i in range(m)]
EL = [0 for i in range(m)]
Cx = [0 for i in range(m)]
Cy = [0 for i in range(m)]
Ax = [0 for i in range(m)]
for i in range(m):
Member_info = (input(f"For member {i + 1}, Enter J and K ends, and
Area Ax: ").split())
J[i] = Member_info[0]
K[i] = Member_info[1]
ELX = float(X[int(Member_info[1]) - 1]) -
float(X[int(Member_info[0]) - 1])
ELY = float(Y[int(Member_info[1]) - 1]) -
float(Y[int(Member_info[0]) - 1])
EL[i] = float((ELX * ELX + ELY * ELY) ** 0.5)
Cx[i] = ELX / (float(EL[i]))
Cy[i] = ELY / (float(EL[i]))
Ax[i] = float(Member_info[2])
ND = 2*NJ
SMS = [[0 for i in range(ND)] for i in range(ND)]
Matrix = []
for i in range(m):
SCM = [[0 for i in range(ND)] for i in range(ND)]
j1 = 2 * (int(J[i])) - 2
j2 = 2 * (int(J[i])) - 1
k1 = 2 * (int(K[i])) - 2
k2 = 2 * (int(K[i])) - 1
SM = [[0 for i in range(4)] for i in range(4)]
SMi = [[0 for i in range(4)] for i in range(4)]
Matrix.append(SMi)
#zia alrahman # 2557774
for i in range(len(SCM)):
for j in range(len(SCM[0])):
SMS[i][j] = SMS[i][j] + SCM[i][j]
ID = [0 for i in range(ND)]
for i in range(NJ):
ID[2 * int(i + 1) - 2] = 2 * i
ID[2 * int(i + 1) - 1] = 2 * i + 1
C = np.cumsum(np.array(JRL))
B = [0 for i in range(ND)]
NR = C[-1]
N = ND - NR
NF = N - 1
for i in range(ND):
if JRL[int(i)] == 1:
B[i] = NF + C[i]
else:
B[i] = ID[i] - C[i]
print("")
Z = 1 # FOR INITIALIZATION OF LOOP
LN = 0 # FOR INITIALIZATION OF LOADING NUMBER
while NA != 0:
LN = LN + 1
print(f"PARAMETERS FOR LOADING NO. {LN}")
NLJM = input("Enter Number of Loaded Joint(NLJ) and Loaded
Member(NLM): ", ).split()
AJ = [0 for i in range(ND)]
NLA = [0 for i in range(int(NLJM[0]))] # FOR INDEXING
for i in range(int(NLJM[0])):
NLJT = input("Loaded Joint(K), AJX(2K-1), AJY(2K): ").split()
NLA[i] = int(NLJT[0])
AJ[(2 * int(NLJT[0]) - 2)] = int(NLJT[1])
AJ[(2 * int(NLJT[0]) - 1)] = int(NLJT[2])
RTT = []
for i in range(m):
RT = [[0 for i in range(4)] for i in range(4)]
RT[0][0] = Cx[i]
RT[1][0] = -Cy[i]
RT[2][0] = 0
RT[3][0] = 0
RT[0][1] = Cy[i]
RT[1][1] = Cx[i]
RT[2][1] = 0
RT[3][1] = 0
RT[0][2] = 0
RT[1][2] = 0
RT[2][2] = Cx[i]
RT[3][2] = -Cy[i]
RT[0][3] = 0
RT[1][3] = 0
RT[2][3] = Cy[i]
RT[3][3] = Cx[i]
RTT.append(RT)
print("")
AE = [0 for i in range(ND)]
AMLX = [[0 for i in range(4)] for i in range(m)]
NLM = [0 for i in range(int(NLJM[1]))] # FOR INDEXING
for i in range(int(NLJM[1])):
AMX = [0 for i in range(4)]
NLMT = input("Loaded Member(M), AML(2J-1), AML(2J), AML(2K-1),
AML(2K): ").split()
NLM[i] = NLMT[0]
AMX[0] = float(NLMT[1])
AMX[1] = float(NLMT[2])
AMX[2] = float(NLMT[3])
AMX[3] = float(NLMT[4])
AMLX[int(NLMT[0]) - 1] = AMX
AC = [0 for i in range(ND)]
for i in range(ND):
AC[i] = AE[i] + AJ[i]
DF = np.linalg.solve(np.array(SFF), np.array(AFC))
DJ = [0 for i in range(ND)]
for i in range(N):
DJ[i] = DF[i]
DJA = [0 for i in range(ND)]
for i in range(ND):
DJA[i] = DJ[int(B[i])]
DJXX[i] = DJX
f1 = open('TRUSS.txt', 'a')
np.set_printoptions(precision=2)
orig_stdout = sys.stdout
sys.stdout = f1
while Z > 0:
Z = Z - 1
print(f"STRUCTURE NO. {int(ITS[0])} PLANE TRUSS")
print("NUMBER OF LOADING SYSTEMS = ", int(ITS[2]))
print("")
print("STRUCTURAL PARAMETERS\n" + f"{'M':>5}" + f"{'N':>5}" +
f"{'NJ':>5}" + f"{'NR':>5}" + f"{'NRJ':>5}" + f"{'E':^18}")
print(f"{m:>5}" + f"{N:>5}" + f"{NJ:>5}" + f"{NR:>5}" + f"{NRJ:>5}"
+ f"{E:^18}")
print("")
print(f"JOINT COORDINATES\n" + f"{'JOINT':>5}" + f"{'X':>12}" +
f"{'Y':>12}")
for i in range(NJ):
print(f"{i + 1:>5}" + f"{"{:.3F}".format(float(X[i])):>12}" +
f"{"{:.3F}".format(float(Y[i])):>12}")
print("")
print(f"MEMBER INFORMATION\n" + f"{'MEMBER':>6}" + f"{'JJ':>4}" +
f"{'JK':>5}" + f"{'AX':>12}" + f"{'EL':>12}" + f"{'CX':>12}" +
f"{'CY':>12}")
for i in range(m):
print(f"{i + 1:>5}" + f"{int(J[i]):>5}" + f"{int(K[i]):>5}" +
f"{"{:.3F}".format(float(Ax[i])):>12}" +
f"{"{:.3F}".format(float(EL[i])):>12}"+
f"{"{:.3F}".format(float(Cx[i])):>12}" +
f"{"{:.3F}".format(float(Cy[i])):>12}")
print("")
print(f"JOINT RESTRAINTS\n" + f"{'JOINT':>5}" + f"{'JR1':>5}" +
f"{'JR2':>5}")
for i in range(NRJ):
print(f"{int(RJ[i]):>5}" + f"{int(JRL[(2 * int(RJ[i]))-2]):>5}" +
f"{int(JRL[(2 * int(RJ[i]))-1]):>5}")
print("")
print(f"LOADING NO. {LN:>3} \n" + f"{'NLJ':>5}" + f"{'NLM':>5}")
print(f"{int(NLJM[0]):>5}" + f"{int(NLJM[1]):>5}")
print("")
if int(NLJM[0]) != 0:
print(f"ACTIONS AT JOINTS \n" + f"{'JOINT':>5}" + f"{'AJ1':>12}" +
f"{'AJ2':>12}")
for i in range(int(NLJM[0])):
print(
f"{int(NLA[i]):>5}" + f"{"{:.3F}".format(float(AJ[(2 * int(NLA[i]) -
2)])):>12}" + f"{"{:.3F}".format(float(AJ[(2 * int(NLA[i]) -
1)])):>12}")
print("")
if int(NLJM[1]) != 0:
print(
"ACTIONS AT END OF RESTRAINTS MEMBERS DUE TO LOADS\n" +
f"{'MEMBER':>6}" + f"{'AML1':>11}" + f"{'AML2':>12}" +
f"{'AML3':>12}" + f"{'AML4':>12}")
for i in range(int(NLJM[1])):
print(
f"{int(NLM[i]):>5}" + f"{"{:.3F}".format(float(AMLX[int(NLM[i]) - 1]
[0])):>12}" + f"{"{:.3F}".format(float(AMLX[int(NLM[i]) - 1]
[1])):>12}" + f"{"{:.3F}".format(float(AMLX[int(NLM[i]) - 1]
[2])):>12}" + f"{"{:.3F}".format(float(AMLX[int(NLM[i]) - 1]
[3])):>12}")
print("")
print(f"JOINT DISPLACEMENTS\n" + f"{'JOINT':>5}" + f"{'DJ1':>12}" +
f"{'DJ2':>12}")
for i in range(NJ):
print(
f"{i + 1:>5}" + f"{"{:.4E}".format(float(DJA[2 * i])):>12}" +
f"{"{:.4E}".format(float((DJA[2 * i + 1]))):>12}")
print("")
print("MEMBER END-ACTIONS\n" + f"{'MEMBER':>6}" + f"{'AM1':>11}" +
f"{'AM2':>12}" + f"{'AM3':>12}" + f"{'AM4':>12}")
for i in range(m):
print(
f"{i + 1:>5}" + f"{"{:.3F}".format(float(AMLF[i][0])):>12}" +
f"{"{:.3F}".format(float(AMLF[i][1])):>12}" +
f"{"{:.3F}".format(float(AMLF[i][2])):>12}" +
f"{"{:.3F}".format(float(AMLF[i][3])):>12}")
print("")
print(f"SUPPORT REACTIONS\n" + f"{'JOINT':>5}" + f"{'AR1':>12}" +
f"{'AR2':>12}")
for i in range(NRJ):
print(
f"{int(RJ[i]):>5}" + f"{"{:.3F}".format(float(ARRA[(2 * int(RJ[i]))-
2])):>12}" + f"{"{:.3F}".format(float(ARRA[(2 * int(RJ[i]))-
1])):>12}")
sys.stdout = orig_stdout
NA = NA - 1
f1.close
Conclusion
In conclusion, engineers and researchers now have a cutting-edge and adaptable way to
perform truss analysis using the Direct Stiffness Method (DSM) in Python. The tool makes
use of Python's many libraries and flexibility to offer a user-friendly platform for accurate
and efficient truss structure analysis. Productivity is increased and the analytical process is
streamlined by having the ability to design truss geometry, specify material parameters, and
view findings all within the same environment. A number of benefits emerge when
contrasting the Python implementation with conventional Fortran-based methods. Python is
more approachable to a broader spectrum of users, including those without substantial
programming knowledge, thanks to its clarity and simplicity of usage. Additionally, a wider
range of tools for deciphering and analyzing truss structures are available thanks to Python's
rich ecosystem of libraries for numerical computation, data analysis, and visualization.
Although Fortran's syntax and high learning curve make it difficult for certain users to use, it
is nonetheless a capable language for numerical calculation. All things considered, the DSM
for truss analysis implementation in Python is a noteworthy development in structural
engineering software, providing a potency, adaptability, and user-friendliness that can assist
researchers and engineers in a variety of fields. Python's contribution to structural analysis is
anticipated to increase as computational tools advance, significantly boosting engineering
practices' efficacy and efficiency.