kelvin@cluxnei.dev:~/blog

kelvin@cluxnei:~/blog$ cat navier-stokes.md

2026-09-14 EN ~18 min read ler em português

The equation can blow up. My simulator will not let it.

Last week OpenAI announced that an internal model proved something about the Navier-Stokes equations. Plenty of people read the headline backwards. What was proved is that the ideal fluid can break, not that it is always well behaved. I have a simulator of those equations running in the browser, and it is built in a way that makes that break impossible to show. Understanding why it will not let it happen is a good way to understand what the proof says.

Taylor-Green vortex. An initial condition written as an exact formula, dropped into a periodic box. It rolls itself into ever smaller structures until it becomes turbulence, and then it is gone. That descent towards smaller scales is exactly where the millennium question lives.

In this text

  1. What was announced, carefully
  2. The equation, term by term
  3. What "blowing up" means
  4. What my simulator actually does
  5. Why it cannot blow up
  6. The price, in measured numbers
  7. What that teaches about the proof
  8. The credit dispute

What was announced, carefully

On 8 September 2026 OpenAI published that an internal model produced a proof concerning the Navier-Stokes millennium problem, and that it was formally verified in Lean. The company says it took 88 hours and used up to ten thousand agents working more or less concurrently.

The content is what tends to get lost in the headline:

It was proved that the three-dimensional Navier-Stokes equations can develop a singularity in finite time.

This is the negative resolution. The millennium question was whether a smooth initial condition stays smooth forever, and the answer is no. The setting is the idealised one from the statement: three-dimensional space with no boundary, a smooth forcing function, and with viscosity, that is real Navier-Stokes and not the frictionless Euler equations.

Two caveats worth more than the rest. Verification in Lean guarantees the proof is internally correct, but the part still left to humans is guaranteeing that the statement written in Lean is logically equivalent to what the mathematicians set out to prove. And this text was written days after the announcement: if you are reading it much later, check where the discussion stands before quoting anything from here.

The equation, term by term

Navier-Stokes is Newton's second law written for a fluid. Instead of following each particle, you follow a velocity field u: at every point in space, where the fluid is going and how fast, at that instant.

∂u→ ∂t = − (u→⋅∇) u→ − ∇pρ + ν∇2 u→ + f→ ∇⋅u→ =0

The first line says how the velocity changes. The second is the incompressibility condition: what flows into a region has to flow out, because the fluid cannot be compressed.

There are four terms on the right, and each one does something you can watch on screen.

Advection, the term that causes the trouble

− (u→⋅∇) u→

The fluid carries itself.

This is the villain of the whole story. Notice that u appears twice, multiplying: velocity transports velocity. That is what makes the equation non-linear, and it is the non-linearity that opens the door for a large velocity to create an even larger one, in a feedback loop. Without this term there would be no millennium problem and no turbulence either.

Pressure, the term that enforces the rule

− ∇pρ

Pressure is not an independent variable here: it is whatever it needs to be to keep ∇·u = 0.

This is the part that usually confuses people. In an incompressible fluid, pressure has no evolution equation of its own. It is computed every step as the one thing capable of cancelling whatever compression the other terms tried to create. It is also the term that makes the equation non-local: stirring the fluid in one corner changes the pressure across the whole domain instantly.

Viscosity, the term that calms things down

ν∇2 u→

Diffusion. It spreads velocity out and eats differences, more strongly the smaller the scale.

Viscosity is the brake. It attacks small structures preferentially, which are exactly the ones advection is trying to create. The millennium problem is the contest between those two terms: advection pushing energy towards ever smaller scales, viscosity trying to dissipate it before the scale reaches zero. The question was whether viscosity always wins. Now we know it does not.

Forcing, the term you control

f→

Everything that pushes the fluid from outside: gravity, buoyancy, a fan, your hand.

In the simulator, buoyancy is what makes smoke rise: every hot cell gets an upward push proportional to its temperature. It is the only forcing in the plume scenario, and it is enough to produce the whole structure.

Plume, with buoyancy as the only forcing. The mushroom cap on top was not drawn: it appears because the head of the plume pushes against still air, rolls its edges inward, and advection does the rest.

What "blowing up" means

A finite-time singularity does not mean the liquid disappears or the screen goes white. It means something precise: there is a finite instant T at which some quantity of the solution stops being bounded. Typically the vorticity, which measures how much the fluid is spinning locally.

lim t→T− ‖ω→ (t)‖ =∞

The vorticity ω grows without bound as it approaches a finite instant T. Past that, the equation no longer has a smooth solution, and saying what happens afterwards stops making sense.

Physically, that is energy concentrating into a region that shrinks to zero size. In real water none of this happens, because long before that the continuum description stops applying and you are talking about molecules. The singularity is a fact about the equation, not about your kitchen sink.

What my simulator actually does

The simulator solves exactly those equations on a uniform grid, using a method called Stable Fluids, published by Jos Stam at SIGGRAPH 1999. Each step does five things, in this order:

  1. Forces: buoyancy and whatever the scenario injects.
  2. Vorticity confinement (Fedkiw et al., 2001): measures the local spin and pushes the fluid back towards it, restoring the small eddies a coarse grid eats.
  3. Viscous diffusion: implicit, solved with Gauss-Seidel.
  4. Advection: semi-Lagrangian, with an optional MacCormack correction to keep the smoke sharper.
  5. Pressure projection: solves ∇²p = ∇·u and subtracts the gradient. This is the step that makes the fluid incompressible.

Hold on to items 3 and 4. They are the ones that close the door.

Why it cannot blow up

Semi-Lagrangian advection works backwards from what intuition suggests. Instead of asking "where does this particle go", it asks, for each cell, where did what is here now come from: it steps backwards through the velocity field and interpolates whatever value it finds.

A cell's new value is always an interpolation of values that already existed. A weighted average is never larger than the largest of the values it mixes. So the maximum of the field cannot grow through advection, whatever the timestep. That is what unconditionally stable means.

Implicit diffusion closes the other half: instead of computing the new state from the old one, it solves a system where the new state appears on both sides. That is stable for any viscosity and any step.

semi-Lagrangian advection   unconditionally stable
implicit diffusion          stable at any timestep
                            ─────────────────────────────
result                      the field never diverges

Which means: even if the real equations wanted to produce a singularity, this method has no way to represent it. It is smooth by construction, not by physics. The stability that keeps it from ever locking up is the same thing that makes it blind to the phenomenon that has just been proved to exist.

The price, in measured numbers

Unconditional stability is not free. The interpolation that guarantees nothing grows also smooths at every step, and that smoothing acts like a viscosity nobody asked for. Its name is numerical viscosity, and at browser resolutions it dominates.

You can see it in the panel. These are the numbers from a Karman vortex street actually running:

Grid          62x24x24
Cells         35.7k
Peak u        1.00
Energy        0.157
Vorticity     1.60
Divergence    0.1003
Reynolds      2,191
Solver        36.1 ms

Two of them deserve attention.

Divergence 0.1003. The equation demands ∇·u = 0 exactly. What is left after the projection is this, and it is not zero. The pressure step is solved by Gauss-Seidel iterations that stop when the budget runs out, not when they converge. Incompressibility is approximate.

Reynolds 2,191. That is the number implied by the viscosity I asked for. The effective Reynolds number of what appears on screen is lower, because numerical viscosity adds to the explicit one. It is why the Taylor-Green vortex at the top decays faster here than in a real direct numerical simulation.

There is an honest counterweight: where it can be measured against reality, the result holds up. The Karman street sheds at a Strouhal number between 0.13 and 0.19, against about 0.2 measured on a real cylinder.

Karman vortex street. Uniform flow past a cylinder. Above Reynolds 50 the wake stops being symmetric and starts shedding alternate vortices from each side. It is the same pattern that makes power lines sing in the wind.

What that teaches about the proof

Nearly every fluid simulator used in production, from visual effects to weather forecasting, makes some version of the same bargain: it trades fidelity at small scales for a method that does not blow up. The choices vary, the bargain does not.

Which means the singularity proved this month is invisible to most of the fluid computation that exists. Not because it is irrelevant, but because the entire numerical engineering was built to suppress exactly the behaviour it describes. A method that could show it would be, from the point of view of someone simulating smoke for film, a broken method.

There is a nice symmetry here with the post on the gravitational simulation. There, the singularity in Newton's law when two bodies come too close is removed on purpose, with Plummer softening, and the text argues for choosing the scale at which you accept being wrong. Here it is the same decision, made for the same reason, against a singularity we now know to be real rather than an accident of the formula.

The credit dispute

It would be dishonest to report the news without this. The announcement came with a dispute attached. OpenAI says it started the effort on 1 September after hearing a rumour, and that it later connected that rumour to Levent Alpöge, of Anthropic, and Tristan Buckmaster, of NYU.

On finishing its own proof and the Lean verification, the company says it approached the two for a joint announcement, and then learned their work addressed a related but distinct problem: the forced Euler equations, which are Navier-Stokes without the viscosity term.

Buckmaster suggested publicly that OpenAI's agents may have had access to his and Alpöge's work and benefited from it. OpenAI credits the pair for the Euler result and claims priority on Navier-Stokes. Both teams owe a foundational debt to earlier work by Córdoba and Martínez-Zoroa.

I have no way to arbitrate this and will not try. I record it because it is part of the fact, and because it is the part that will age first.

A note on the videos. They were captured under software rendering, at about 7 frames per second, and reassembled at 24. They are therefore sped up: what you watch in a minute took several to compute. The levels adjustment is the same as in the other posts. The physics was not touched.

The simulator lives at cluxnei.dev/navier-stokes/, with twelve scenarios and each one's parameters exposed before it starts. The source, with 53 tests and a README that documents its own flaws, is on GitHub.

kelvin@cluxnei:~/blog$