Skip to main content

Fast 2D mesh library for hydrodynamic domains — Python API with optional C++ acceleration

Project description

CHILmesh pipeline — peel layers → quality → truss → FEM smooth → peel layers

CHILmesh

Fast 2D mesh processing, smoothing, and analysis for triangular, quadrilateral, and mixed-element meshes. Intended for hydrodynamic domains.

Dominik Mattioli1†, Ethan Kubatko2
Corresponding author | 1Unaffiliated | 2Ohio State University (The CHIL)

PyPI Python 3.10+ Tests Open issues DOI License

MATLAB users: This Python library is the actively-developed successor to the original MATLAB codebase. The original (no longer maintained) is at src/@CHILmesh/CHILmesh.m and on MATLAB File Exchange


Table of Contents

Status & Roadmap

Current status (June 2026): Stable and actively-maintained. C++ half-edge backend (up to ~15× faster on full init); bit-identical output verified; cross-backend equivalence tests across C++ and Rust; fort.14 + .2dm + fort.13 I/O; mixed-element support; full mesh-mutation API (split/swap/merge/collapse, #94); lazy header-only summary().

  • Now: Pre-built binary wheels (cibuildwheel, manylinux/macOS/Windows); Rust layer-peel completion (#163).
  • Next: performance optimization; parallelization; conda-forge packaging; mkdocs API site; native .chil file format
  • Future: formal integration within a unified ecosystem including ADMESH PyPI version and QuADMESH PyPI version

Why CHILmesh

The stable backbone for hydrodynamic mesh generation & tooling.

  • Pythonic APIfrom chilmesh import Mesh; backwards-compatible CHILmesh alias preserved.
  • C++ acceleration, bit-identical output — half-edge extension is up to ~15× faster than pure Python on full init (8.6× on the 272k-element ENPAC mesh below), verified bit-for-bit by the cross-backend equivalence suite (76 tests across C++ and Rust backends).
  • One interface for all topologies — triangles, quadrilaterals, and mixed meshes share the same call surface.
  • Stable v1.x API — downstream projects can pin chilmesh>=1.0,<2.

Installation

pip install chilmesh                        # PyPI
uv pip install chilmesh                     # uv
conda install -c conda-forge chilmesh       # conda-forge (pending)
pip install -e .                            # from source

Backends & the PyPI wheel. The published PyPI wheel is currently pure-Python — it does not bundle the compiled C++/Rust extensions, so a plain pip install chilmesh runs the (correct, but slower) Python backend and chilmesh.backend_info() reports available: ['python']. The C++/Rust speedups advertised below require a source build of the extension (pip install ./src/chilmesh_cpp with a C++ toolchain; cargo build --release in src/chilmesh_core for Rust). Pre-built binary wheels are tracked in #229.


Quick Start

from chilmesh import Mesh

mesh = Mesh.read_from_fort14("ocean.14")
mesh.smooth_mesh(method="fem", acknowledge_change=True)
quality, angles, stats = mesh.elem_quality()
mesh.plot_quality()

The legacy chilmesh.CHILmesh import is preserved for backward compatibility. Built-in fixtures live at chilmesh.examples.{annulus, donut, block_o, structured}(). See examples/ for runnable scripts.


Features

  • Fast — C++ backend full-inits the 531,680-element ENPAC2003 mesh in ~1.4 s — 8.6× over pure Python (up to ~15× on smaller meshes)
  • Mixed-element — triangles, quads, and mixed meshes share one API
  • Smoothing — Balendran direct FEM, Zhou-Shimada angle-based, and ADMESH Spring-Based Truss
  • Analysis — element quality, interior angles, layer-based decomposition (peel_layers)
  • I/OADCIRC .fort.14 and SMS Aquaveo .2dm read/write
  • Spatial queries — point-in-element, k-nearest vertices, radius search at O(log n)
  • Mesh alterations — advancing-front element addition (add_advancing_front_element), coordinate moves; full mutation suite tracked in #94
  • Valence integrationfrom_admesh_domain() adapter

Performance

Reference workload: EasternPacific_ENPAC2003 — 272,913 vertices · 531,680 elements · 75 layers, from the Valence registry. Medians of 3 runs, single machine, chilmesh 1.2.2.

Stage MATLAB (Octave) ‡ Python C++ Rust
Fast init (adj, no peel) 2.738 s 6.454 s 0.769 s tbd
Peel only 12.771 s 5.814 s 0.669 s tbd
Full init (adj + peel) 16.677 s 12.300 s 1.438 s tbd
Quality (signed area) 75 ms 51 ms 7 ms tbd

Like-for-like: every backend runs the same operation on the same in-memory arrays. No fort.14 parse, signed-area quality. All resolve n_layers = 75; Python↔C++ layers are bit-identical (test_backend_equivalence.py).

  • C++ leads every stage — full init 8.6× over Python, 11.6× over Octave.
  • Octave builds adjacency 2.4× faster than Pythonsparse()-accumulated, in compiled built-ins.
  • Python peels 2.2× faster than Octave — ~26% ahead on full init overall.
  • Rust — the layer peel matches Python on n_layers, layer-member sets (OE/IE/OV/IV), per-layer bEdgeIDs (full-mesh edge IDs, ascending), full-mesh Edge2Vert/Vert2Edge ordering, and signed areas — verified by the rust-equivalence CI job across all four fixtures incl. block_o (#163). Perf is now measured (the ENPAC cells above stay tbd — that mesh lives outside the repo): on the bundled fixtures Rust full-inits ~3–5× faster than Python but ~2–5× slower than C++. Its get_vertex_edges query path was O(n) per call (rebuilt the edge list each call); that defect is now fixed — the vertex→edge index is cached, so queries are O(1) (Block_O 954 μs → 0.32 μs, 76/76 equivalence tests still pass). Full data, methodology, the "should Rust replace Python anywhere?" analysis, and the default-backend/opt-in discussion: docs/RUST_EVALUATION.md. Bottom line: C++ remains the acceleration path; Rust earns no perf niche over it.

‡ Octave 8.4, interpreter. Times are in-memory compute only — fort.14 parse and rendering excluded. Machine-dependent. Full method: docs/BENCHMARK.md.

EasternPacific_ENPAC2003 quality plot and distribution
Figure 1. Scale demo on EasternPacific_ENPAC2003 (272,913 vertices · 531,680 elements). plot_quality() renders per-element skew quality; plot_quality_histogram() emits the matched-colormap distribution beneath. Reproduce: python scripts/generate_enpac_showcase.py.

Full pipeline cost (parse · adjacency · peel · spatial-index · quality · render — render dominates), the cross-backend layer-parity catalog (557 → 273k vertices), and mesh-quality metrics: docs/BENCHMARK.md. The layer peel is distinct from medial axis / skeleton / distance — docs/CONCEPTS.md:

distance field vs medial axis vs skeleton vs layers
Figure 2. Related, not identical — distance is a scalar field; its ridge is the medial axis; the skeleton is a thinned discrete curve; layers are concentric element bands (what CHILmesh peels). Full write-up: docs/CONCEPTS.md. Reproduce: python scripts/illustrate_mesh_concepts.py.

Smoothing

Three algorithms — each preserves boundary nodes, leaves topology unchanged, and accepts mixed-element meshes.

Algorithm API call Style Best for
Balendran direct FEM smooth_mesh(method='fem') One-shot sparse solve General-purpose default; stable on tri/quad/mixed
Zhou-Shimada angle-based smooth_mesh(method='angle-based') Iterative, angle-maximising Difficult mixed meshes where FEM stalls
ADMESH Spring-Based Truss smooth_mesh(method='sdf', sdf=...) Spring/force relaxation against SDF Quality gains with SDF-respecting boundary nodes (triangle-only)

Backends

pip install chilmesh gives you the pure-Python implementation — zero compiled dependencies, runs everywhere, and is the canonical reference every other backend is validated against. The C++ extension is the high-performance opt-in: same algorithms, bit-identical output, up to ~15× faster on full init.

Language Role How to get it
Python Reference implementation — the default pip install chilmesh
C++ High-performance backend (half-edge) — bit-identical output pip install ./src/chilmesh_cpp (or bash scripts/build_cpp.sh)
Rust ❄️ Frozen (experimental quad-edge); output-equivalent to Python (rust-equivalence CI, all 4 fixtures incl. block_o) but not developed further. Measured ~2–5× slower than C++ on full init (queries were O(n)/call, now cached to O(1)) — docs/RUST_EVALUATION.md concludes it earns no perf niche over C++ source build, not recommended
MATLAB Original 2017 implementation, archived & unmaintained src/@CHILmesh/CHILmesh.m
import chilmesh

chilmesh.backend_info()
# After a source build of the C++ extension:
# {'available': ['cpp', 'python'],
#  'selected': 'cpp',
#  'versions': {'cpp': '0.6.0.dev0', 'python': '1.2.2'}}

PyPI installs are pure-Python. The example above reflects a source build of the C++ extension. A plain pip install chilmesh from PyPI currently ships no compiled extension, so backend_info() reports {'available': ['python'], 'selected': 'python'} (#229). Build from source (pip install ./src/chilmesh_cpp) for the C++ path until pre-built binary wheels land.

How the backend is chosen. When CHILMESH_BACKEND is unset, CHILmesh auto-selects the fastest available backend, in order C++ → Rust → Python — so a build that has only the Rust extension will use Rust over Python automatically. Force one with CHILMESH_BACKEND=python|cpp|rust, and check what's active with chilmesh.backend_info().

Opt-in reality — both compiled backends are source builds. Neither C++ nor Rust ships in the PyPI wheel, and Rust is not a lighter-weight opt-in than C++: C++ needs a C++ toolchain + CMake (pip install ./src/chilmesh_cpp), Rust needs a Rust toolchain (maturin build …). Until pre-built binary wheels land (#229), a plain pip install chilmesh runs pure-Python everywhere. If you build one, build C++ — it is the recommended accelerator (~5× faster than Rust on full init, bit-identical output); the Rust backend is frozen (kept and output-equivalent, but not developed further — docs/RUST_EVALUATION.md explains why it earns no niche over C++ and should not replace Python). The path to making C++ the zero-opt-in default is prebuilt binary wheels (docs/dev/PREBUILT_WHEELS_PLAN.md, #229), not switching languages. The cpp↔python bit-identity guarantee is gated in CI by the cpp-equivalence job and Rust output-parity by the rust-equivalence job, both of which build the extension and run tests/test_backend_equivalence.py. Pre-built binary wheels (manylinux / macOS / Windows) via cibuildwheel are planned — see docs/ for build-from-source instructions.

Engine

CHILmesh is a graph over the mesh — seven adjacency tables (built once) back O(1) edge lookup, O(n log n) adjacency build, O(n) peel, and O(log n) spatial queries. The C++ half-edge backend reproduces them bit-for-bit. Full table + complexities: docs/ARCHITECTURE.md.

Examples

python examples/01_quickstart.py        # load, stats, plot
python examples/02_fort14_roundtrip.py  # fort.14 read/write
python examples/03_smoothing.py         # angle-based smoother
python examples/04_spatial_queries.py   # find_element, radius search, k-nearest

CLI

chilmesh info mesh.fort.14                                      # stats
chilmesh convert mesh.2dm mesh.fort.14                         # format conversion
chilmesh smooth mesh.fort.14 -o out.fort.14 --method fem       # smooth in-place
chilmesh plot mesh.fort.14 -o mesh.png --quality               # render

Also available as python -m chilmesh. Each subcommand has --help.


Documentation

  • docs/API.md — full API reference
  • docs/BENCHMARK.md — benchmark methodology and raw data
  • docs/CONCEPTS.md — distance vs medial axis vs skeleton vs layers (definitions, algorithms, math, synonyms)
  • tests/TESTING.md — test guide (pytest markers, local commands)
  • examples/ — runnable scripts (quickstart, fort.14 round-trip, smoothing, spatial queries)

Citation

CHILmesh originated in MATLAB as the data structure backing a layer-peel-driven indirect tri-to-quad conversion heuristic (Mattioli, OSU MSc Thesis, 2017) QuADMESH Thesis

@software{mattioli_chilmesh,
  author    = {Mattioli, Dominik O. and Kubatko, Ethan J.},
  title     = {{CHILmesh}: a fast 2D mesh library for triangular,
               quadrilateral, and mixed-element grids},
  year      = {2026},
  publisher = {Zenodo},
  version   = {1.2.2},
  doi       = {10.5281/zenodo.20263854},
  url       = {https://github.com/domattioli/CHILmesh}
}

Thesis source (Mattioli, 2017). Read thesis (PDF)

@mastersthesis{mattioli2017quadmesh,
  author = {Mattioli, Dominik O.},
  title  = {{QuADMESH+}: A Quadrangular ADvanced Mesh Generator
            for Hydrodynamic Models},
  school = {The Ohio State University},
  year   = {2017},
  url    = {http://rave.ohiolink.edu/etdc/view?acc_num=osu1500627779532088}
}

Contributing

Issues and PRs welcome at github.com/domattioli/CHILmesh. Run pytest -v before opening a PR — see tests/TESTING.md.


License

Noncommercial / research use only. Licensed under the PolyForm Noncommercial License 1.0.0 with an additional No-AI/ML-training restriction — see LICENSE and .claude/AI-USAGE.md. No commercial use and no use as AI/ML training data without a separate written license. Commercial or AI-training licenses: https://github.com/domattioli

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chilmesh-1.4.1.tar.gz (274.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chilmesh-1.4.1-py3-none-any.whl (229.9 kB view details)

Uploaded Python 3

File details

Details for the file chilmesh-1.4.1.tar.gz.

File metadata

  • Download URL: chilmesh-1.4.1.tar.gz
  • Upload date:
  • Size: 274.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for chilmesh-1.4.1.tar.gz
Algorithm Hash digest
SHA256 62f883b6568cf1a48502d8d303f39fd7008412fb157e902a347ec582ca7ab28b
MD5 417bdad611a2c356004d106852d55239
BLAKE2b-256 33b269db7f3514c082c4d39b509e411ef60274063ffdeaf484cd9916333381be

See more details on using hashes here.

File details

Details for the file chilmesh-1.4.1-py3-none-any.whl.

File metadata

  • Download URL: chilmesh-1.4.1-py3-none-any.whl
  • Upload date:
  • Size: 229.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for chilmesh-1.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ae299e46449b6ec4f0f71c025692f6cff7ddfa3d5d6e0f5eb706664b1082ec0b
MD5 ec2c23875be70d328cfd9dbbc6716897
BLAKE2b-256 ab6eb59333f967a26dd69dcb6de805913af9eee52eac71a24cc95f29cfd9c957

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page