Full 3D de Rham complex
Π⁰ over H¹, Π¹ over H(curl), Π² over H(div), Π³ over L². The complete discrete de Rham complex, lowest order, lowest friction.
A small, dependency-free JavaScript reference implementation of Π⁰, Π¹, Π², Π³ for the 3D de Rham complex. Bounded, commuting, exact on the boundary. Built for engineers who care about the math.
Capabilities
One library. Four form degrees. Three trace spaces. Zero transpilation. The same code runs in Node 24+, the browser, and the sandboxed playground.
Π⁰ over H¹, Π¹ over H(curl), Π² over H(div), Π³ over L². The complete discrete de Rham complex, lowest order, lowest friction.
Vertex values u(v), edge tangentials ∫_e u·t ds, and face normal fluxes ∫_f u·n dA reproduced to machine precision on every boundary simplex.
Vertex, edge, and face duality functionals on P¹, N₀, and RT₀, built from the barycenter tent μ and the local mass matrix on each star.
LU solve, 3×3 inverse, barycentric gradients, surface differential operators — every kernel routine is hand-rolled in pure JavaScript.
Hot-path code paths. Sub-millisecond per projection on 10k tetrahedra.
O(log N) point-in-tet queries after a one-time balanced tree build. Pick any point inside the unit cube and get the projected value in microseconds.
Scalar bubble basis for H¹ (p ≥ 4) and an L² monomial basis for L² (p ≥ 1). Hand-written .d.ts for every module.
Get started
npm install,No build step. No transpiler. No peer-dep negotiation. Drop the lib into any Node 24+ project and call projectH1, projectHcurl, or projectHdiv — the rest of the de Rham complex is just composition.
01# Node 24+ (Node 26 recommended)02npm install traceprojectorArchitecture
Every projector splits into a boundary-preserving part and an interior ring part. Both are computed in stable local solves on Alfeld- or Worsey–Farin-subdivided patches — no global system, no iterative refinement.
The master equation
Π_∂ˡ prescribes the boundary data exactly. Π_ringˡ is the interior projector with vanishing trace. Together they form a single, commuting, bounded operator.
Prescribes the boundary data exactly. Built on Alfeld (boundary faces) or Worsey–Farin (bulk tet) splits.
Stable local problem with vanishing trace on the boundary. Decouples from boundary geometry.
eq. 6.25 — vertex scalar duality
eq. 6.31 — Whitney edge tangential
eq. 6.36 — Raviart–Thomas face flux
The discrete operators {grad, curl, div} and the projectors {Π⁰, Π¹, Π², Π³} commute term-by-term on every mesh.
Algorithm and analysis from Ern, Guzmán, Potu (2026) — arXiv:2604.28103.
The bundled playground runs the full library in your browser. Rotate the mesh, change the function, change the form degree, and watch the L² error converge as you refine the mesh.
3D tetrahedral viewer
Inspect the projected field on a live rotating mesh.
Five canonical test functions
Sincos, quadratic, linear, trig, exponential.
Convergence plot
L² error vs. mesh size, h = 1/n on the unit cube.
API surface
The whole public surface fits on a postcard. No event emitters, no stream lifecycle, no hidden state — every call is deterministic and side-effect-free.
Read the full API referencenew Projector(mesh, whitney, opts)Orchestrates the four form-degree projectors and precomputes everything you need.
projector.projectH1(u, point, p)Project onto P¹ at any point inside the unit cube. Returns the scalar field value.
projector.projectHcurl(u, point, p)Project onto the Nédélec edge element space. Returns a 3-vector field.
projector.projectHdiv(u, point, p)Project onto the Raviart–Thomas face element space. Returns a 3-vector field.
projector.projectL2(u, point, p)Project onto cell-wise constants. Bounded in L² norm.
projector.projectAtPoint(u, point, p)Project at any 3D point. AABB point location handled internally.
By the numbers
Everything you need to evaluate traceprojector before you import it. No marketing gymnastics, no inflated benchmarks.
Passing test cases
Mocha + Chai across the full surface
Runtime dependencies
Hand-rolled linear-algebra kernel
Point-in-tet lookup
Balanced AABB tree
Discrete de Rham complex
Π⁰ · Π¹ · Π² · Π³
Spin up the playground, pick a function, and watch the trace projectors do their thing on a live tetrahedral mesh — all in your browser, no install required.
⌘ npm install traceprojector