Skip to main content

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

Project description

CHILmesh pipeline — raw → smoothed → layerized

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; 36 cross-backend equivalence tests; 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 skeletonization 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 36 cross-backend equivalence tests.
  • 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 (layerize)
  • 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 layerize) 2.738 s 6.454 s 0.769 s tbd
Layerize only 12.771 s 5.814 s 0.669 s tbd
Full init (adj + layerize) 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 layerizes 2.2× faster than Octave — ~26% ahead on full init overall.
  • Rust — skeletonization now 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); only perf timings (tbd) remain open.

‡ 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 · layerize · spatial-index · quality · render — render dominates), the cross-backend layer-parity catalog (557 → 273k vertices), and mesh-quality metrics: docs/BENCHMARK.md. Layerization 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 layerizes). 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 Experimental (quad-edge); skeletonization reaches full n_layers/layer-member/bEdgeIDs/edge-ordering parity with Python (rust-equivalence CI, all 4 fixtures incl. block_o), perf timings still open — see #163 source build, not recommended yet
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.

Force a specific backend with CHILMESH_BACKEND (python or cpp). When unset, the fastest available is picked. The cpp↔python bit-identity guarantee is gated in CI by the cpp-equivalence job (ubuntu), which builds the extension and runs 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) layerize, 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 skeletonization-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.3.0.tar.gz (257.2 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.3.0-py3-none-any.whl (215.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for chilmesh-1.3.0.tar.gz
Algorithm Hash digest
SHA256 cb824303e49ef402a648008cd6c16f961d9a9b66599968f7be8fcc49dd6b2527
MD5 bdabbb19471122921d175d1d371f30e5
BLAKE2b-256 dfa52049b0e17fdac2157d718550ed995268efa204c200dafed36edf4e4dc9ae

See more details on using hashes here.

File details

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

File metadata

  • Download URL: chilmesh-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 215.3 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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 015d3501d2c1c47ea613eee6874a3decd43948dc4b58040c8c09fba0e6800136
MD5 08a0aee42c17abd98691fdad2212e036
BLAKE2b-256 0b4b0666bdfc43d80a6d63bf198d25efa289861154846aee586e68e8e22e9177

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