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
Six 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, a 3-/4-block C-grid for sharp-/blunt-TE bodies (airfoils, hydrofoils) with auto TE detection and downstream wake branches, conformal C-grid wing-tip caps, a 12-block OH hybrid that extends the cubed-sphere wrap with a structured H-channel out to a Cartesian bounding box, and a 12-/14-block CH hybrid that does the same for C-grid airfoils with a chord/normal-aligned far-field frame. Five are driven straight from shore mesh --topology cubed_sphere|ogrid|cgrid|ch|oh (the wing-tip caps are Python-API only, plus the dedicated shore cap-tip command). 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
Twenty-one 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

# Need an STL?  Generate one analytically:
shore profile naca 0012 -o naca0012.dat                    # 2D Selig section
shore body extrude --section naca0012.dat --span 1.0 -o naca0012.stl  # 3D wing
shore body sphere --radius 1.5 -o sphere.stl               # primitive bodies

# 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

The fastest path on Linux / macOS / WSL — installs SHORE in an isolated pipx venv with the shore CLI on your PATH:

curl -fsSL https://raw.githubusercontent.com/szaghi/shore/main/install.sh | bash

Or, equivalently, with pipx directly:

pipx install shore-mesh

Or, with pip inside a virtual environment (when you want import shore from your own scripts):

python -m venv .venv && source .venv/bin/activate
pip install shore-mesh

The PyPI distribution name is shore-mesh. The Python import name and CLI entry point both stay shoreimport 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   # 999 passing (~1 min, coverage ~85%)

Using SHORE with Claude Code

This repo ships a Claude Code skill at .claude/skills/shore/ that teaches the agent how to operate the shore CLI end-to-end — topology choice, the spacing knobs, and the full STL → mesh → Xall-bundle (grd / cc-par / proc-input) workflow, including the argument-order gotchas. Claude Code discovers it automatically when you open this repository.

To make it available in every project (so you can drive shore from any directory), copy it into your user skills directory:

cp -r .claude/skills/shore ~/.claude/skills/shore

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 — with both Python (examples/05-chimera-assembly/chimera_assembly.py) and bash (chimera_assembly.sh) reference scripts — is at the cc.par + boxes pipeline guide.

CLI reference

Twenty-one commands, grouped by purpose:

Group Commands
Mesh generation shore mesh, shore primitive, shore project
Body generation shore profile, shore body
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 + 3-/4-block C-grid + 12-/14-block CH hybrid + 12-block OH hybrid (all via shore mesh --topology)
  • 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.1.tar.gz (340.9 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.1-py3-none-any.whl (256.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: shore_mesh-0.1.1.tar.gz
  • Upload date:
  • Size: 340.9 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.1.tar.gz
Algorithm Hash digest
SHA256 959a3bcf855bd07cbdf3c567bd536a05bdc91836e755f76b88996a47ecb6266a
MD5 3533ad8d23cd2e7395312ac933a9dda3
BLAKE2b-256 bc9b0fc46d4d365c3feca573eca309d78a34fa0976b62406f536f3912d5ca043

See more details on using hashes here.

Provenance

The following attestation bundles were made for shore_mesh-0.1.1.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.1-py3-none-any.whl.

File metadata

  • Download URL: shore_mesh-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 256.4 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 49d0f28a34ec7fd32fca92c121c6f63f55b8b6afe6aa62925646112c223aa6e8
MD5 7e1868d5d131d51acfee7f67428bea49
BLAKE2b-256 d1103d88b3e857e2bfe68ce606d67e687774e991fbe12c0c3fe8e6d87d07824e

See more details on using hashes here.

Provenance

The following attestation bundles were made for shore_mesh-0.1.1-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