Playground

Project any function onto the discrete 3D de Rham complex.
Π
The projection along a line through the centre
11 points on a segment through the vertex the field is centred on. The curve is the field; the dots are the operator; a red cross is a point the operator could not answer.
6.50120.0000x
Residuals
Two of the properties the papers claim, measured for the chosen operator on this mesh and field.

Press “Measure residuals”. It computes the coefficients on the boundary and on a sample of edges, which for the bounded operators takes seconds.

The same thing as a program
Runs on Node.js 24 or newer with traceprojector installed.
import { Locator, BoundedCommutingProjector } from 'traceprojector';
import { generateUnitCubeMesh } from 'traceprojector/generator';

const mesh = generateUnitCubeMesh(4);
const vertices = mesh.getVertices();
const tetrahedra = mesh.getTetrahedra();

const u = (p) => 1 / Math.sqrt(Math.hypot(p[0] - 0.5, p[1] - 0.5, p[2] - 0.5));
const projector = new BoundedCommutingProjector(vertices, tetrahedra);
const locator = new Locator(mesh);

const points = [
  [0.06, 0.513, 0.507],
  [0.148, 0.513, 0.507],
  [0.236, 0.513, 0.507],
  [0.324, 0.513, 0.507],
  [0.412, 0.513, 0.507],
  [0.5, 0.513, 0.507],
  [0.588, 0.513, 0.507],
  [0.676, 0.513, 0.507],
  [0.764, 0.513, 0.507],
  [0.852, 0.513, 0.507],
  [0.94, 0.513, 0.507],
];
for (const point of points) {
  const found = locator.findTetrahedron(point);
  if (!found) continue;
  const { tIdx } = found;
  // A ProjectError here means the operator cannot read this field.
  console.log(point.join(', '), u(point), projector.project(u, point, tIdx, 0));
}