A lightweight, dependency-free Python package for parsing ASCII Gmsh MSH files
Project description
gmshparser — parse Gmsh .msh files
gmshparser is a small, dependency-free Python package for reading ASCII Gmsh MSH files. It provides a modern immutable API for normal application code while retaining the original parser-oriented API for backward compatibility.
- Python: 3.12 or newer
- MSH formats: 1.0, 2.0, 2.1, 2.2, 4.0, and 4.1
- Core dependencies: none
- Typing: PEP 561 inline type information through
py.typed - Scope: reading meshes; writing and binary MSH files are not supported
Project links:
Installation
Install the stable release with uv:
uv add gmshparser
or with pip:
pip install gmshparser
Install the current development version directly from GitHub:
uv add "gmshparser @ git+https://github.com/ahojukka5/gmshparser.git"
Entry points
The original top-level entry point is intentionally unchanged:
| Call | Result |
|---|---|
gmshparser.parse(path) |
original mutable compatibility Mesh |
gmshparser.read(path) |
modern immutable ModernMesh |
gmshparser.api.parse(path) |
modern immutable Mesh in the explicit modern namespace |
This means existing applications using gmshparser.parse() continue to behave
exactly as before.
Pythonic API
Use read() for ordinary new code:
import gmshparser
mesh = gmshparser.read("mesh.msh")
print(mesh.version, len(mesh.nodes), len(mesh.elements))
Applications that prefer the verb parse can opt into the modern namespace:
from gmshparser.api import parse
mesh = parse("mesh.msh")
Collections iterate over value objects and use original Gmsh tags for lookup:
for node in mesh.nodes:
print(node.tag, node.x, node.y, node.z)
node = mesh.nodes[42]
element = mesh.elements[17]
Elements link directly to their nodes and expose a typed element kind:
from gmshparser import ElementType
triangles = mesh.elements.by_type(ElementType.TRIANGLE)
for triangle in triangles:
print(triangle.tag, triangle.element_type, triangle.node_tags)
for node in triangle:
print(node.coordinates)
Entity context is available without separate node and element block APIs:
surface = mesh.entity(dimension=2, tag=7)
print(len(surface.nodes), len(surface.elements), surface.element_types)
print(mesh.surfaces)
print(mesh.volumes)
Physical groups
Named and anonymous physical groups are available directly from the modern
model. Names from $PhysicalNames and assignments from MSH 1.x, 2.x, and 4.x
are retained:
walls = mesh.physical_groups["Walls"]
domain = mesh.physical_groups[(3, 2)]
for element in walls.elements:
print(element.tag, element.physical_tags)
print(walls.entities)
print(walls.nodes)
A convenience method also accepts a name or a numeric tag:
walls = mesh.physical_group("Walls")
domain = mesh.physical_group(2, dimension=3)
read() accepts filesystem paths, Path objects, and open text streams. See the
Pythonic API guide
for the complete model.
Periodic meshes
Periodic entity relations from MSH 2.x and 4.x are available through the modern model:
link = mesh.periodic_links[(2, 7)]
print(link.master_entity_tag, link.affine_transform)
for slave_node_tag, master_node_tag in link.node_pairs:
print(slave_node_tag, master_node_tag)
The compatibility model exposes the same records through
get_periodic_link() and get_periodic_links().
NumPy interoperability
NumPy support is optional:
uv add "gmshparser[numpy]"
Convert the modern mesh into detached array data:
import gmshparser.numpy as gnp
from gmshparser import ElementType
arrays = gnp.to_numpy(mesh)
triangles = arrays.cells[ElementType.TRIANGLE]
triangle_points = arrays.points[triangles.connectivity]
triangle_node_tags = arrays.cell_node_tags(ElementType.TRIANGLE)
Cell connectivity contains zero-based rows into arrays.points. Original Gmsh
node tags, element tags, and entity keys remain available alongside the arrays.
Mixed meshes are represented as rectangular cell blocks grouped by element type.
Structured parser errors
Both entry points expose the same error hierarchy and source context:
try:
mesh = gmshparser.read("broken.msh")
except gmshparser.ParseError as error:
print(error)
print(error.filename)
print(error.line_number)
print(error.section)
print(error.line)
A typical message is:
broken.msh:127 [$Elements]: Element 42 requires 3 nodes, got 4
Specific errors include UnsupportedVersionError,
UnsupportedBinaryFormatError, UnexpectedEndOfFileError,
InvalidNodeError, InvalidElementError, and
InvalidElementConnectivityError. Every ParseError is also a ValueError, so
existing broad handlers continue to work. The parser does not print failures to
stdout or stderr.
See the error-handling guide for the full hierarchy and recovery examples.
Compatibility API
Existing applications using the original mutable get_* / set_* model can
continue unchanged:
legacy_mesh = gmshparser.parse("mesh.msh")
for entity in legacy_mesh.get_node_entities():
for node in entity.get_nodes():
print(node.get_tag(), node.get_coordinates())
The parser detects the MSH version automatically in both APIs.
Command-line interface
The installed gmshparser command can print a mesh summary, nodes, or elements:
gmshparser mesh.msh info
gmshparser mesh.msh nodes
gmshparser mesh.msh elements
gmshparser --version
nodes output begins with the node count, followed by
node_id x y z. elements output begins with the element count, followed by
element_id element_type connectivity....
Visualization helpers
Matplotlib is optional. Helpers accept both the modern and compatibility mesh models:
import gmshparser
import matplotlib.pyplot as plt
mesh = gmshparser.read("mesh.msh")
X, Y, triangles = gmshparser.helpers.get_triangles(mesh)
plt.triplot(X, Y, triangles)
plt.axis("equal")
plt.show()
Install the optional dependency separately:
uv add matplotlib
Development
The repository uses uv and intentionally does not commit dependency lock files. Ruff provides formatting and linting, while mypy validates both the package and a strict downstream public-API example.
git clone https://github.com/ahojukka5/gmshparser.git
cd gmshparser
uv sync
uv run ruff format --check gmshparser tests examples benchmarks
uv run ruff check gmshparser tests examples benchmarks
uv run mypy gmshparser
uv run mypy --strict tests/typing/public_api.py
uv run pytest
Build the documentation with:
uv sync --group docs
uv run mkdocs build --strict
See the Contributing guide for dependency groups and the release workflow.
License
gmshparser is released under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gmshparser-0.4.0.tar.gz.
File metadata
- Download URL: gmshparser-0.4.0.tar.gz
- Upload date:
- Size: 34.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
694654dd2972596321dfbeb3049a5e03f7d9ac3cb2098af7920d1e8f422e4134
|
|
| MD5 |
0b2146953349f319561e72546383d355
|
|
| BLAKE2b-256 |
ef65cecea2baa6c586bf7317565f42d601d4fcc410b05007d79821b6d1881f44
|
File details
Details for the file gmshparser-0.4.0-py3-none-any.whl.
File metadata
- Download URL: gmshparser-0.4.0-py3-none-any.whl
- Upload date:
- Size: 47.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b49835e4651adac0f472bd2c870d41a8519f3178620c8cd7917d1e40c6ae8019
|
|
| MD5 |
80fa60fb911094eb4a2dda6b75dfd59c
|
|
| BLAKE2b-256 |
9fb9c1caf00a619261d280bf34198feff6fd515231452efd08d63140a210865d
|