1-D Finite Elements: Stiffness Assembly

Build a complete finite element solver for an axial bar: linear shape functions, element stiffness matrix and load vector, global assembly, applying boundary conditions, solving, and post-processing stresses and reactions. Understand why linear elements give exact nodal values in 1-D, how convergence works, and how the same steps scale to 2-D/3-D FEM software.

Commercial FEM packages (ANSYS, Abaqus, COMSOL) hide millions of equations, but every one follows the same five steps: discretise, build element matrices, assemble, apply boundary conditions, solve and post-process. Doing it once by hand for a bar demystifies the whole field.

An axial bar is the simplest case: each 2-node element acts like a spring of stiffness EA/h, and assembling elements is like connecting springs in series.

An analogy

Assembling a stiffness matrix is like building with LEGO: each element brick has its own small matrix, and the global structure is formed by snapping bricks together at shared nodes — where their stiffnesses add.

The five FEM steps

Every FE analysis, from a bar to a jet engine, follows:

Where kₑ comes from

Substitute u = N₁u₁ + N₂u₂ into the weak form: kᵢⱼ = ∫EA Nᵢ′Nⱼ′ dx. With N₁′ = −1/h and N₂′ = 1/h, this gives (EA/h)[[1, −1], [−1, 1]] — exactly a spring of stiffness EA/h. The load vector ∫qNᵢ dx splits a uniform load equally between the two nodes.

Properties of K

K is symmetric, banded (each node couples only to neighbours) and singular before supports are applied — the rigid-body motion has zero energy. Applying u(0) = 0 removes that mode and makes K positive definite, so efficient Cholesky or sparse solvers can be used.

Scaling up

In 2-D/3-D, elements are triangles, quads, tets or hexes; shape functions are defined on a reference element and mapped with the Jacobian (isoparametric formulation); integrals are done by Gauss quadrature; K has millions of rows but is extremely sparse. Mesh convergence studies — refining until results change by less than a few percent — are mandatory in professional practice.

Formulas

Worked example: Assembling two elements

Given: Two equal elements, stiffness k each

Find: Global K.

Answer: K = k [[1, −1, 0], [−1, 2, −1], [0, −1, 1]]

Worked example: Stepped bar

Given: E = 200 GPa; A₁ = 200 mm², A₂ = 100 mm², each 0.5 m; P = 20 kN at tip, fixed at root

Find: Displacements and stresses.

Answer: u = [0, 0.25, 0.75] mm; σ = 100, 200 MPa

Worked example: Reaction

Given: Bar with UDL q = 5 kN/m over 2 m plus P = 10 kN

Find: Support reaction.

Answer: R = −20 kN (acting opposite to the loads)

Complete 1-D bar FEM solver

import numpy as np

# Axial bar: -EA u'' = q on [0, L], u(0) = 0, EA u'(L) = P
EA, L, q, P = 2.0e7, 2.0, 5.0e3, 1.0e4        # N, m, N/m, N
for ne in (1, 2, 4):
    n = ne + 1
    h = L / ne
    K = np.zeros((n, n)); F = np.zeros(n)
    ke = EA / h * np.array([[1, -1], [-1, 1]])  # element stiffness
    fe = q * h / 2 * np.array([1, 1])           # consistent load vector
    for e in range(ne):                          # assembly
        idx = [e, e + 1]
        K[np.ix_(idx, idx)] += ke
        F[idx] += fe
    F[-1] += P                                   # point load at the tip
    u = np.zeros(n)
    u[1:] = np.linalg.solve(K[1:, 1:], F[1:])    # apply u(0) = 0
    print(f"{ne} element(s): tip u = {u[-1]*1e3:.4f} mm, mid u = {np.interp(L/2, np.linspace(0, L, n), u)*1e3:.4f} mm")
x = L / 2
print(f"exact:          tip u = {(q*L**2/2 + P*L)/EA*1e3:.4f} mm, mid u = {((q*L*x - q*x**2/2) + P*x)/EA*1e3:.4f} mm")
# 1 element(s): tip u = 1.5000 mm, mid u = 0.7500 mm
# 2 element(s): tip u = 1.5000 mm, mid u = 0.8750 mm
# 4 element(s): tip u = 1.5000 mm, mid u = 0.8750 mm
# exact:          tip u = 1.5000 mm, mid u = 0.8750 mm

Nodal displacements are exact for any mesh (a special 1-D property), but between nodes the linear interpolation is wrong until a node sits there — with one element the midpoint is 14% low. Stresses (constant per element) converge more slowly than displacements.

Common mistakes

Applications

Key takeaways

Going further