Skip to main content

SHORE — Structured Hyperbolic Overlapping Remeshing Engine

Project description

SHORE — Structured Hyperbolic Overlapping Remeshing Engine

Latest Version Build Status Coverage Supported Python versions License

Hyperbolic mesh generation for Chimera CFD — body-fitted near-body grids and parametric backgrounds, in one tool.

🏗️ Full Chimera assembly in one tool
Generate every grid an overset assembly needs — body-fitted near-body meshes and parametric backgrounds — in the same world frame. Pack them into the Xall solver bundle (.grd + cc.par + marker boxes) without leaving the SHORE CLI. Pipeline walkthrough
📐 Body-fitted near-body meshes
Three topologies for surface inputs (STL today; CAD on the roadmap) — single-block O-grid, 6-block cubed sphere with gnomonic cap k=0 seed and C1 cap-equator seam pinning, and a single-block C-grid for sharp-TE bodies (airfoils, hydrofoils) with auto TE detection and downstream wake branches. One shore mesh call from a triangulated body to Xall-compatible .geo files. Cubed sphere
🧱 Parametric backgrounds
Box, annular cylinder, and 5-block flat-caps cylinder primitives with per-axis spacing laws — fill the far field without an STL. Per-edge spacing on Box and Annulus, transfinite-interpolation blends; flat-caps cylinder is Chimera-fringe-free for GPU-friendly backgrounds. Primitives
🌊 Seam-aware hyperbolic marching
Each wall-normal layer advances along outward normals computed with centred differences across multi-block seams (ghost rows from partner blocks). Spacing continuity across block edges holds layer by layer; per-layer Laplacian smoothing + Jacobian guard catch any cell inversion immediately. Algorithm
🔍 Focused CLI
Nineteen commands cover the full chimera pipeline — generate (mesh, primitive), subdivide and balance for parallel solvers (split, balance), pack for the solver (grd, cc-par, proc-input, boxes-from-stl), merge multi-component runs (grd-merge, cc-par-merge, proc-input-merge), inspect (info, check), and visualise (export, view, boxes-export). A Rich progress bar shows per-layer Jacobians during marching. CLI reference
🎨 ParaView and Jupyter visualization
Export to VTK StructuredGrid (shore export) and MultiBlock (.vtm) for ParaView with per-cell Jacobian colour maps and overlaid marker boxes. Or use shore view for an immediate PyVista window, or shore.vis directly in Jupyter notebooks with the HTML backend. API reference
✅ Fully tested pipeline
Pytest suite covers every CLI command, geometric correctness, Jacobian inversion detection, multi-block adjacency wiring, axis-map orientation, VTK export round-trip, and geo / grd / cc.par format fidelity. Contributing
🆓 Free and open source
Released under the MIT license. Pure Python — depends only on NumPy, trimesh, Typer, and Rich. PyVista is an optional dependency for visualization. No compiled extensions, no C++ meshing backends.

Full documentation

What is SHORE?

SHORE produces every structured grid a Chimera (overset) CFD assembly needs and packages them for the solver. Two product lines, one tool:

  • Body-fitted near-body meshes by hyperbolic normal extrusion of a body surface. Surface input is a triangulated STL today; CAD (STEP / IGES / BREP) is on the roadmap.
  • Parametric backgrounds that fill the far field — no STL needed, just analytic geometry. Box, annular cylinder, and flat-caps cylinder primitives.

Hole cutting, fringe identification, and donor search are the solver's responsibility — SHORE produces every grid and every descriptor the solver needs, then steps out of the way.

# Body-fitted near-body mesh (default: 6-block cubed sphere)
shore mesh fuselage.stl --ni 60 --nj 80 --nk 40 --ds 1e-4 --growth 1.15 -o fuselage -v

# Single-block O-grid alternative (one .geo, j-periodic)
shore mesh fuselage.stl --topology ogrid --ni 60 --nj 80 --nk 40 -o fuselage

# C-grid for sharp-TE bodies (airfoil, hydrofoil) with downstream wake branches
shore mesh naca0012.stl --topology cgrid \
    --ni-body 120 --ni-wake 30 --n-stations 5 --wake-length 15 \
    --nk 30 --ds 5e-4 --growth 1.15 -o naca0012

# Parametric background — no STL needed
shore primitive flat-caps --r-out 10 --z0 -10 --z1 50 --ni 16 --nc 24 --nk 60 -o background

# Inspect
shore info fuselage_sub0.geo
shore check fuselage_sub0.geo

Quick start

Installation

pip install shore-mesh           # distribution name on PyPI
# the import / CLI name stays `shore`:
#   import shore
#   shore --help

Or from source for development:

git clone https://github.com/szaghi/shore.git
cd shore
python -m venv .venv && source .venv/bin/activate
make dev    # pip install -e ".[dev]"
make test   # currently ~588 passing

Your first body-fitted mesh

Given a body surface sphere.stl, generate a 6-block cubed-sphere mesh with 40 equator latitude points, 60 longitude points, and 30 wall-normal layers:

shore mesh sphere.stl --ni 40 --nj 60 --nk 30 --ds 1e-3 --growth 1.15 -o sphere -v

The -v flag shows a live progress bar:

⠸ Loading STL     ████████████████  1/1   5,120 triangles  0:00:00
⠸ Marching        ████████████████ 29/29  jmin=2.30e-05    0:00:00
✓ Wrote 6 .geo files  (sub: 40x16x30, caps: 16x16x30)

Validate the result:

shore check sphere_sub0.geo
✓ All Jacobians positive.

Your first parametric background

No STL required — primitives build their nodes from analytic geometry:

# 5-block flat-caps cylinder (Chimera-fringe-free; central square + 4 trapezoidal sub-blocks)
shore primitive flat-caps --r-out 10 --z0 -10 --z1 50 --ni 16 --nc 24 --nk 60 -o background
# → background_center.geo, background_sub_e.geo, background_sub_n.geo,
#   background_sub_w.geo, background_sub_s.geo

Other primitives:

shore primitive box --min -10 -10 -10 --max 10 10 50 --ni 30 --nj 30 --nk 60 -o domain
shore primitive annulus --r-in 1.5 --r-out 5 --z0 -2 --z1 2 --ni 30 --nj 64 --nk 40 -o buffer

Xall pipeline

Once each component (near-body and / or background) is generated, package it for the Xall solver:

# Pack each component into binary .grd
shore grd wall_*.geo -o wall.grd
shore grd background_*.geo -o background.grd

# Generate the chimera descriptor (consumed by overset preprocessor)
shore boxes-from-stl fuselage.stl --block sub0 --max-outward-gap 0.10 -o boxes.json
shore cc-par wall.adjacency.json wall.cc.par --grd wall.grd --boxes boxes.json
shore cc-par background.adjacency.json background.cc.par --grd background.grd --free-bc -9

# Generate the runtime work-distribution descriptor (consumed by Xall)
shore proc-input wall.grd       wall.proc.input       --np 16
shore proc-input background.grd background.proc.input --np 16

# Merge multi-component runs into a single Xall job
shore grd-merge        background.grd          wall.grd          -o assembly.grd
shore cc-par-merge     background.cc.par       wall.cc.par       -o assembly.cc.par --grd assembly.grd
shore proc-input-merge background.proc.input   wall.proc.input   -o assembly.proc.input

The full walkthrough — including the examples/05-chimera-assembly/chimera_assembly.py reference script — is at the cc.par + boxes pipeline guide.

CLI reference

Nineteen commands, grouped by purpose:

Group Commands
Mesh generation shore mesh, shore primitive, shore project
Adjacency / parallelism shore split, shore balance
Xall pipeline shore grd, shore grd-merge, shore cc-par, shore cc-par-merge, shore proc-input, shore proc-input-merge, shore boxes-from-stl
Inspection shore info, shore check
Visualisation shore export, shore view, shore boxes-export
Configuration shore config

All commands accept --help for full option lists. See the CLI reference for full documentation.

Key options for shore mesh

Option Default Description
--topology cubed_sphere cubed_sphere (6 blocks), ogrid (1 block, j-periodic), or cgrid (1 block, sharp-TE body with wake branches)
--ni 40 Latitude / equator meridional node count
--nj 60 Longitude node count (multiple of 4 for cubed sphere)
--nk 30 Wall-normal node count (includes the wall row at k=0; the marcher extrudes nk - 1 cells)
--ds 1e-3 First-layer thickness (geometric spacing)
--growth 1.15 Geometric growth ratio
--theta-cap-deg 30° Polar exclusion angle (cubed sphere)
--volume-k-spacing geometric geometric, tanh, or tanh2
--smooth 0.2 Laplacian smooth strength [0–1]
--smooth-iters 2 Laplacian sweeps per layer
-o / --output <stem> Output stem (multi-block writes <stem>_<label>.geo)
-v / --verbose off Rich progress bar

Algorithm overview

Body-fitted: surface projection + hyperbolic marching

For body-fitted meshes, SHORE runs two stages:

  1. Surface projection. The body's anchor (centroid by default) is the origin of a structured ray-cast onto the STL. The 6-block cubed sphere uses gnomonic flat-square cap projection at each pole + great-circle slerp meridians for the equator, with C1 step matching at every cap-equator seam vertex. The single-block O-grid uses a uniform lat-lon ray template. Both require the body to be star-shaped from the anchor.

  2. Hyperbolic marching. Each wall-normal layer is computed as

    $$P_{i,j}^{k+1} = P_{i,j}^{k} + \Delta s_k \cdot \hat{n}_{i,j}^{k}$$

    where $\Delta s_k$ comes from the chosen spacing law (geometric, tanh, or tanh2) and $\hat{n}$ is the outward normal. At multi-block seams, the boundary tangent uses a centred difference against ghost rows from partner blocks instead of a one-sided fallback — this is the seam-aware kernel that keeps spacing continuous across block edges layer by layer. Per-layer Laplacian smoothing and a Jacobian guard catch any cell inversion immediately.

Parametric backgrounds

Primitives build their nodes from analytic geometry — no projection, no marching. Each axis has its own spacing law (uniform / tanh / tanh2); per-edge overrides on Box and Annulus produce a transfinite-interpolation blend between the four parallel edges. The 5-block flat-caps cylinder pins its radial and tangential distributions geometrically (central square + 4 trapezoidal sub-blocks with conforming SHARED seams).

Marker boxes for hole-cutting

For chimera assemblies, SHORE generates marker boxes from the body STL via voxel-fill + greedy AABB merge: voxelise the body's AABB, include every voxel that overlaps the body, then greedy-merge face-adjacent grid blocks into slab-shaped AABBs whenever the merged corners stay within the user's max_outward_gap budget. The output is a small slab cover that contains the body and fits inside the near-mesh — both invariants enforced by construction. See Algorithm — marker boxes.

Roadmap

  • Body-fitted topologies: 6-block cubed sphere (production default) + single-block O-grid
  • Parametric primitives: box, annular cylinder, 5-block flat-caps cylinder
  • Gnomonic flat-square cap k=0 projection with C1 seam-step pinning
  • Seam-aware hyperbolic marching (centred-difference normals across block seams)
  • Per-edge spacing data model (Spacing1D, Edge.first_step/last_step, pinned law)
  • Adjacency JSON sidecar with axis_map orientation
  • Xall pipeline: .geo.grd (shore grd), chimera descriptor (shore cc-par), marker boxes (shore boxes-from-stl)
  • Multi-component merge (shore grd-merge, shore cc-par-merge) for Xall assemblies
  • PyVista visualization (shore view, shore export, shore boxes-export, shore.vis)
  • GitHub Actions CI + VitePress documentation site
  • CAD surface input (STEP / IGES / BREP via pythonOCC or cadquery)
  • Multi-block surface decomposition for non-star-shaped bodies
  • Steger–Sorenson orthogonality source term for high-curvature bodies
  • Box-shaped outer-boundary morphing (alternative to background overlap)
  • Other CFD formats (Plot3D, CGNS)

Authors

Stefano Zaghi · stefano.zaghi@cnr.it

Chief Yak Shaver, Accidental Research Scientist, and HPC Farmer — CFD researcher who decided that one more day debugging Fortran build systems was one day too many, opened a Python REPL "just to prototype," and now finds himself maintaining a meshing library, a chimera assembler, an MPI load balancer, and the seven blog tabs he keeps meaning to read.

Andrea Di Mascio · andrea.dimascio@univaq.it

Sommo Vate & Resident Gandalf — responsible for the deep CFD intuitions SHORE pretends to know.

Claude (Anthropic)

Omniscient Code Oracle & Tireless Rubber Duck — AI pair programmer, responsible for writing the boring parts so humans don't have to.

License

SHORE is released under the MIT License.

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

shore_mesh-0.1.0.tar.gz (238.4 kB view details)

Uploaded Source

Built Distribution

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

shore_mesh-0.1.0-py3-none-any.whl (181.6 kB view details)

Uploaded Python 3

File details

Details for the file shore_mesh-0.1.0.tar.gz.

File metadata

  • Download URL: shore_mesh-0.1.0.tar.gz
  • Upload date:
  • Size: 238.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for shore_mesh-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a7f07923c989a83b0870241c67d13274875b95daf0137d363604268b050e4ff5
MD5 a13fe3f3732dd62ea0e81309ed8216b3
BLAKE2b-256 912feecceae562f9bf83fb76262969e8824b98ae5f47cb582d17106f5643c79c

See more details on using hashes here.

Provenance

The following attestation bundles were made for shore_mesh-0.1.0.tar.gz:

Publisher: python-package.yml on szaghi/shore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file shore_mesh-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: shore_mesh-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 181.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for shore_mesh-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c72c8ba73b14afeb19829342b5acf6fa877df33baf7c26dcd574e2ed7b5d2d03
MD5 24b01a0e866473e024de788c8005c939
BLAKE2b-256 4036facdbd5e867e01520781dc0fa2dc4f48ba5ab59c8f3f8615bb059a37253a

See more details on using hashes here.

Provenance

The following attestation bundles were made for shore_mesh-0.1.0-py3-none-any.whl:

Publisher: python-package.yml on szaghi/shore

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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