Differentiable design
Click a feature, see the gradient, optimise live: physics differentiated with respect to shape, and the honest limit that keeps it a screening tool.
I clicked one fillet radius on a plate with a hole, and a gradient told me exactly which way to drag it before I ever re-ran the solver.
That’s not a rendering trick. It’s a derivative of physics with respect to shape, computed directly, with a real finite-element solver in the loop the whole time.
Why this is unusual
Normally, “how does stress change if I make this fillet bigger” is answered by trial and error: change the geometry, re-mesh, re-solve, compare. Neither MOOSE nor FEniCSx — two solid, general finite-element tools — gives you the derivative d(physics)/d(shape) directly. You get a single answer per solve, not a direction to move in.
We built CutFEM solvers with a gradient that flows straight through them. Right now that covers 20 differentiable physics modes, backed by 125 out of 125 live tests passing. The basics check out at the level a numerics engineer actually cares about: patch tests are exact to machine precision, and the geometry derivative matches finite-difference checks.
Geometry as two layers, not one mesh
The part that makes “click and see the gradient” possible is how we represent geometry. There are two layers. The first is a recipe — an editable feature tree, the kind of thing a CAD user already thinks in: this fillet, that hole, this extrusion. The second is a theta envelope — a cloud of Gaussian surfels that the physics solver actually computes on. The two layers are differentiable in both directions: theta maps to a signed-distance field, which the solver consumes, and the round trip theta → SDF → CutFEM solve reproduces the field at a relative error of 0.0212.
Boundary conditions anchor per feature, not per wall. “Clamp fillet 5” pins exactly the nodes belonging to that fillet, not a generic face — with an equilibrium residual of 1.95e-6. The full gradient dJ/d{mu, sigma, w} runs through the entire graph, and we checked it against finite differences: agreement to 3.4e-4, comfortably inside our 1e-2 threshold.
What it actually did on a real problem
Plate with a hole, a classic stress-concentration case. Optimising against peak stress, the live run moved peak von Mises stress from 209.5 MPa down to 180.8 MPa — a 13.7% reduction, and the descent was monotonic the whole way, not a lucky single step.
The mistake we paid an experiment to find
Our first instinct was to optimise mean stress, because it’s the smoother, easier signal to differentiate against. We ran it. Mean von Mises barely moved — -0.2% — because the mean is dominated by the far field, the large bulk of material that’s barely stressed at all. The hole barely registers in an average.
That’s the wrong objective. Parts don’t fail at the mean; fatigue cracks start at the peak. Optimising mean stress optimises the wrong thing convincingly. We only found this because we ran both and compared — it’s a small result, but it’s the kind of mistake that looks completely reasonable until you check it against how things actually break.
What this changes, and what it doesn’t
The product framing here matters: the engine doesn’t hand back a voxel grid or a point cloud that a human has to reinterpret. It hands back an editable proposal — which feature to move, and by how much, in the same feature-tree language the geometry started in. We also proved the export path works end-to-end: TorchScript round-trips at exact parity, and ONNX export holds to 9.7e-7, at a 10.6 MB model size. So this isn’t stuck in a research notebook — it deploys.
Here’s the honest limit, and it matters more than any number above: this optimisation loop trusts the surrogate’s shape of the stress field to point the gradient in a useful direction, but on our own geometry-disjoint accuracy holdout, the surrogate’s peak-location error and peak-value error are not certification-grade — our best model still misses our own accuracy gate by a wide margin on unseen geometry. That means today this tool is a ranking and screening instrument: it’s very good at telling you which direction reduces stress, and by roughly how much, on cases inside its comfort zone. It is not yet a replacement for a certified solve before you cut metal. Every proposal it makes should be re-verified through the real solver before it becomes a decision, exactly the same discipline we use everywhere else in this project.
I think that’s the honest way to describe a differentiable design tool at this stage: fast, directionally correct, genuinely useful for exploring a design space — and still accountable to a real solver at the end.
If you’ve built or used gradient-based shape optimisation, where did your gradient point you in the wrong direction, and how did you catch it?
Discuss NeuroCAD as a pilot or investment opportunity.
Working MVP/demo is available for qualified conversations.
Contact the Founder