Additive Manufacturing: Scanning-Laser Thermo-Mechanics
A laser sweeps across a clamped metal plate — one pass of a powder-bed or directed-energy build. The
moving hot spot conducts heat into the plate (and loses some to the surroundings); the locally hot
material wants to expand but the cool material around it holds it back, so a thermal stress field
travels with the beam. Two physics in one coupled jno.fem:

Temperature drives stress — a linear cross-coupling
Temperature (P1) and displacement (P2 vector) go into one monolithic system. The coupling is the
thermal-expansion term - beta*(Tb - T_ref)*trace(ep) — temperature feeds the mechanical balance
exactly the way Boussinesq buoyancy feeds the momentum balance:
T, sT = d.fem_symbols(names=("T", "sT"), order=1)
u, phi = d.fem_symbols(value_shape=(2,), names=("u", "phi"), order=2)
eu, ep = symgrad(u, [xi, yi]), symgrad(phi, [xi, yi])
thermal = Tb.t*sb + (Tb.x*sb.x + Tb.y*sb.y) + Bi*Tb*sb # heat (the laser is added per-step)
mech = lam*trace(eu)*trace(ep) + 2*mu*inner(eu, ep, n_contract=2) - beta*(Tb - T_ref)*trace(ep)
fem = jno.fem([thermal, mech, u(xb, yb) - 0.0, T(ci[0],ci[1]) - 0.0, u(ci[0],ci[1]) - 0.0])
The moving laser is a per-step load — and the operator is constant
A time-dependent source can't live in the weak form, but with a bring-your-own stepper that's no
obstacle: the whole problem is linear, so its operator M + dt·A never changes. Factor it once
with a sparse LU and back-substitute every step — the laser is simply a different right-hand side
(a Gaussian centred at the current beam position, scattered as a lumped nodal load):
lu = splu((M + dt*A).tocsc()) # factor ONCE
for step in range(nsteps):
cx = x0 + v_scan * (step+1)*dt # beam moves
g = (2*P/(pi*r0**2)) * exp(-2*((xT-cx)**2 + (yT-y0)**2)/r0**2)
load = zeros(fem.dofs); load[:nT] = g * nodal_area # lumped source on the T block
w = lu.solve(M @ w + dt*load) # back-substitute (no re-factor)
The entire 50-step coupled solve runs in a fraction of a second.
Validated against Rosenthal — and honest about plasticity
The deposited laser energy balances the stored heat plus surface loss (to ~1 %); the constrained hot
zone is in compression (tr σ < 0); and the trailing thermal wake matches the shape of the
classic Rosenthal moving-point-source solution (right panel — the finite spot, finite plate, and
surface loss make it slightly cooler than the idealised point source).
Pure thermo-elasticity shows the transient stress that travels with the beam and relaxes once the plate re-cools uniformly. Permanent residual stress and warping require plasticity (a J2 return-mapping step) — the natural extension; we deliberately do not call the elastic stress "residual".
Reference: D. Rosenthal, Trans. ASME 68:849 (1946) — the theory of moving heat sources.