loading...
Vapour density against distance from the centre (mean over rings): the depleted zone around the crystal
running...
How to use
Drag to orbit, wheel or pinch to zoom, Space pauses, R restarts. The cold stage, slide, macro objective and controller were modelled in Blender (baked PBR textures); the crystal is a set of hexagonal prisms built live, one per frozen cell, with height following the cell mass. The coloured disc under the crystal is the vapour density. The controller screen shows the current model state.
The science
The model. A snow crystal grows by water vapour diffusing to a seed and freezing on it. Reiter's cellular automaton (2005) puts this on a hexagonal lattice, because ice has hexagonal symmetry. Each cell holds a number s (water mass). A cell is frozen if s >= 1; it is receptive if it is frozen or touches a frozen cell. Otherwise it is part of the vapour.
One time step. Split every cell's mass into a diffusing part u (zero in receptive cells, s in the others) and a non-diffusing part v (s + gamma in receptive cells, zero elsewhere). Then
s'(x) = u(x) + (alpha / 2) ( mean of u over the 6 neighbours - u(x) ) + v(x)
alpha sets the diffusion rate, gamma is the vapour that sticks to every receptive cell per step, and the outer ring of the lattice is held at the background density beta.
Why the shapes differ. Corners and tips stick out into the vapour and are reached by more molecules than the flat sides (the Mullins-Sekerka instability), so a hexagon sprouts arms. High vapour density (beta near 1) feeds the faces fast enough that the crystal stays a plate; low beta and low gamma give thin arms and side branches. The shapes are the same family Libbrecht describes from lab-grown crystals, but the model is a caricature: real growth also depends on temperature in a complicated way.
Six-fold symmetry. Because the rules are identical in the six directions, a noise-free crystal started from a point or a hexagon is exactly symmetric. Real snowflakes are never exactly symmetric because each arm sees slightly different conditions; the noise slider multiplies gamma by a random factor to mimic that.
Diffusion checks. A pulse spreading by this rule has the mean-square displacement <r^2> = (alpha / 2) t a^2 (a random walk in which a fraction alpha/2 of the mass hops each step to a random neighbour), measured in the hexagonal lattice units. The page measures it from a simulated pulse and compares. Total mass is conserved by the diffusion step, and for the growing crystal M(t) = M(0) + sum gamma over receptive cells + boundary inflow, which the page tracks separately and compares with the direct sum.
Honest simplifications. (1) This is a 2D plate crystal; real crystals also grow thickness, with different branching in layers. The 3D view lifts each cell by its mass, which is a visual, not a physical, height. (2) The boundary condition fixes the vapour density at the lattice edge, so the growth stops (it is stopped automatically) when the arms reach the edge. (3) There is no temperature, latent heat or surface kinetics. (4) The presets are chosen for variety, not matched to a measured temperature and humidity. (5) Lattice units are not millimetres.
Checks run in the page. Diffusion spreading for two alpha values; mass conservation; the mass bookkeeping of a growing crystal; six-fold symmetry for a point seed and for a hexagonal seed; and the loss of symmetry when noise is on.