Weak Form, Variational Methods & Galerkin
The finite element method rests on rewriting a differential equation in its weak (integral) form and seeking the best approximation within a finite set of trial functions. Learn strong vs weak form, integration by parts, essential vs natural boundary conditions, the Rayleigh–Ritz energy method, the Galerkin method, and why the approximation is optimal — with a SymPy Galerkin solution.
The strong form −u″ = f demands u be twice differentiable everywhere. Multiply by a test function v and integrate by parts and you get ∫u′v′ dx = ∫fv dx — only first derivatives needed. This 'weak form' accepts simpler, piecewise functions, which is exactly what makes finite elements possible.
Galerkin's idea: choose u from a small family of trial functions and require the weak form to hold for every test function in the same family. The result is a matrix equation Kc = F — the heart of every FEM program.
An analogy
Instead of demanding a solution satisfy the equation at every point (impossible for simple functions), the weak form asks it to be right 'on average' when tested against a set of weightings — like checking a bridge with a set of load tests rather than every possible load.
Why weaken the equation?
Real structures have corners, material jumps and point loads where second derivatives do not exist. The weak form needs only first derivatives (square-integrable), so piecewise-linear 'tent' functions — continuous but with kinks — become valid approximations.
Essential vs natural boundary conditions
Essential (Dirichlet) conditions prescribe u — e.g. a fixed support u(0) = 0. They must be built into the trial functions, and test functions vanish there. Natural (Neumann) conditions prescribe EA u′ — e.g. an end force P. They appear automatically in the boundary term from integration by parts and simply add to the load vector.
Ritz and Galerkin
For elastic problems, the true displacement minimises total potential energy Π. Rayleigh–Ritz substitutes trial functions into Π and sets ∂Π/∂cᵢ = 0. For symmetric problems this gives exactly the Galerkin equations. Galerkin also works where no energy functional exists (e.g. some flow problems).
Ritz with a single sine for a simply supported beam under UDL gives a mid-span deflection only 0.4% above the exact 5qL⁴/384EI — try it below.
Optimality and convergence
Galerkin orthogonality means the error is orthogonal to the trial space in the energy inner product, so u_h is the best possible approximation in the energy norm (Céa's lemma). Displacement-based FE solutions therefore converge from the stiff side — computed deflections are lower bounds that increase with mesh refinement. Error in energy norm decreases as O(hᵖ) for elements of degree p.
Formulas
- Strong form:
−(EA u′)′ = f on (0, L), plus BCs - Weak form:
∫₀ᴸ EA u′ v′ dx = ∫₀ᴸ f v dx + [EA u′ v]₀ᴸ for all admissible v - Galerkin approximation:
u ≈ Σ cⱼ φⱼ, v = φᵢ → Σⱼ Kᵢⱼ cⱼ = Fᵢ - Matrix entries:
Kᵢⱼ = ∫ EA φᵢ′ φⱼ′ dx, Fᵢ = ∫ f φᵢ dx - Energy functional (Ritz):
Π(u) = ½∫ EA (u′)² dx − ∫ f u dx − P u(L); δΠ = 0 - Galerkin orthogonality:
a(u − u_h, v_h) = 0 → u_h is the best fit in the energy norm
Worked example: Deriving the weak form
Given: −u″ = f on (0, 1), u(0) = 0, u′(1) = g
Find: Weak form.
- Multiply by v (v(0) = 0), integrate
- −∫u″v = ∫u′v′ − [u′v]₀¹
- Boundary: u′(1)v(1) = g v(1)
Answer: ∫u′v′ dx = ∫fv dx + g v(1)
Worked example: One-term Galerkin
Given: −u″ = x, u = c x(1 − x)
Find: c.
- φ′ = 1 − 2x; ∫(1 − 2x)² = 1/3
- ∫x·x(1 − x) = 1/12
- c/3 = 1/12
Answer: c = 1/4 → u = (x − x²)/4
Worked example: Ritz beam estimate
Given: Simply supported beam, UDL q, w = a sin(πx/L)
Find: a.
- Π = ½EI∫(w″)² − ∫qw
- ∂Π/∂a = 0 → a = 4qL⁴/(π⁵EI)
Answer: a = 0.013071 qL⁴/EI vs exact 0.013021 (+0.39%)
Galerkin solution with polynomial trial functions (SymPy)
import sympy as sp
# Galerkin for -u'' = x on [0, 1], u(0) = u(1) = 0 (exact: u = (x - x^3)/6)
x = sp.symbols("x")
f = x
exact = (x - x**3) / 6
for N in (1, 2):
phis = [x**(i + 1) * (1 - x) for i in range(N)] # satisfy the BCs
c = sp.symbols(f"c0:{N}")
u = sum(ci * p for ci, p in zip(c, phis))
# weak form: int u' v' dx = int f v dx for every test function v = phi_j
eqs = [sp.integrate(sp.diff(u, x) * sp.diff(p, x) - f * p, (x, 0, 1)) for p in phis]
sol = sp.solve(eqs, c)
uN = sp.expand(u.subs(sol))
print(f"N={N}: u = {uN}, u(0.25) = {float(uN.subs(x, 0.25)):.5f}")
print(f"exact: u = {sp.expand(exact)}, u(0.25) = {float(exact.subs(x, 0.25)):.5f}")
# N=1: u = -x**2/4 + x/4, u(0.25) = 0.04688
# N=2: u = -x**3/6 + x/6, u(0.25) = 0.03906
# exact: u = -x**3/6 + x/6, u(0.25) = 0.03906With one trial function the answer is approximate; with two, the trial space contains the exact cubic, so Galerkin recovers it exactly. FEM uses the same equations, but with local piecewise basis functions instead of global polynomials.
Common mistakes
- Wrong: Imposing force BCs on the trial functions. — Right: Natural BCs enter through the boundary term, not the trial space.
- Wrong: Trial functions violating essential BCs. — Right: They must satisfy u = prescribed values.
- Wrong: Assuming FE deflections are upper bounds. — Right: Displacement FE is too stiff: deflections are typically underestimated.
Applications
- Structural FEM: Every displacement-based element comes from the weak form.
- Heat & diffusion: Weak forms of Laplace/Poisson for thermal FE.
- Electromagnetics: Variational FE for fields in motors and antennas.
- Quick estimates: Ritz with one or two terms for buckling and vibration.
Key takeaways
- Weak form = multiply by v, integrate by parts.
- Essential BCs in trial space; natural BCs in load vector.
- Galerkin/Ritz → Kc = F.
- Best approximation in the energy norm.
Going further
- Petrov–Galerkin: Different test functions for convection-dominated flow (SUPG).
- Mixed formulations: Separate fields for incompressible solids and Stokes flow.
- A-posteriori error estimates: Adaptive mesh refinement driven by residuals.