query based meshing on top of GMSH
Project description
meshql
Query-based meshing on top of GMSH
About
meshql is a declarative, query-based tool for parametric mesh generation built on top of GMSH. It provides an intuitive API for creating structured and unstructured meshes with support for:
- Query-based selection: Use CadQuery-like selectors to target specific geometry entities
- Boundary layers: Automatic boundary layer generation for both 2D and 3D meshes
- Transfinite meshing: Automated structured meshing with intelligent edge/face grouping
- Physical groups: Easy boundary condition assignment with named groups
- Preprocessing: Advanced geometry splitting and partitioning for complex workflows
- Multiple formats: Export to GMSH, SU2, VTK, and other mesh formats
- Visualization: Built-in mesh and geometry visualization tools
Installation
Prerequisites
meshql requires GMSH and CadQuery. Install them first:
# Install GMSH (required)
conda install -c conda-forge gmsh python-gmsh
# Install CadQuery (required for CAD geometry support)
conda install -c conda-forge -c cadquery cadquery=master
From PyPI
pip install git+https://github.com/OpenOrion/meshql.git#egg=meshql
From Source
git clone https://github.com/OpenOrion/meshql.git
cd meshql
pip install -e ".[gmsh]"
Quick Start
Basic Example: NACA Airfoil with Boundary Layer
import cadquery as cq
from meshql import GeometryQL
from meshql.utils.shapes import generate_naca4_airfoil
# Generate NACA 0012 airfoil coordinates
airfoil_coords = generate_naca4_airfoil("0012", num_points=40)
with GeometryQL.gmsh() as geo:
mesh = (
geo
.load(
cq.Workplane("XY")
.circle(20)
.polyline(airfoil_coords)
.close()
)
# Configure airfoil surface
.edges(type="interior")
.addPhysicalGroup("airfoil")
.addBoundaryLayer(
ratio=2,
size=0.00001,
num_layers=40,
)
.setMeshSize(0.01)
.end()
# Configure farfield
.edges(type="exterior")
.addPhysicalGroup("farfield")
.setMeshSize(3.0)
.end()
.generate(2)
.show("mesh")
)
Structured Mesh with Preprocessing
import cadquery as cq
from meshql import GeometryQL, Split
with GeometryQL.gmsh() as geo:
(
geo
.load(
cq.Workplane("XY").box(10, 10, 10).rect(2, 2).cutThruAll(),
preprocess=(Split, lambda split: (
split
.from_plane(angle=(90, 90, 0))
.from_plane(angle=(-90, 90, 0))
)),
)
.setTransfiniteAuto(max_nodes=50)
.generate(3)
.show("mesh", only_surface=True)
)
3D Wing with Interior Faces
import cadquery as cq
import numpy as np
from meshql import GeometryQL
from meshql.utils.shapes import generate_naca4_airfoil
airfoil_coords = generate_naca4_airfoil("0012", num_points=40) * 5 - np.array([2.5, 0])
with GeometryQL.gmsh() as geo:
(
geo
.load(
cq.Workplane("XY")
.box(10, 10, 10)
.faces(">Z")
.workplane(centerOption="CenterOfMass")
.polyline(airfoil_coords)
.close()
.cutThruAll()
)
.faces(type="interior")
.addPhysicalGroup("wing")
.addBoundaryLayer(size=0.001, ratio=1.5, num_layers=3)
.end()
.generate(2)
.show("mesh")
)
Key Features
Selection System
Use intuitive CadQuery-style selectors to target geometry entities:
.faces(">Z") # Top faces
.edges(type="interior") # Interior edges
.solids() # All solids
.vertices() # All vertices
Meshing Operations
Boundary Layers
Automatic boundary layer generation for viscous flow simulations:
.addBoundaryLayer(
size=0.001, # First cell height
ratio=1.5, # Growth ratio
num_layers=10, # Number of layers
)
Transfinite Meshing
Automated structured meshing with intelligent parameter selection:
.setTransfiniteAuto(
max_nodes=50, # Maximum nodes per edge
min_nodes=2, # Minimum nodes per edge
auto_recombine=True, # Recombine to quads/hexes
)
Physical Groups
Assign boundary conditions with named groups:
.faces(">Z")
.addPhysicalGroup("top_wall")
.end()
.faces("<Z")
.addPhysicalGroup("bottom_wall")
.end()
Mesh Refinement
Control mesh size and algorithms:
.setMeshSize(0.1) # Set mesh size
.setMeshAlgorithm2D("Delaunay") # 2D algorithm
.setMeshAlgorithm3D("Delaunay") # 3D algorithm
.refine() # Refine mesh
.recombine() # Recombine elements
Preprocessing
Geometry Splitting
Split complex geometries for structured meshing:
preprocess=(Split, lambda split: (
split
.from_plane(angle=(90, 90, 0)) # Split by plane
.from_ratios([0.25, 0.5, 0.75]) # Split by ratios
.from_normals([(1, 0, 0), (0, 1, 0)]) # Split by normals
.from_edge(selector=">Z") # Split from edge
))
Mesh Import
Load existing meshes from various formats:
import meshly
mesh = meshly.Mesh(
vertices=vertices_array,
indices=indices_array,
markers={"boundary": [face_indices]}
)
geo.load(mesh)
Output Formats
Export to multiple mesh formats:
.write("output.msh", dim=2) # GMSH format
.write("output.su2", dim=2) # SU2 format
.write("output.vtk", dim=2) # VTK format
Visualization
Built-in visualization tools:
.show("mesh") # Show mesh
.show("mesh", only_surface=True) # Show surface only
.show("gmsh") # Open in GMSH GUI
Examples
More examples available in the examples directory:
- cube.ipynb: Basic structured meshing with boundary layers
- naca0012.ipynb: Airfoil meshing with boundary layers
- inviscid_wedge.ipynb: Inviscid flow simulation setup
- turbo.ipynb: Turbomachinery example with STEP import
- progression.ipynb: Mesh refinement progression
Documentation
- Changelog: Version history and feature releases
Development Setup
Quick Start
git clone https://github.com/OpenOrion/meshql.git
cd meshql
make install
Available Make Commands
# Install package in development mode with GMSH support
make install
# Build Python package
make build-package
# Run tests
make test
# Clean build artifacts
make clean
# Quick local build (for testing)
make build
Manual Installation
git clone https://github.com/OpenOrion/meshql.git
cd meshql
pip install -e ".[gmsh]"
Contributing
We welcome contributions! Please check out the Discord for discussions and collaboration.
Support
- Discord: Join our community
- Issues: Report bugs or request features
Tutorial
Video tutorial available:
latest: https://www.youtube.com/watch?v=7skc6wjwoTk
v1: https://www.youtube.com/watch?v=ltbxRsuvaLw
License
MIT License - see LICENSE file for details.
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 meshql-2.0.0.tar.gz.
File metadata
- Download URL: meshql-2.0.0.tar.gz
- Upload date:
- Size: 42.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93d303048570d2e1e9562124d3acd556f76a19263254379cc54ad24995ec0ab6
|
|
| MD5 |
2a8fd78d83e57a824d44be7b8c06aab4
|
|
| BLAKE2b-256 |
fe818cfdbf431ea11a3978a23b2e4c9ed5ecb6f7623694b6b9241ff6a6b68da4
|
File details
Details for the file meshql-2.0.0-py3-none-any.whl.
File metadata
- Download URL: meshql-2.0.0-py3-none-any.whl
- Upload date:
- Size: 48.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46d4820e57eaf673390994a57b8088fa40831184228e5f1638e59dbec49f928a
|
|
| MD5 |
e12a8be68b2162d1f7710a70e094fac7
|
|
| BLAKE2b-256 |
223acaac9b82929f35c5ded18113d8ba2723a4b8b8e75489669bb89701e41d6a
|