How we test a physics engine.
A finite-element engine that gives an agent the wrong number is worse than no engine at all — the agent will trust it. So in physicsbase the test suite isn't an afterthought. It's the specification.
Most software tests check that code does what the author intended. Physics tests have a harder job: they check that the code agrees with the universe. The beautiful thing about mechanics is that for a great many problems, the universe's answer is written down in closed form — a clean formula from a textbook. A cantilever's tip deflects by \(PL^3/3EI\). A column buckles at \(\pi^2 EI/L^2\). A restrained bar heated by \(\Delta T\) carries \(-E\alpha\,\Delta T\). If the engine disagrees with the formula, the engine is wrong. Full stop.
The test is the spec
Every element and every analysis in physicsbase ships with at least one test that builds a problem whose answer is known exactly, solves it, and asserts equality to tolerance. Nothing is trusted because it "looks right." Here's a real one — Euler buckling of a pinned column:
def test_buckling_pinned(): m, p = _column("pinned") # pin-ended steel column res = buckling(m, num_modes=1) expected = math.pi**2 * p["E"] * p["I"] / p["L"]**2 # Euler's Pcr assert res.critical_loads[0] == pytest.approx(expected, rel=1e-2)
No golden files, no "close enough by eye." The engine's returned critical load must match Euler's formula to within 1%, or the build fails.
The 53
As of this writing the suite is 53 checks, all green, spanning the whole engine:
| Area | Checked against |
|---|---|
| Bars, trusses, beams | axial \(PL/AE\), tip \(PL^3/3EI\), rotation \(ML/EI\) |
| 3D frames | biaxial bending and torsion \(TL/GJ\) |
| Continuum & solids | uniform-strain patch tests for every element (CST, Q4, LST, Q8, tet4, hex8, axisymmetric) |
| Dynamics | cantilever & simply-supported natural frequencies; step-response 2× overshoot |
| Stability | Euler buckling — pinned, cantilever, fixed-fixed |
| Thermal & loads | \(-E\alpha\,\Delta T\), self-weight, distributed loads, tractions |
| Multiphysics | conduction profiles, convection, 2D/3D field patch tests, convection-diffusion, coupled thermal stress |
| Nonlinear | the damage law's stress-strain response |
The uniform-strain patch test deserves a special mention, because it's the cleanest idea in the whole file. Impose a displacement field corresponding to a constant strain on an element's nodes, ask the element what stress it reports, and check it equals the exact \(\mathbf{D}\!:\!\boldsymbol{\varepsilon}\). If an element passes the patch test, its strain-displacement matrix is correct — the single most important property a new element can have. Every solid element in physicsbase passes it.
pytest -q. Fifty-three closed-form validations, a few seconds, all green. The suite is the honest answer to "can I trust this number?" See the validation docs →