Trusses: A Gable Roof Frame (1D Bar FEA)
using Rasmah
using LinearAlgebraOverview
A truss is a structure made of pin-jointed bars that carry only axial load — no bending. Roof frames, crane jibs, bridges, and radio masts are trusses because they use material at maximum efficiency: every bar is in pure tension or compression. The analysis is the oldest finite-element method there is: each bar is a 1-D element of axial stiffness EA/L, the bars are assembled into a global stiffness, and K u = f is solved for the joint displacements. From those, the axial force in every member follows.
This tutorial builds a gable roof frame — the classic triangle: two rafters and a tie beam, spanning 8 m with a 1.5 m rise, carrying a 10 kN snow load at the apex. The member forces of this frame can be found by hand with the method of joints, which is exactly how we verify the finite-element answer.
The method of joints
At the apex C the two rafters share the load. Each rafter makes the angle θ with the horizontal, so vertical equilibrium gives
\[ N_{rafter} = -\frac{P}{2\sin\theta}, \]
and horizontal equilibrium at the roller support gives the tie tension N_tie = P/(2 tan θ). With P = 10 kN, a span of 8 m and a rise of 1.5 m, sin θ = 1.5/√(4² + 1.5²) and the numbers come out as below.
Building the frame
Three joints — the two supports A, B and the apex C — and three members. One support is pinned, the other rolls horizontally, so the frame is statically determinate and the tie carries the rafter thrust:
span, rise = 8.0, 1.5
nodes = [0.0 span span / 2; # A, B, C
0.0 0.0 rise;
0.0 0.0 0.0]
struts = [1 3 1; # A-C, C-B, A-B
3 2 2]
t = Truss(nodes, struts)
println("nodes = ", num_nodes(t), ", struts = ", num_struts(t))
println("total member length = ", round(ustrip(total_length(t)); digits = 2), " m")nodes = 3, struts = 3
total member length = 16.54 m
Stiffness and solve
Each bar contributes EA/L · [n̂n̂ᵀ −n̂n̂ᵀ; −n̂n̂ᵀ n̂n̂ᵀ] at its two joints. The rafters are a pair of L 70 × 70 × 6 angles (A ≈ 8.13 cm² each) in S235 steel. Pin A, let B roll (restrain only its y), fix the out-of-plane z dofs, and hang 10 kN from the apex:
E, A = 2.10e11, 8.13e-4 # steel, 8.13 cm² per member
K = truss_stiffness(t, steel, A)
println("K is symmetric: ", K ≈ K')
println("K size: ", size(K))
fixed = [1, 2, 3, 5, 6, 9] # A pinned, B rolls, z dofs out
loads = zeros(9); loads[8] = -10000.0 # −10 kN at the apex C
u = solve_truss(t, steel, A, fixed, loads)
println("apex displacement (mm): ", round.(u[7:9] * 1e3; digits = 2))K is symmetric: true
K size: (9, 9)
apex displacement (mm): [0.33, -1.94, 0.0]
Member forces vs. the method of joints
N = truss_axial_forces(t, steel, A, u)
θ = atan(rise, span / 2)
println("member FEM (N) hand (N)")
println("rafters ", round(N[1]; digits = 0), " ", round(-10000 / (2 * sin(θ)); digits = 0))
println("tie ", round(N[3]; digits = 0), " ", round(10000 / (2 * tan(θ)); digits = 0))member FEM (N) hand (N)
rafters -14240.0 -14240.0
tie 13333.0 13333.0
The finite-element member forces match the method-of-joints values to the last digit — the rafters carry 14.2 kN in compression and the tie 13.3 kN in tension (negative = compression). Notice how the tie tension exceeds the applied load: the shallow θ amplifies the horizontal thrust, which is why gable frames need a sturdy tie or buttresses.
A grid truss (and why it needs bracing)
grid_truss(nx, ny, nz, spacing) builds a rectangular grid with struts only along the grid edges — it is a mechanism without diagonals (the reduced stiffness is singular). Add diagonal bracing (or a full ground structure) to make it stable before solving:
g = grid_truss(3, 2, 1, 1.0)
println("grid truss: nodes = ", num_nodes(g), ", struts = ", num_struts(g))grid truss: nodes = 6, struts = 7
Notes
truss_stiffness,solve_truss,truss_axial_forces,truss_complianceare the FEA primitives; the trussTrussstruct is also used by the robotics assembly planner (assemble_sequence,rrt_path,plan_assembly).solve_trussreduces the system with a Cholesky solve, so the supported structure must be stable (no rigid-body modes or mechanisms).
Next steps
- Beams — the bending members a truss deliberately avoids.
- Topology optimization — the ground-structure truss problem behind
solve_truss’s design sibling. - Assembly mates — putting pinned parts like these together.
