Structural elements
Overview
The FEM chapters so far filled a solid with tetrahedra. But many structures are slender — a bridge truss, a machine frame, a thin panel — and a solid mesh wastes thousands of elements on a shape whose behaviour is really one- or two-dimensional. Structural elements capture that behaviour directly: a truss is a set of pin-jointed bars, a beam is a line that also bends, and a plate/shell is a surface that bends out of its plane.
Each element is its own tiny theory of a slender member, so a handful of bars or a single surface mesh replaces an enormous solid mesh — with the same physics and far fewer degrees of freedom.
Trusses
A truss is a set of pin-jointed bars: each member carries only an axial force $N = (EA/L)\,\hat{\mathbf{n}}\cdot\Delta\mathbf{u}$ (tension positive), with no bending. That one force per bar is enough to model bridges, towers, and the ground structures behind truss topology optimization.
Rasmah.Truss — Type
TrussA node-and-strut truss: nodes (3×N coordinates) and strut connectivity (2×M, 1-based).
Fields
nodes:3×Nmatrix of node coordinates.struts:2×Mmatrix of strut endpoint indices.
Rasmah.grid_truss — Function
grid_truss(nx, ny, nz, spacing) -> TrussConstruct a rectangular grid truss with nx×ny×nz nodes spaced spacing apart, with struts along the grid edges.
Rasmah.truss_stiffness — Function
truss_stiffness(t::Truss, material, A)The global (3N × 3N) truss stiffness matrix: each strut contributes EA/L · [ n̂n̂ᵀ −n̂n̂ᵀ; −n̂n̂ᵀ n̂n̂ᵀ ] in its two nodes' displacement dofs, where n̂ is the strut's unit direction, E the material's Young's modulus, and A the (geometric) cross-sectional area.
Rasmah.solve_truss — Function
solve_truss(t::Truss, material, A, fixed, loads)Solve K u = f for the truss displacement (reduced for the fixed dofs).
Rasmah.truss_axial_forces — Function
truss_axial_forces(t::Truss, material, A, u)The axial force N = (EA/L) n̂·Δu in each strut for a displacement field u (positive = tension).
Rasmah.truss_compliance — Function
truss_compliance(t, material, A, fixed, loads) -> RealThe compliance fᵀu of a truss: the dot product of the loads with the solved displacement field (see solve_truss).
A single bar is the cleanest check. Fix one end, let the other slide along the bar, pull it, and the displacement must be $\delta = FL/(EA)$:
bar = Truss([0.0 1.0; 0.0 0.0; 0.0 0.0], reshape([1, 2], 2, 1))
u = solve_truss(bar, Material(youngs_modulus=200e9, poisson_ratio=0.3), 1e-4, [1, 2, 3, 5, 6], [0.0, 0.0, 0.0, 1e3, 0.0, 0.0])
u[4]4.9999999999999996e-5With $F = 10^{3}\,\text{N}$, $L = 1\,\text{m}$, $E = 2\times10^{11}\,\text{Pa}$, $A = 10^{-4}\,\text{m}^{2}$, the bar stretches $FL/(EA) = 5\times10^{-5}\,\text{m}$ exactly.
Beams and frames
A beam adds bending: the same member now resists transverse load through a flexural rigidity $EI$, on top of the axial $EA$. A frame is a network of beams connected rigidly at their joints:
Rasmah.BeamFrame — Type
BeamFrame(nodes, elements)A node-and-member frame: nodes is a d×N matrix of node coordinates (d ∈ {2,3}) and elements a 2×M matrix of 1-based node index pairs. Unlike a Truss, members carry bending (and, in 3D, torsional) stiffness.
Rasmah.beam_stiffness — Function
beam_stiffness(frame, E, A, I; model=:euler_bernoulli, ν=0.3, κ=5/6)Global stiffness matrix of a 2D BeamFrame. A and I are the (uniform, or per-member) cross-sectional area and second moment of area; model ∈ :euler_bernoulli (thin, shear-rigid) / :timoshenko (shear-deformable, with Poisson ratio ν and shear correction factor κ).
Rasmah.beam_stiffness_3d — Function
beam_stiffness_3d(frame, E, A, Iy, Iz, J; ν=0.3)Global stiffness matrix of a 3D BeamFrame (Euler–Bernoulli space frame): axial + torsion + two-plane bending. A cross-section area, Iy/Iz the two second moments of area, J the polar (torsional) moment of area; each may be a scalar or a per-member vector. G = E/(2(1+ν)).
Rasmah.solve_beam — Function
solve_beam(frame, E, A, I, fixed, loads; model=:euler_bernoulli, ν=0.3, κ=5/6)Solve K u = f for a 2D beam frame (reduced for the fixed dofs).
Rasmah.solve_beam_3d — Function
solve_beam_3d(frame, E, A, Iy, Iz, J, fixed, loads; ν=0.3)Solve K u = f for a 3D beam frame (reduced for the fixed dofs).
model = :euler_bernoulli is the classical thin-beam theory (plane sections stay plane and normal); model = :timoshenko adds shear deformation for short or thick members. The 3D form carries axial, torsion, and two-plane bending.
Plates and shells
Where a beam is a line that bends, a plate is a surface that bends. A thin plate follows Kirchhoff–Love theory (a single deflection $w$ per node); a Mindlin plate adds the rotations $(\theta_x, \theta_y)$ as independent unknowns so shear is not neglected, and a flat shell adds in-plane membrane action on top of the plate:
Rasmah.PlateBending — Type
PlateBending <: AbstractPhysicsSimply-supported thin-plate (Kirchhoff–Love) bending. The biharmonic problem D ∇⁴w = q is split into two Poisson solves for the transverse deflection w.
Rasmah.solve_plate — Function
solve_plate(m::TriangleMesh, D, fixed, source)Transverse deflection w of a simply-supported thin plate of flexural rigidity D under a nodal source source = ∫ q N (see pressure_load). Solved by the exact biharmonic splitting into two −Δ Poisson solves.
Rasmah.pressure_load — Function
pressure_load(m::TriangleMesh, q)The consistent nodal source ∫ q Nᵢ of a uniform transverse pressure q (each element's qA distributed over its three vertices).
Rasmah.MindlinPlate — Type
MindlinPlate <: AbstractPhysicsPhysics driver for Mindlin–Reissner (thick) plate bending: rotations are independent C0 fields with transverse shear handled by selective reduced integration.
Rasmah.solve_mindlin_plate — Function
solve_mindlin_plate(m, E, ν, t, fixed, loads; κ=5/6)Solve the Mindlin–Reissner plate bending problem K u = f (reduced for the fixed dofs). loads is a nodal transverse-load vector indexed like the w dofs; fixed dofs are the constrained (w, θx, θy) dofs.
Rasmah.FlatShell — Type
FlatShell <: AbstractPhysicsPhysics driver for the flat triangular facet shell, combining the constant-strain membrane with the Mindlin plate (5 dofs per node: u, v, w, θx, θy).
Rasmah.solve_flat_shell — Function
solve_flat_shell(m, E, ν, t, fixed, loads; κ=5/6)Solve the flat-shell problem K u = f (reduced for the fixed dofs).
The simply-supported square plate under uniform pressure has a closed-form Navier-series solution, so it is the natural check. With $E = 2\times10^{11}$, $\nu = 0.29$, thickness $t = 0.01$, and pressure $q = 10^{3}$, the centre deflection is
m = triangulate_box(1.0, 1.0, 12, 12)
boundary = Int[]
for i in 1:size(m.vertices, 2)
(m.vertices[1, i] ≈ 0.0 || m.vertices[1, i] ≈ 1.0 ||
m.vertices[2, i] ≈ 0.0 || m.vertices[2, i] ≈ 1.0) && push!(boundary, i)
end
w = solve(PlateBending(), m, steel, 0.01; fixed=boundary, pressure=1e3)
round(maximum(abs.(ustrip(w))); digits=6)0.000218The Navier series gives $w_{\max} = 2.23\times10^{-4}\,\text{m}$; the $12\times12$ mesh recovers $2.18\times10^{-4}$ — the two-Poisson-solve biharmonic split agreeing with the analytic answer to within the discretization error.
Next steps
Structural elements are the slender-member counterpart of the solid Finite element method, and the truss kernel feeds straight into ground-structure Topology optimization. For running a structural solve through the same one-line solve(Physics(), …) interface, see Solving with physics.
