ENGR 492 Course Project # 2

Two-Dimensional Static Truss Analysis

Omar Noury
#73735524

Taymour Metwalli
#15770787


Open Project

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:

  • Diagonal entries represent the net stiffness contributions of all elements connected to a specific node.
  • Off-diagonal entries represent the coupling stiffness between two nodes connected by an element.



\[ 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

The 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)



Within the ELEMENT class, calculations for various variables are computed and saved, namely;

  • Length of the element: \[ L = \sqrt{(x_j - x_i)^2 + (y_j - y_i)^2} \]
  • Directional cosines: \[ l = \frac{x_j - x_i}{L}, \quad m = \frac{y_j - y_i}{L} \]
  • Stiffness matrix coefficients:
    These coefficients are derived to account for the element's stiffness in the global coordinate system and to reduce computational complexity later on: \[ 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 application of these coefficients is illustrated in The Stiffness Matrix section below


Fixture and Force Classes

The 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.

Initial Values

Nodes, elements, materials, and boundary conditions are initialized into arrays where;

  • Nodes: Each node is defined with its \(x\) and \(y\) coordinates, such as \( (120, 0) \).
  • Elements: Each element connects two nodes and is initialized with its material and cross-sectional area.
  • Materials: Materials include modulus of elasticity, \(E\), and a color for visualization, with predefined values for steel and aluminum.

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} \]

  • Diagonal terms are computed by summing up the contributions of all elements connected to a node

  • Off-diagonal terms account for the interaction between connected nodes.

To illustrate : Node number two is connected to three elements; 1, 3, & 4. The coefficients of those elements, \(a_i, b_i, c_i\) are summed at the diagonal entry for node two, rows 3 & 4 and columns 3 & 4. Since we know that element 1 connects node 2 to node 1, we subtract element 1's coefficients from rows 1 & 2 at column 3 & 4 (the off-diagonal entries for node 1 that are associated with the diagonal entry for node 2).

Note that this matrix will always be symmetric about the diagonal. We can then simply subtract element 1's coefficints from the summetric indices, columns 1 & 2 at row 3 & 4. This process is repeated for the other elements connected from node two to other elements, moving down the diagonal node by node.

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} \]



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 i = 0 to n-1:


// Loop through each element at the current row of the adjacency matrix

FOR each connected element in AdjMatrix[i]:

IF element is connected (elConnected != 0):


// Update diagonal entries of the stiffness matrix

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:

  • Unconstrained Nodes: A node with no support and no external forces is free to move in both horizontal and vertical directions. The Displacments reamin unknown while the reaction forces at such nodes both equal zero. \[ u = u\ , \quad v = v \] \[ F_{x} = 0\ , \quad F_{y} = 0 \]
  • Fixed Support: A node with a fixed support has zero displacement in both horizontal (\(u\)) and vertical (\(v\)) directions. The reaction forces at such nodes remain unknown. \[ u = 0\ , \quad v = 0 \] \[ F_{x} = F_{x}\ , \quad F_{y} = F_{y} \]
  • Roller Support: A node with a roller support is typically constrained in one direction while free to move in the other direction only if the roller surface is normal to one of the global coordinate axes. For such nodes, displacement in the direction normal to the roller surface is zero while the other remains as unknown.

    For a vertical roller (rolls along the y axis): \[ u = 0, \quad v = v \] \[ F_{x} = F_{x}\ , \quad F_{y} = 0 \]

    For a Horizontal roller (rolls along the x axis): \[ u = u, \quad v = 0 \] \[ F_{x} = 0\ , \quad F_{y} = F_{y} \] In the case that the roller is inclined, the constraints become more complex, requiring Multiple Point Constraints to accuratley represent the systems behaviour.

    Multiple Point Constraints (MPCs)

    In truss analysis, Multiple Point Constraints (MPCs) are used to model conditions where the motion of a node is constrained along a specific inclined direction, rather than purely along the global Cartesian axes. These constraints are essential for accurately capturing the structural behavior under external loads.

    For an inclined roller, the constraint direction is defined by its orientation angle \(\theta\). Instead of directly setting the horizontal (\(u\)) or vertical (\(v\)) displacement to zero, the constraint is applied to a combined motion along the inclined axis. This is expressed mathematically as:

    \[ u \cdot \cos\theta + v \cdot \sin\theta = 0 \]
    Here:
    • \(u\): The horizontal displacement of the constrained node.
    • \(v\): The vertical displacement of the constrained node.
    • \(\theta\): The angle of inclination of the roller relative to the global X-axis.

    Similarly, the reaction forces at such constraints are expressed as:

    \[ -F_{x} \cdot \sin\theta + F_{y} \cdot \cos\theta = 0 \]

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:

  • Adding the constraint equations:
    \[ u \cdot \cos\theta + v \cdot \sin\theta = 0 \quad \ \ \ \ \& \quad -F_{x} \cdot \sin\theta + F_{y} \cdot \cos\theta = 0 \] Into the stiffness matrix directly, ensuring that the solution satisfies the inclined motion restriction.

Implementation

In the application, the stiffness matrix, displacement vector, and force vector are modified to incorporate the constraints by introducing new rows/columns.

For the default configuration of the truss, with a inclined roller at some angle \(\theta\) at the node 3:

  • The \([K]\) matrix becomes
    \[ \begin{bmatrix} &a_{1+2} & b_{1+2} & -a_1 & -b_1 & -a_2 & -b_2 & 0 & 0 &╎& 0 & 0& \\ &b_{1+2} & c_{1+2} & -b_1 & -c_1 & -b_2 & -c_2 & 0 & 0 &╎& 0 & 0& \\ &-a_1 & -b_1 & a_{1+3+4} & b_{1+3+4} & -a_3 & -b_3 & -a_4 & -b_4 &╎& 0 & 0& \\ &-b_1 & -c_1 & b_{1+3+4} & c_{1+3+4} & -b_3 & -c_3 & -b_4 & -c_4 &╎& 0 & 0& \\ &-a_2 & -b_2 & -a_3 & -b_3 & a_{2+3+5} & b_{2+3+5} & -a_5 & -b_5 &╎& -1 & 0& \\ &-b_2 & -c_2 & -b_3 & -c_3 & b_{2+3+5} & c_{2+3+5} & -b_5 & -c_5 &╎& 0 & -1& \\ &0 & 0 & -a_4 & -b_4 & -a_5 & -b_5 & a_{4+5} & b_{4+5} &╎& 0 & 0& \\ &0 & 0 & -b_4 & -c_4 & -b_5 & -c_5 & b_{4+5} & c_{4+5} &╎& 0 & 0 & \\ &╌╌ &╌╌ &╌╌ &╌╌ &╌╌ &╌╌ &╌╌ &╌╌ &✛& & & \\ &0 &0 &0 &0 & \cos\theta & \sin\theta &0 &0& & 0 & 0& \\ &0 &0 &0 &0 &0 &0 &0 &0 & & -\sin\theta & \cos\theta & \\ \end{bmatrix} \]
    • The Two additional columns correspond to \(F_{x3}\) & \(F_{y3}\) respectively
    • The unknown forces in the force vector, \(F_{x3}\) & \(F_{y3}\) , are moved to the stiffness matrix (thus set to zero in the force vector)
    • Since the matrix already has columns corresponding to \(u_{3}\) & \(v_{3}\), the first constraint equation can be added directly as a new row
    • The second constraint equation can then be added as another row where the entries correspond to the two new columns

  • 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}} \\ u_{\text{4}} \\ v_{\text{4}} \\ \end{bmatrix} => \begin{bmatrix} u_{\text{1}} \\ v_{\text{1}} \\ u_{\text{2}} \\ v_{\text{2}} \\ u_{\text{3}} \\ v_{\text{3}} \\ u_{\text{4}} \\ v_{\text{4}} \\ --\\ F_{\text{x3}} \\ F_{\text{y3}} \end{bmatrix} \quad \quad [F]= \begin{bmatrix} F_{\text{x1}} \\ F_{\text{y1}} \\ F_{\text{x2}} \\ F_{\text{y2}} \\ F_{\text{x3}} \\ F_{\text{y3}} \\ F_{\text{x4}} \\ F_{\text{y4}} \end{bmatrix} => \begin{bmatrix} F_{\text{x1}} \\ F_{\text{y1}} \\ F_{\text{x2}} \\ F_{\text{y2}} \\ 0 \\ 0 \\ F_{\text{x4}} \\ F_{\text{y4}} \\ --\\ 0 \\ 0 \\ \end{bmatrix} \]
    • Two additional rows in the displacement vector, \(F_{x3}\) & \(F_{y3}\), respectively
    • The unknown forces in the force vector, \(F_{x3}\) & \(F_{y3}\) , are moved to the stiffness matrix (thus set to zero in the force vector)
    • Two additional \(0\) rows in the Force vector correspond to the RHS of the constraint equations


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:

  • Node 1 is unconstrained but it has an extrenal force acting on it with magnitudes; \(F_{\text{ext-x}}\) & \(F_{\text{ext-y}}\) in the x and y axis.
  • Node 2 is unconstrained and has no extrenal forces acting on it.
  • Node 4 is fixed, it is has a net displacement of zero.

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:

  • Identifying rows and columns in the stiffness matrix \([K]\) associated with constrained degrees of freedom (\(u_i = 0, v_i = 0\)).
  • Removing these rows and columns from \([K]\), resulting in a reduced stiffness matrix \([K_r]\).
  • Removing the corresponding entries in the displacement matrix \([u]\) and force matrix \([F]\), yielding reduced matrices \([u_r]\) and \([F_r]\).


The partioning process involves:

  • Identifying rows and columns in the stiffness matrix \([K]\) associated unknown Forces (\(F_x , F_y\)).
  • Removing these rows and columns from \([K]\) and holding onto them, resulting in a reduced stiffness matrix \([K_r]\).
  • Removing the corresponding entries in the displacement matrix \([u]\) and force matrix \([F]\), yielding reduced matrices \([u_r]\) and \([F_r]\).
  • After the reduced system is solved for displacements, the equations removed from this matrix are then solved for the unknown forces

For example: In the default truss configuration, Node 4 has a fixed constrained (\(u_4 = 0 , v_4 = 0\)):
  • The rows and columns corresponding to \(u_4\) & \(v_4\) are removed from \([K]\).
  • The entries for \(u_4\) & \(v_4\) are removed from \([u]\) and \([F]\).


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:

  • Forward Substitution: Solve \([L][z] = [F_r]\) for the intermediate vector \([z]\).
  • Backward Substitution: Solve \([U][u_r] = [z]\) for the reduced displacement vector \([u_r]\).

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

  • Implement the solution for external forces applied at inclined rollers
  • Expand the scope of the application to model and solve three dimensional truss systems
  • Update the materials array to provide a variety of materials with different properties
    • Note: The application currently handls adding new materials
  • Improve the GUI by adding an interactive way to add nodes and elements
  • Use what I learnt while working on this project to make a real-time solver for dynamic problems using Lagrange's method and the RK-4 numerical solution
  • live laugh and love