2D Truss System Solver

2 Dimensional Truss Solver Use html5 supporting browser

The larger of total system width and height[mm]

x[mm] y[mm] x constraint y constraint

x-Force[N] y-Force[N]

Young's modulus[MPa] Area[mm2]

First Node Second Node

Bar List

Direct Stiffness Method for 2D Trusses

  • Step 1: Definition of the joint positions and the truss members between the joints. This includes the cross section area and Young’s modulus for each truss member as well as the boundary conditions for each joint. In the process of defining the joint positions, also for each joint a code vector is defined. The code vector of each joint consists of two numbers corresponding to the two possible directions of displacement that the joint can undergo. The assignment of code numbers to the joints(also called “nodes” in the rest of this text) is such that the first node has the code vector \((0,1)\), the second node has the code vector \((2,3)\) and so on. The joint positions and these code vectors are packed together in a data structure called “node”. Later on, while the truss members are being defined, the geometry and material properties of each truss member are packed together in a data structure called “bar”. The “bar” data structure also contains a code vector which is established by joining the code vectors of the two nodes belonging to the particular truss member.
  • Step 2: Definition of the local member stiffness matrices \(\mathbf{k^{'}}\). These matrices are defined with respect to the local coordinate system \((\)\((x^{'},y^{'})\) in Figure 1 \()\) of each member.
\[\begin{split}\mathbf{k^{'}} = \begin{bmatrix} \displaystyle\frac{EA}{L} & -\displaystyle\frac{EA}{L} \\ -\displaystyle\frac{EA}{L} & \displaystyle\frac{EA}{L} \end{bmatrix}\end{split}\]
  • Step 3: Definition of the coordinate transformation matrices \(\mathbf{t}\) for each truss member. Using these matrices the local member stiffness matrices, local displacements(\(u_1^{'}, u_2^{'}\)) and forces(\(q_1^{'}, q_2^{'}\)) at each end of the truss members are transformed into the global coordinate system. These matrices are populated by the cosines and sines of the angle between the member axis and the global x-coordinate system (usually a horizontal axis).
_images/LocalGlobalDispsForces.JPG

Figure 1: Member end forces and displacements in local and global coordinates

\[\begin{split}\mathbf{t} = \begin{bmatrix} \cos{\theta_x} & \sin{\theta_x} & 0 & 0 \\ 0 & 0 & \cos{\theta_x} & \sin{\theta_x} \end{bmatrix}\end{split}\]

In Figure 1 \(u_{1x},u_{1y}, u_{2x}, u_{2y}\) and \(q_{1x},q_{1y}, q_{2x}, q_{2y}\) denote the global end displacements and end forces respectively.The conversion of the forces, displacements and the stiffness matrices between the local and global coordinate systems can be done as follows:

\[\mathbf{q} = \mathbf{t^T}\mathbf{q^{'}}, \quad \mathbf{u^{'}} = \mathbf{t}\mathbf{u}, \quad \mathbf{q}=\mathbf{k}\mathbf{u} \Rightarrow \mathbf{k}=\mathbf{t^T}\mathbf{k^{'}}\mathbf{t}\]
  • Step 5: Assemblage of the global stiffness matrix for the entire system from the global stiffness matrices of the bars. This operation uses the code vectors of the truss members. As mentioned in step 1, each 2D truss member is assigned a code vector consisting of 4 numbers. As an example if a bar is located between the first and third (in the order of definition) nodes of the system, then the code vector of this bar would be \((0, 1, 4, 5)\). The data structure “bar” contains a vector called “codeVec” where the numbers \((0, 1, 4, 5)\) would be stored for this particular bar. Let’s assume as an example that the total number of nodes in the system is 3. Then the total number of possible joint displacements (in other words the total degrees of freedom of the system) would be 6 and the global system stiffness matrix would be a 6X6 matrix. Let’s call this matrix \(\mathbf{K}\). In the process of programming this method, \(\mathbf{K}\) is initialized as a zero matrix. Afterwards the entries of the member global stiffness matrices are added to the proper parts of \(\mathbf{K}\). In case of the example bar the following operations would be necessary: \(\mathbf{K}[0][0]+=\mathbf{k}[0][0]\), \(\mathbf{K}[0][1]+=\mathbf{k}[0][1]\), \(\mathbf{K}[0][4]+=\mathbf{k}[0][2]\), \(\mathbf{K}[0][5]+=\mathbf{k}[0][3]\), \(\mathbf{K}[1][4]+=\mathbf{k}[1][2]\), \(\mathbf{K}[1][5]+=\mathbf{k}[1][3]\) and so on. The following pseudocode would do this operation for all bars in the system and assemble the system global stiffness matrix

    for(i =0;i<total number of bars;i++)
      for(j=0;j<4;j++)
        for(m=0;m<4;m++)
          index1=bars[i].codeVec[j]
          index2=bars[i].codeVec[m]
          K[index1][index2]+=bars[i].k[j][m]
        next
      next
    next
    
  • Step 6: Partitioning of the global stiffness matrix \(\mathbf{K}\), the global displacement vector \(\mathbf{U}\) and the global force vector \(\mathbf{Q}\). \(\mathbf{Q}\) and \(\mathbf{U}\) are related to each other as follows:

    \[\mathbf{Q} = \mathbf{K}\mathbf{U}\]

    In the above equation both \(\mathbf{Q}\) and \(\mathbf{U}\) have known and unknown parts by the definition of the system such that where \(\mathbf{U}\) is known, \(\mathbf{Q}\) is unknown and vice versa. In order to come up with an equation system from which the unknown parts of \(\mathbf{U}\) can be solved, a sub global stiffness matrix \(\mathbf{K_s}\) as well as sub load and displacement vectors \(\mathbf{Q_s}\) and \(\mathbf{U_s}\) have to be defined. For this purpose the code values in the entire system corresponding to the degrees of freedom where the displacement is unknown but the force is known, are packed into a vector called “subIndices”. Also, the known forces at these degrees of freedom are packed into the vector \(\mathbf{Q_s}\). The next step is to initialize \(\mathbf{K_s}\) as a zero matrix and then to populate it using the following pseudocode.

    for(i=0;i<length of subIndices;i++)
      for(j=0;j<length of subIndices;j++)
        Ks[i][j]=K[subIndices[i]][subIndices[j]]
      next
    next
    
  • Step 7: The unknown displacements \(\mathbf{U_s}\) are solved from the equation system \(\mathbf{Q_s}=\mathbf{K_s}\mathbf{U_s}\). Afterwards the values in \(\mathbf{U_s}\) are added to the initially zero vector \(\mathbf{U}\) using the following pseudocode.

    for(i=0;i<length of subIndices;i++)
      U[subIndices[i]]=Us[i]
    next
    
  • Step 8: Computation of the force vector with \(\mathbf{Q}=\mathbf{K}\mathbf{U}\).

  • Step 9: Using \(\mathbf{Q}\) and \(\mathbf{U}\), global force and displacement vectors \(\mathbf{q}\) and \(\mathbf{u}\) are assigned to each truss member as follows.

    for(i=0;i<total number of bars;i++)
      for(j=0;j<4;j++)
        index=bars[i].codeVec[j]
        bars[i].q[j]=Q[index]
        bars[i].u[j]=U[index]
      next
    next
    
  • Step 10: For each truss member, the global load and displacement vectors are transformed into the local coordinate system in order to compute the axial forces and displacements of each truss member. The equations \(\mathbf{u^{'}}=\mathbf{t}\mathbf{u}\) and \(\mathbf{q^{'}}=\mathbf{k^{'}}\mathbf{u^{'}}\) are used. As shown in Figure 1 the local force \(\mathbf{q_2^{'}}\) is defined as a tensile force. In Figure 1, \(\mathbf{q_1^{'}}\) and \(\mathbf{q_2^{'}}\) correspond to \(\mathbf{q^{'}[0]}\) and \(\mathbf{q^{'}[1]}\) respectively. Therefore a positive value of \(\mathbf{q^{'}[1]}\) indicates tension in the member whereas a negative value indicates compression.

References

[1] Hibbeler R.C., Structural Analysis, 8th edition, ISBN:9780132570534