How it works

What runs when you press Run, what it is built on, how it is checked, and how to get the most out of the playground and Folder. The short version: the whole finite element pipeline, from mesh to picture, executes in your browser, in TypeScript and WebAssembly, in a Web Worker so the page stays responsive.

The pipeline

MILAMIN was never one trick. The 2008 paper showed that a general unstructured finite element code reaches a million unknowns per minute when every stage gets equal care: meshing, assembly, factorization and postprocessing all have to scale, because the moment one of them is neglected it dominates the total time. That strategy, not any single component, is what runs here, stage by stage:

Unknowns are counted as in 2008: two velocities at every node of the 7-node element, the bubble node included; the pressure is eliminated element by element and never enters the global system. The browser solver condenses the bubble before assembly, so the system it factorizes has about two thirds of that count, which is part of its speed. The stage times shown on the pages add up to the quoted totals; outside them are the one-off start of the worker and its wasm modules and a few milliseconds of bookkeeping.

Threads and memory

The default thread count is deliberately not the maximum your machine offers. Two-dimensional factorizations gain little beyond about four threads and lose ground when every hardware thread is used, which is what a memory-bandwidth limit looks like, so the pages start at four on a desktop and at two on a phone, and let you try more. On the one phone we measured, with its mix of large and small cores, one and two threads were equally fast at a million unknowns. Everything is in the benchmark and its log. A run with a million unknowns needs about 2.5 gigabytes and the largest settings allocate several. The solver modules are 32-bit WebAssembly, so each can address at most 4 GB, and that memory lives inside the browser’s own process: a 32-bit browser cannot hand one module anything near that, a 64-bit browser can, so the largest settings need a 64-bit browser with memory to spare. Numbers depend on your machine; the benchmark runs on yours.

Checked, not just fast

The solvers come with verification suites, run before every release: 46 checks against the analytical circular-inclusion and rigid-polygon solutions and between the two independent factorization paths, plus 26 checks of Folder’s growth rates against the analytical small-amplitude theory. The convergence lab runs the inclusion comparison live on finer and finer meshes and shows where the error lives.

Using the playground

A model is a short JavaScript function body returning { mesh, mu, bc }: closed boundary polylines or an explicit point-and-segment list, region seeds with a material attribute and a local mesh size, a viscosity per material and a Dirichlet or free-slip velocity per boundary marker. The playground documents the API under its editor and starts from three presets. Boundaries may not cross or touch, which is checked before meshing. Your model is remembered in your browser; Share link puts it in the address, and opening such a link loads it. The panels save as PNG, zoom with the wheel or the buttons and the colour range can be set by hand. Ctrl+Enter runs, Stop ends a runaway model.

Using Folder

Folder steps a layered model through shortening or extension: the box is remeshed at every step, Stokes is solved (with Picard iterations for power-law materials, each step starting from the previous solution), and the interfaces are advected. Changing an input redraws the initial geometry at once, before any meshing; the dominant wavelength for the chosen layer is shown under the perturbation controls so the perturbation can be set in relation to it. Inputs are remembered and can be shared as a link; the field panel enlarges, saves as PNG and takes manual colour limits.

Reproducing the numbers

The benchmark sweep, the convergence study and the playground presets can also be run from the command line with Node, using the same code as the pages, so every number on the site can be recomputed without a browser. The benchmark log in the repository records the measurements on the devices we had.

The repository

The site and the solver are one repository on GitHub, written in TypeScript with a little C++ for the parts compiled to WebAssembly, and delivered to your browser as JavaScript and wasm: