ENGR 492 Course Project # 2
Two-Dimensional Static Truss Analysis
Introduction
The Stiffness Method
The stiffness method is a systematic approach used in structural analysis to calculate nodal displacements
and internal forces within a structure. It is based on the relationship between nodal forces \([F]\), nodal
displacements \([u]\), and the global stiffness matrix \([K]\), expressed as:
\[
[K][u] = [F]
\]
In this equation:
\([K]\): The global stiffness matrix representing the structure's resistance to deformation.
\([F]\): The nodal force vector representing external forces applied to the structure.
\([u]\) : The nodal displacement vector containing unknown displacements at each degree of freedom.
By solving this system of linear equations, the nodal displacements \([u]\) are determined, which can then
be used to compute internal forces and stresses in the truss elements.
Calculation of a 4x4 Stiffness Matrix - global
The stiffness matrix for a truss element in a global Cartesian coordinate system accounts for the
orientation of the element. This orientation is defined using the directional cosines:
\[
l = \cos\theta, \quad m = \sin\theta
\]
Here, \(l\) and \(m\) are the directional cosines corresponding to the horizontal and vertical axes,
respectively, and \(\theta\) is the angle of the element with respect to the global x-axis.
Using these directional cosines, the local stiffness matrix for a truss element is transformed into the
global stiffness matrix. For a single truss element, the 4x4 global stiffness and displacement matrices are
calculated as:
\[
[K] [u]=
\frac{EA}{L}
\begin{bmatrix}
l^2 & lm & -l^2 & -lm \\
lm & m^2 & -lm & -m^2 \\
-l^2 & -lm & l^2 & lm \\
-lm & -m^2 & lm & m^2
\end{bmatrix} \begin{bmatrix}
u_{\text{ initial}} \\
v_{\text{ initial}} \\
u_{\text{ final}} \\
v_{\text{ final}}
\end{bmatrix}
\]
In this equation:
\(E\): | The modulus of elasticity of the truss material. |
\(A\): | The cross-sectional area of the truss element. |
\(L\): | The length of the truss element. |
\(l, m:\) | Directional cosines for the global coordinate system. |
\(u, v\): | horizontal and vertical displacements, respectively. The subscripts \(\text{initial}\) and \(\text{final}\) correspond to the starting and ending nodes of the specific element. |
The stiffness matrix above captures the contribution of a single element in the global coordinate
system. When assembling the global stiffness matrix for the entire structure, these individual matrices are
added to their corresponding positions based on the nodes connected by the element.
The final global displacement matrix will have twice as many rows as there are degrees of freedom since each
degree of freedom has a displacement in the x and y axis, denoted \(u,v\) respectively.
Similarly, the global stiffness matrix will be a square matrix with dimensions equal to the number of rows of
the displacement vector.
The Global Stiffness Matrix
The stiffness matrix is a critical component of the stiffness method, used to calculate the displacements and
internal forces in a truss structure. It represents the relationship between nodal displacements and forces,
encapsulating the stiffness properties of all elements in the structure.
Construction
The global stiffness matrix is constructed as a square matrix, where the size is determined by twice the number
of nodes in the structure (to account for two degrees of freedom per node: horizontal and vertical
displacements). Each entry in the matrix is defined as follows:
\[ K = \begin{bmatrix} k_{11} & k_{12} & k_{13} & k_{14} \\ k_{21} & k_{22} & k_{23} & k_{24} \\ k_{31} & k_{32} & k_{33} & k_{34} \\ k_{41} & k_{42} & k_{43} & k_{44} \end{bmatrix} \]
Role in Truss Analysis
The global stiffness matrix serves as the backbone of the truss analysis process. By coupling the nodal
displacements and applied forces through the stiffness relationships, the system of equations \([K][u] = [F]\)
is formed. This system is then solved to obtain the displacements \([u]\), which are subsequently used to
calculate the internal stresses and reactions.
The details of solving this system and deriving additional results will be discussed in subsequent sections.
In this software, the global stiffness matrix was constructed directly by traversing the truss, node by node,
and summing up the individual contributions of each each element connected to a specific node.
The details on how this was done are expanded on in the Modeling section of this report.
Modeling
Data Structures and Coordinate Calculations
The application uses JavaScript classes to define and store the properties of each node, element, force, and
fixture in the truss system. This object-oriented approach allows for clean, reusable code and structured
storage of data. Below is an overview of the key classes and the calculations performed.
Node Class
The NODE
class is used to define the coordinates of a point in the truss
system. Each node is initialized with its \(x\) and \(y\) coordinates, representing its position in the
global Cartesian coordinate system. All nodes, elements, materials, and components (forces and fixtures)
created are stored in arrays. Each element and node are added to their respective arrays in order so that
their labels correspond to their indices in the array.
Nodes are initialized as follows:
new Node(x, y)
ELEMENT
class represents a truss member connecting two nodes. Each element is
initialized with a reference to the its initial and final node connections, denoted \(N_i\) and \(N_f\)
respectively. From these nodes, the coordinates of start and end position are saved as (\(x_i, y_i, x_j, y_j\)).
Moreover, elements are also initialized with a referece to a material object ( has Modulus of Elasticity \(E\)
and color properties) and cross-sectional area (\(A_r\)).
Elements are initialized as follows:
new Element(nodes[0],nodes[1], materials[0], Ar)
ELEMENT
class, calculations for various variables are computed and
saved, namely;
FIXTURE
and FORCE
classes are used to define
boundary conditions and external loads, respectively. Each fixture stores its angle, type (e.g., roller or
fixed), and the node its located at, while each force stores its angle, magnitude, and the node its located at.
This structured approach to data storage and computation ensures that the global stiffness matrix and force-displacement relationships are computed efficiently and accurately.
The Adjacency Matrix
The adjacency matrix is a fundamental component in the representation and analysis of truss structures within the application. It defines the connectivity between nodes, serving as the foundation for constructing the global stiffness matrix used in the stiffness method. Each element in the adjacency matrix indicates whether a direct connection (truss element) exists between two nodes and, if so, provides a reference to the associated element's properties.
Implementation
The adjacency matrix is implemented as a square matrix, where the number of rows and columns corresponds to the number of nodes in the structure. Each entry in the matrix is defined as follows:
> A value of 0 indicates no direct connection between the corresponding nodes.
> A non-zero entry contains a reference to the truss element connecting the two nodes.
\[ \begin{bmatrix} 0 & \text{Element 1} & \text{Element 2} & 0 \\ \text{Element 1} & 0 & \text{Element 3} & \text{Element 4} \\ \text{Element 2} & \text{Element 3} & 0 & \text{Element 5} \\ 0 & \text{Element 4} & \text{Element 5} & 0 \end{bmatrix} \]
Figure 1: The Adjacency Matrix for the Default setup of the truss
The matrix is constructed by iterating over all nodes and elements in the structure. For each element, the start (Ni) and end (Nf) nodes are identified, and the matrix is updated symmetrically to reflect the undirected nature of truss connections. This ensures that both directions of the connection are represented.
Role in the Stiffness Method
The adjacency matrix simplifies the process of assembling the global stiffness matrix. By providing a structured representation of node connections, it allows the program to efficiently determine the contributions of each element to the global stiffness matrix by providing a direct reference to the instance the specific element and the indices of the nodes it is connected to.
The specifics of how the stiffness matrix is constructed from the adjacecny matrix will be expanded on in the following section.
The Stiffness Matrix
The stiffness matrix is constructed using the adjacency matrix to map the connections between nodes and their associated elements. For the default configuration, the Global Stiffness Matrix \([K]\) matrix is assembled as follows:
\[ \begin{bmatrix} &a_1 + a_2 & b_1 + b_2 & |& -a_1 & -b_1 & | & -a_2 & -b_2 & |& 0 & 0 &\\ &b_1 + b_2 & c_1 + c_2 & |& -b_1 & -c_1 & | & -b_2 & -c_2 & |& 0 & 0 &\\ &--&--&--&--&--&--&--&--&--&--&--&\\ &-a_1 & -b_1 & |& a_1 + a_3 + a_4 & b_1 + b_3 + b_4 & | & -a_3 & -b_3 & |& -a_4 & -b_4 &\\ &-b_1 & -c_1 & |& b_1 + b_3 + b_4 & c_1 + c_3 + c_4 & | & -b_3 & -c_3 & |& -b_4 & -c_4 &\\ &--&--&--&--&--&--&--&--&--&--&--&\\ &-a_2 & -b_2 & |& -a_3 & -b_3 & | & a_2 + a_3 + a_5 & b_2 + b_3 + b_5 & |& -a_5 & -b_5 &\\ &-b_2 & -c_2 & |& -b_3 & -c_3 & | & b_2 + b_3 + b_5 & c_2 + c_3 + c_5 & |& -b_5 & -c_5 &\\ &--&--&--&--&--&--&--&--&--&--&--&\\ &0 & 0 & |& -a_4 & -b_4 & | & -a_5 & -b_5 & |& a_4 + a_5 & b_4 + b_5 &\\ &0 & 0 & |& -b_4 & -c_4 & | & -b_5 & -c_5 & |& b_4 + b_5 & c_4 + c_5 \end{bmatrix} \]
This matrix captures the stiffness contributions of each element in the system and represents the global stiffness matrix in the Cartesian coordinate system.
The coefficients \(a_i , b_i, c_i\) are calculated for the elements as :
\[
a = \frac{l^2 A_r E}{L}, \quad b = \frac{lm A_r E}{L}, \quad c = \frac{m^2 A_r E}{L}
\]
The global stiffness matrix of each individual element is then :
\[
[K_e] =
\begin{bmatrix}
&a & b & | & -a & -b &\\
&b & c & & -b & -c &\\
&-&-&+&-&- \\
&-a & -b & & a & b &\\
&-b & -c & | & b & c &
\end{bmatrix}
\]
FOR i = 0 to n-1: // Loop through each element at the current row of the adjacency matrix
IF element is connected (elConnected != 0):
// Update diagonal entries of the stiffness matrix
The final matrix is constructed using the adjacency matrix as a guide for which two nodes are connected by which element.
For each node pair connected by a truss
element, the stiffness contributions are calculated based on the element's coefficients and added to the corresponding entries in the stiffness matrix.
Psudo-code of the original algorithm used for the stiffness matrix is presented below to better demonstrate how the final stiffness matrix was assembled:
// Initialize a loop to go through each node
FOR each connected element in AdjMatrix[i]:
stiffnessMatrix[i*2][i*2] += Round(elConnected.a)
stiffnessMatrix[i*2][i*2 + 1] += Round(elConnected.b)
stiffnessMatrix[i*2 + 1][i*2] += Round(elConnected.b)
stiffnessMatrix[i*2 + 1][i*2 + 1] += Round(elConnected.c)
// Update off-diagonal entries (connections to other nodes)
stiffnessMatrix[i*2][index*2] -= Round(elConnected.a)
stiffnessMatrix[i*2][index*2 + 1] -= Round(elConnected.b)
stiffnessMatrix[i*2 + 1][index*2] -= Round(elConnected.b)
stiffnessMatrix[i*2 + 1][index*2 + 1] -= Round(elConnected.c)
// For example: For the first row of the ADJ Matrix, if the third index has an element reference,
That means the element referenced is connected from the first node to the third node. In this case,
the coefficients of that specific elemement are added to node 1's diagonal entry and
subtracted from node 3's off-diagonal entries with respect to node 1.
The Displacement and Force Matrices
The displacement and force matrices are key components of the stiffness method, representing the nodal
displacements and forces in the global coordinate system. These matrices are directly involved in solving the
system of equations:
\[
[K][u] = [F]
\]
where:
\([u]\): | The nodal displacement matrix containing horizontal (\(u\)) and vertical (\(v\)) displacements for each node. |
\([F]\): | The nodal force matrix containing the externally applied forces at each degree of freedom. |
For the default configuration with 4 nodes, the displacement matrix is structured as:
\[
[u] =
\begin{bmatrix}
u_1 \\ v_1 \\ u_2 \\ v_2 \\ u_3 \\ v_3 \\ u_4 \\ v_4
\end{bmatrix}
\]
Here, \(u_i\) and \(v_i\) represent the horizontal and vertical displacements of node \(i\), respectively.
Similarly, the force matrix is structured as:
\[
[F] =
\begin{bmatrix}
F_{x1} \\ F_{y1} \\ F_{x2} \\ F_{y2} \\ F_{x3} \\ F_{y3} \\ F_{x4} \\ F_{y4}
\end{bmatrix}
\]
where \(F_{xi}\) and \(F_{yi}\) are the external forces in the horizontal and vertical directions applied at
node \(i\), respectively.
Solution
Boundary Conditions
Boundary conditions are essential for ensuring the stiffness method produces a solvable system of equations.
In the
context of truss analysis, boundary conditions define the constraints applied to specific nodes, restricting
their
displacements in one or more directions and eliminating or defining forces.
There are three primary types of boundary conditions applied in the application:
To incorporate MPCs into the stiffness method, the global stiffness matrix \([K]\) is modified to reflect the coupling between horizontal and vertical degrees of freedom at the constrained node. This involves:
Finally, known reaction forces and displacements defined by fixed supports and unconstrained nodes are substituted
into the force and displacements vectors. Additionally, Extrnal forces defined by the user are split into their x and y components
then subsitiuted into the force vector.
For the default configuration of the truss, the \([u]\) & \([F]\) vectors become:
\[
[u]=
\begin{bmatrix}
u_{\text{1}} \\
v_{\text{1}} \\
u_{\text{2}} \\
v_{\text{2}} \\
u_{\text{3}} \\
v_{\text{3}} \\
0 \\
0 \\
F_{\text{x3}} \\
F_{\text{y3}}
\end{bmatrix}
\quad
\quad
[F]=
\begin{bmatrix}
F_{\text{ext-x}} \\
F_{\text{ext-y}} \\
0 \\
0 \\
0 \\
0 \\
F_{\text{x4}} \\
F_{\text{y4}} \\
0 \\
0 \\
\end{bmatrix}
\]
The substitutions here correspond to:
Partioning / Simplifying
The process of partitioning and simplifying is a critical step in preparing to solve the system of equations.
This step directly follows imposing the boundary conditions. partioning involves reducing the size of the system by
removing and holding onto the rows and columns that correspond to unknown reaction forces so that the unknown displacments
can be solved for first. Simplifying involves removing the rows and columns associated with known displacements.
After implementing boundary conditions, the resulting system of equations often includes rows and columns
corresponding to zero displacements. These rows and columns do not contribute to the solution of the unknown
displacements and can be safely removed to simplify the system.
The simplification process involves:
The partioning process involves:
This approach results in a reduced system of equations:
\[
[K_r][u_r] = [F_r]
\]
\[
\begin{bmatrix}
&a_{1+2} & b_{1+2} & -a_1 & -b_1 & -a_2 & -b_2 & 0 & 0& \\
&b_{1+2} & c_{1+2} & -b_1 & -c_1 & -b_2 & -c_2 & 0 & 0& \\
&-a_1 & -b_1 & a_{1+3+4} & b_{1+3+4} & -a_3 & -b_3 & 0 & 0& \\
&-b_1 & -c_1 & b_{1+3+4} & c_{1+3+4} & -b_3 & -c_3 & 0 & 0& \\
&-a_2 & -b_2 & -a_3 & -b_3 & a_{2+3+5} & b_{2+3+5} & -1& 0& \\
&-b_2 & -c_2 & -b_3 & -c_3 & b_{2+3+5} & c_{2+3+5} & 0 & -1& \\
&0 &0 &0 &0 & \cos\theta & \sin\theta & 0 & 0& \\
&0 &0 &0 &0 & 0 &0 & -\sin\theta & \cos\theta & \\
\end{bmatrix}
\begin{bmatrix}
u_{\text{1}} \\
v_{\text{1}} \\
u_{\text{2}} \\
v_{\text{2}} \\
u_{\text{3}} \\
v_{\text{3}} \\
F_{\text{x3}} \\
F_{\text{y3}}
\end{bmatrix}
=
\begin{bmatrix}
F_{\text{ext-x}} \\
F_{\text{ext-y}} \\
0 \\
0 \\
0 \\
0 \\
0 \\
0 \\
\end{bmatrix}
\]
This system contains only the unknown displacements. By simplifying the matrix system in this way,
computation is greatly simplified.
Solving the system of equations
To solve for the unknown displacements in the system, the LU decomposition method was utilized. LU decomposition is an efficient numerical technique that factors the global stiffness matrix \([K_r]\) into a lower triangular matrix \([L]\) and an upper triangular matrix \([U]\), such that:
\[
[K_r] = [L][U]
\]
This decomposition allows the system of equations:
\[
[K_r][u_r] = [F_r]
\]
to be solved in two steps:
Once the unknown displacements \([u_r]\) were determined, they were integrated with the known displacements (from boundary conditions) to reconstruct the full displacement vector \([u]\). This vector represents the horizontal and vertical displacements for all nodes in the system.
After obtaining the displacement vector, the unknown reaction forces at constrained nodes were calculated by substituting \([u]\) back into the original stiffness equation:
\[
[F] = [K][u]
\]
This step allowed for the determination of reaction forces at fixed supports.
The use of LU decomposition in this process not only ensured computational efficiency but also provided a structured approach to solving the system of equations, accommodating the modifications made during partitioning and simplification.
In the application, LU decomposition was implemented by the math.js library. An alternative method to solve for the \([u_r]\) matrix involved multiplying the inverse of the reduced stiffness matrix by the force matrix, hovever, due to the computational complexity involved
with inverting such a large matrix, the LU decomposition method was chosen to maintain good preformance.
Finding Element Displacement, Strain, Stress, and Force
After solving for the nodal displacements, the next step is to compute key quantities for each truss element: element displacement, strain, normal stress, and internal force. These calculations are critical for assessing the structural behavior of the truss under applied loads.
1. Element Displacement
The relative displacement between the nodes of each element is computed as:
\[
\delta = u_j - u_i
\]
where \(u_i\) and \(u_j\) are the axial displacements of the initial and final nodes, respectively. This value captures the total deformation along the length of the element.
2. Strain
The strain in each element is calculated using its relative displacement and length:
\[
\varepsilon = \frac{\delta}{L}
\]
where \(L\) is the original length of the element. Strain is a unitless measure of deformation relative to the element’s original length.
3. Normal Stress
The normal stress in each element is determined using Hooke's Law:
\[
\sigma = E \cdot \varepsilon
\]
where \(E\) is the modulus of elasticity of the material. Normal stress is expressed in psi (pounds per square inch) and indicates whether the element is in tension (\(\sigma > 0\)) or compression (\(\sigma < 0\)).
4. Internal Force
The internal axial force in the element is derived using the normal stress and cross-sectional area:
\[
F = \sigma \cdot A
\]
where \(A\) is the cross-sectional area of the element. The force is expressed in pounds-force (lbf) and represents the axial load carried by the element.
These calculations allow for the evaluation of structural performance, identifying elements under significant tension or compression and ensuring that all elements remain within their allowable stress limits.
Conclusion
Summary
This project demonstrated the implementation of the stiffness method for the structural analysis of truss systems using a web-based application. By integrating key engineering concepts such as the adjacency matrix, stiffness matrix, and boundary condition handling, the application efficiently calculated nodal displacements, internal forces, and stresses for a given truss configuration.
The application utilizes JavaScript classes and modular programming to handle data structures representing nodes, elements, and boundary conditions. Through LU decomposition, the system of equations was solved efficiently, and the results were systematically used to compute secondary parameters such as element displacements, strains, stresses, and internal forces. The visual output, combined with tabular results, provides a comprehensive understanding of the truss's structural behavior.
The accuracy and scalability of the application make it a versatile tool for structural analysis. It is particularly valuable for educational purposes, helping students and engineers visualize and understand the stiffness method and its application to real-world structures.
Next Steps