RapidMesh

2D and 3D mesh generation for electromagnetic FEM and MoM in pure Rust.

Box minus two spheres

RapidMesh is a tetrahedral mesh generator for 3D electromagnetic FEM with a first-class 2D path for 2.5D MoM solvers, in pure Rust. Solid primitives (box, cylinder, sphere, cone, torus, prism, sweep, loft) assemble into a tagged complex; exact-arithmetic CSG booleans (exact predicates, no float snapping) produce a non-manifold B-rep with exactly conforming material interfaces. A box minus two overlapping spheres comes out watertight, with the sphere patches meshed at their own curvature.

Dielectric resonator, cutaway

Meshing is dimensionally hierarchical: corners, then edges, then faces, then the volume, freezing each level before the next consumes it. Within every dimension, error-driven adaptive sampling combines with variational point relaxation for quality: sizing-weighted Lloyd relaxation on edges and faces, optimal-Delaunay relaxation in the volume, plus sliver exudation and edge removal targeting the minimal dihedral angle. The frozen surface triangulation is a hard constraint on the volume Delaunay, which is what makes the boundary watertight by construction. The sizing and chart formulae for every curve and surface modality are derived with a computer-algebra system rather than approximated ad hoc.

Two-region via, cutaway

A coaxial step carries a conductor, a dielectric and a change of diameter. The interfaces between those regions have to be shared triangle for triangle; where they are not, the solver sees a crack that is not in the geometry.

Coaxial step, tagged regions

Meshing is budgeted: mesh(target_elements=N) retunes the global size scale over a few remeshes, since the element count scales with the third power of the scale, and lands within a few percent of N while the relative refinement from curvature and sizing keeps its shape. Surface budgets act as a cap instead: the count-driven refinement resolves the sizing field but stops at the triangle budget, split across patches by area, spending its last splits on the worst-quality triangles. Solvers can plan a mesh the way RSLAB plans a factorization: the cost is known before the run.

The 2D path

Symmetric transformer, MoM surface mesh

The same core that meshes each 3D surface patch is the standalone planar mesher for MoM: graded, sliver-free constrained Delaunay triangulation of tagged polygons with holes, with RWG edge topology derived in the same bundle. A target_count budget scales the sizing field so the mesh lands near the requested triangle count, shared across all metal layers:

import rapidmesh as rm

layers = rm.mesh_layers(groups, sizing, target_count=20_000)
# points, tris, tags, RWG edges and boundary topology per layer

Overlapping regions within a group weld into one electrically continuous component; separate metal layers never merge.

The corpus

mesh.rapidpassives.org

A corpus of 101 geometries (primitives, booleans, multi-region assemblies, RF passives, STL/OBJ imports) is re-run and re-rendered on every full run, each one checked for watertightness, manifoldness and minimal dihedral angle. The API serves the solver as an oracle: mesh representations carry exactly what FEM assembly and refinement need.

Where it stands

The 2D path is the mature one. It meshes for RapidMoM , and the count-based budget, an exact element target rather than a size hint, is something gmsh does not offer at all.

The 3D path is not at gmsh parity. Element quality holds up, but it is slower, and some geometries still leave straddler slivers along curved intersection edges, where the faceted chain sits a sagitta off the true carrier surface. RapidFEM therefore still meshes with gmsh.

What is finished is the solver side. RapidMesh is designed for mesher-in-the-loop operation rather than file exchange, and the FEM and MoM interfaces are all there: a solver asks for a mesh, gets the topology it needs from the same call, and can ask again with a different budget without leaving the process.

History

The first mesher I wrote was a 2D QuadTree in 2023, built because a quasi-electrostatic finite volume solver of mine needed one: refinement toward edges, a balanced tree, and a triangulation with Laplacian smoothing on top. It was written against one solver, which is how RapidMesh is built too.

RapidMesh started in June 2026 with one goal: replace gmsh inside the stack with a deterministic, embeddable mesher. It is the youngest part of the stack and the least finished.