Simulate the physical world.
Differentiate all of it.
Rigid bodies, particles, fields, molecules, lattices. One engine, in Rust, with analytical gradients through every step and thousands of environments on the GPU.
Built on tang, which supplies the scalars, the linear algebra, and the differentiable kernels underneath.
phyz is a differentiable simulation engine for articulated rigid bodies, particles, electromagnetic fields, molecular dynamics, and beyond. Every algorithm computes gradients for optimization, control, and learning.
Plug in semi-implicit Euler, RK4, or your own solver. Load MuJoCo MJCF models. Fit simulation parameters to real trajectories. Batch thousands of environments on the GPU.
The numerics come from tang: generic scalars for dual numbers and exact derivatives, dense linear algebra, and a tensor IR that lowers to CUDA, Metal, Vulkan, and WGSL. phyz is the physics on top.
phyz is early, ambitious, and open source.
Build a model, step it, and ask for the Jacobian of the next state with respect to this one. The simulation on the right is this code, running; the readouts are its numbers.
use phyz::{ModelBuilder, Simulator, Vec3}; use phyz_diff::symbolic::CompiledStepJacobians; // Double pendulum: two revolute joints, links hang in −Y. // Joint frames and spatial inertias as in examples/double_pendulum.rs. let model = ModelBuilder::new() .gravity(Vec3::new(0., -9.81, 0.)) .dt(0.001) .add_revolute_body("upper", -1, frame_upper, inertia) .add_revolute_body("lower", 0, frame_lower, inertia) .build(); let mut state = model.default_state(); state.q[0] = 1.88; state.q[1] = 1.26; // joint angles // Trace ABA + the integrator symbolically, once. // Every eval after that is exact: no finite differences. let jac = CompiledStepJacobians::build(&model); let sim = Simulator::rk4(); loop { sim.step(&model, &mut state); let j = jac.eval(&[&state.q[..], &state.v[..], &state.ctrl[..]].concat()); // j.dqnext_dq: ∂q′/∂q how this state moves the next // j.dvnext_dctrl: ∂v′/∂τ how a torque now moves the next // chain these through a rollout for end-to-end gradients println!("‖∂q′/∂q‖ = {:.3}", j.dqnext_dq.norm()); }
Step and differentiate. ∂q′/∂q is the 2×2 drawn under the pendulum: it says how a nudge to either joint now shows up in both joints one millisecond later. Its norm spikes when the lower link whips.
Every card is a phyz crate compiled to WASM and drawn live, with the simulation's own numbers under it. Each one says what is happening and what you would use it for.
Articulated rigid bodies on Featherstone's spatial algebra: O(n) forward dynamics, contacts through GJK/EPA, energy you can audit. The part of phyz a robot is made of.
Two links on revolute joints, integrated with RK4 at a millisecond. The trail is the lower tip; the energy readout is what the joint damping takes out each second, so the drift you see is physical, not numerical.
ForChecking a solver: any integrator that loses energy without damping is wrong, and this card is the test.
Five pendulums with sphere contacts between the bobs. An impulse enters on the left and crosses the row through four near-elastic collisions in a single step, so the far bob leaves before the near one has visibly moved.
ForImpact-heavy mechanisms: latches, escapements, anything where contact timing decides the outcome.
Twenty spheres dropped into a loose pile. GJK/EPA finds each contact pair, a penalty law resolves it, Coulomb friction stops the pile spreading. The pile height settles in about two seconds.
ForHoppers, bins, parts feeders, and any scene where many rigid bodies have to come to rest against each other.
Discrete elements, the material point method, and mass-spring bodies. For the materials that don't have a shape until you simulate them: grains, soils, jellies.
Five hundred grains as discrete elements against funnel walls. The neck is five grain diameters wide, which is where arching starts, so the flow rate is set by grains jamming and un-jamming, not by gravity.
ForSilo and hopper discharge, powder dosing, and the clogging behavior that continuum models can't see.
A column of sand collapses under its own weight. The material point method carries stress on a background grid and a Drucker-Prager yield surface decides when it flows, so the run-out distance comes from the friction angle.
ForLandslides, excavation, wheel-soil interaction, and tuning a soil model against a lab collapse test.
A disc of particles tied by springs is dropped and lands on its edge. It squashes, rings, and settles; springs stretched past six percent are drawn in blue so you can see where the strain goes.
ForSoft grippers, tires, and padding: anything where a deformable part meets a hard one and you care about contact area.
Grids instead of bodies: Maxwell on a Yee lattice, Boltzmann on D2Q9, and a thousand pendulums drawn as one surface. Waves, flows, and sweeps.
A plane wave hits a wall with two slits. Maxwell's equations run on an 80×80 Yee grid with an absorbing boundary, and what's drawn is time-averaged intensity, so the picture that builds up is the interference pattern itself.
ForAntenna and waveguide layouts, photonic structures, and radar cross-section studies at a scale a laptop can run.
Flow past a cylinder on a D2Q9 lattice Boltzmann grid. Vorticity is drawn, blue one way and coral the other, so the von Kármán street alternating down the wake is visible as it sheds.
ForDrag on bluff bodies, cooling flow through electronics, and fast 2D flow where a full Navier-Stokes solver is more than you need.
1,024 pendulums whose lengths sweep across the grid, all released at once. Their periods differ slightly, so their phases drift apart into a travelling wave and then back into step: a batched simulation drawn as one field.
ForParameter sweeps: run a thousand variants of a model at once and see the whole response surface, which is what the GPU batch path does at scale.
Articulated trees under control. Torques in, the same O(n) dynamics out, one body or a hundred at once. This is what the controller runs against.
An eight-joint quadruped with the torso fixed. Each joint is a PD servo chasing a trot, diagonal legs in phase; the torques go in as control inputs and the articulated-body algorithm gives back the motion. Drag to orbit.
ForGait design and controller tuning before touching hardware, with the same O(n) dynamics the robot's own controller can run.
The classic control benchmark: a pole balanced on a cart by a PD law on angle and position. It recovers from a quarter-radian push, brings the cart back to center, and resets every fourteen seconds.
ForA first test for any controller or learned policy, and a sanity check that the dynamics match the textbook.
One hundred inverted pendulums, each with a different pair of PD gains. The ones that stand up light up; the ones that don't fall. The grid is the gain space, read directly.
ForBatched policy search and reinforcement learning: thousands of environments stepping together is how training data gets made.
Every simulation on this page is differentiable. These three put the gradient to work, and two of them differentiate through contact, which is where most engines stop.
A spinning box lands somewhere. One backward pass through the whole rollout returns ∂(landing)/∂(every corner) and ∂/∂mass, exactly. The arrows on the corners are those gradients: move a corner that way and it lands further right. Drag sideways to change the spin.
ForDesign optimization with physics in the loop: let the shape or the mass distribution be the thing you optimize, not just the controller.
A block on a slope with the convex Coulomb contact the simulator ships, differentiated through the contact solve. Below the friction angle it sticks and d(slide)/dμ is exactly zero; past it, the derivative switches on and matches the closed form. Drag up and down to tilt.
ForSystem identification of friction and restitution from real contact data, and gradient-based control through impacts.
Pull the pendulum back and let go: that's the recording, in bone. The model starts with the wrong length, in blue, and gradient descent on the trajectory error pulls it onto your swing. Mass gets a gradient too, and it's zero, because a pendulum's period doesn't depend on it.
ForFitting a simulator to a real robot's logs so that what you plan in sim holds on the floor.
Position-based dynamics with real compliance, meters per newton, so the stretch you see is a material property and not an iteration count. Cloth, cables, and anything that hangs.
A 28×18 cloth pinned down one edge in a gusting wind. Position-based dynamics with real compliance, in meters per newton: structural, shear and bending constraints at eight substeps a frame. Edges turn blue where they're stretched. Drag to orbit.
ForSails, banners, tarps and cable-stayed fabric where the wind load matters more than the stitch.
A square cloth dropped over a sphere onto a floor. The solver has no collisions of its own, so this card projects particles out of the sphere between short solver calls, which is all position-based dynamics needs. Drag to orbit.
ForGarments, covers and packaging: how a flexible sheet settles over a rigid thing underneath.
Two meters of cable hung across 1.6 meters of span. It falls into a catenary and hangs there; the readout is how much the links stretch under their own weight, which is compliance times tension and nothing else.
ForTethers, hoses and power cables on robots and cranes, where sag and tension have to be right before anything else is.