Skip to content

snappyHexMesh Boundary Layer Toolkit

Why boundary layers matter

In cardiovascular computational fluid dynamics, the wall shear stress field is the single most clinically meaningful quantity the simulation produces. Time-averaged wall shear stress (TAWSS) and the oscillatory shear index (OSI) drive endothelial response, atherosclerosis localisation, and aneurysm growth predictions. Both quantities are computed from the velocity gradient at the vessel wall, so the accuracy of the wall-adjacent mesh directly determines whether a simulation result is trustworthy or misleading.

A standard tetrahedral or hex-dominant mesh refined only at the wall surface is not enough. To resolve the steep velocity gradient inside the viscous sublayer, the mesh must transition smoothly from large interior cells to thin, anisotropic prismatic layers hugging the wall. snappyHexMesh, the OpenFOAM mesher, supports this through its addLayers step, but generating reliable layers in patient-specific geometry is notoriously sensitive: parameters interact, the inner curvature of the aortic arch is hostile to layer growth, and the typical user has to tune a dozen knobs before the result is acceptable.

This toolkit removes that friction.

Application Overview

The snappyHexMesh Boundary Layer Toolkit is a Python-based automation tool that simplifies boundary layer meshing in OpenFOAM. Through systematic parameter studies and automatic detection, it reduces the required user inputs from 10+ parameters to just 2 essential ones. The toolkit was developed alongside the AortaCFD pipeline and validated on real patient-specific aortic geometries, so the parameter ranges reflect what actually works for cardiovascular meshes rather than synthetic benchmarks.

Status: Available - Complete toolkit with validated results

Key Features: - 90% parameter reduction through automation - Auto-detection of wall patches, interior points, and mesh parameters - Validated performance: 87-95% thickness fraction consistently - Quick iteration capability for parameter optimization

Layer segmentation example Boundary layer mesh with 10 layers, showing consistent layer thickness distribution.

Mesh configuration comparison Comparison of different layer configurations and their effect on mesh quality.

Quick Start

The toolkit operates entirely from the command line. Place your STL files in the standard OpenFOAM constant/triSurface/ directory, run a single Python script with two parameters, and it produces a complete snappyHexMeshDict with validated layer settings. The two parameters are the relative target thickness (T-rel) and the number of prismatic layers (n-layers); everything else is detected from the geometry.

Basic Usage

# Place your STL files in constant/triSurface/
#   - wall_aorta.stl (or wall.stl) 
#   - inlet.stl
#   - outlet1.stl, outlet2.stl, etc.

# Run with just 2 parameters!
python auto_layers.py --T-rel 0.35 --n-layers 5

Everything else is auto-detected: - Wall and inlet patch names - Interior point via ray-casting - Base cell size from blockMeshDict
- Outlet patches automatically

Validated Parameter Ranges

Based on systematic testing with complex vascular geometry, where T_rel = T_total/Δx_surf (total boundary layer thickness relative to surface cell size):

Layers Best T_rel Expected Thickness Fraction
2-3 0.30-0.40 90-95%
4-5 0.30-0.35 87-90%
8-10 0.20-0.25 78-84%

Installation & Setup

Prerequisites

# OpenFOAM 12
which snappyHexMesh

# Python 3.7+ with NumPy
pip install numpy

Installation Options

Option 1: Lightweight Toolkit (144KB)

Perfect if you have your own STL files:

git clone https://github.com/JieWangnk/snappy-layer-toolkit.git
cd snappy-layer-toolkit
python auto_layers.py --T-rel 0.35 --n-layers 5

Option 2: Complete Package with Test Case (7.3MB)

Includes everything + working example for immediate testing:

Download: snappy-layer-toolkit-v1.0-20250901.tar.gz

# Extract and test immediately
tar -xzf snappy-layer-toolkit-v1.0-20250901.tar.gz
cd snappy-layer-toolkit-v1.0-20250901

# 30-second demo with included geometry
./quick_start.sh

Advanced Usage

# Parameter optimization
python auto_layers.py --sweep --T-rel-range 0.2 0.5 0.05 --n-layers 5

# Quick iteration (reuse surface mesh)
python auto_layers.py --T-rel 0.30 --n-layers 5 --quick

# Manual base cell size (when blockMeshDict absent)
python auto_layers.py --T-rel 0.35 --n-layers 5 --dx-base 0.001

How It Works

1. Auto-Detection System

Patch Identification: Automatically scans constant/triSurface/ for STL files with common naming patterns (wall.stl, inlet.stl, etc.) and maps these to OpenFOAM patch names. Falls back to constant/geometry/ if triSurface/ doesn't exist.

Interior Point Calculation: Uses ray-casting with the Möller-Trumbore algorithm to find valid interior points automatically. The method:

  • Samples candidate points within geometry bounding box
  • Casts rays in multiple directions
  • Counts surface intersections (odd = inside geometry)
  • Uses majority voting for robustness
  • Sanity check: Ensures distance to nearest wall > 3·Δx (prevents boundary interference)
  • Quality assurance: Validates interior point is sufficiently far from surfaces

Mesh Parameter Detection: Extracts base cell size from blockMeshDict when available, ensuring consistency between background and layer meshes. When blockMeshDict is absent, specify base cell size with --dx-base parameter.

2. Empirical Parameter Relationships

Through systematic testing on the 0010_H_AO_H aorta model (166,708 surface triangles), the toolkit establishes validated relationships between:

  • Layer count and optimal thickness parameters
  • Surface refinement impact on thickness fraction
  • Expansion ratio stability limits

3. Geometric Validation

Feature Size Check: Before mesh generation, validates that minimum feature size exceeds first-layer height:

  • Analyzes surface geometry for narrow passages and sharp features
  • Compares against calculated first-layer thickness (T_total/layers × expansion_factor)
  • Aborts with clear error if features too small: prevents impossible layer growth
  • Suggests parameter adjustments (fewer layers or higher T_rel) when validation fails

4. Effective Layer Calculation

Calculates actual layers achieved using geometric series relationship:

N_eff = ln(1 + (ER^N - 1) × f) / ln(ER)

Where: - ER = expansion ratio - N = target layers - f = thickness fraction achieved

Usage Examples

For New Users (Conservative)

# Best success rate
python auto_layers.py --T-rel 0.35 --n-layers 3

For Production (Balanced)

# Balanced performance
python auto_layers.py --T-rel 0.30 --n-layers 5 --levels 2 3

For Research (High Resolution)

# Challenging but detailed
python auto_layers.py --T-rel 0.20 --n-layers 10 --levels 2 3

Validation Results

The validation strategy combines geometric verification (does the mesh actually have the layers it claims?) with quantitative performance reporting (what fraction of the requested boundary layer thickness was achieved?). Both metrics matter: snappyHexMesh frequently reports success while silently producing degenerate cells in high-curvature regions, so reading the log alone is not enough. The toolkit re-extracts the achieved thickness from the mesh itself and compares it to the requested target.

Layer Growth Progression

The following table summarises layer growth results across four configurations tested on a complex aortic geometry (166,708 surface triangles). Higher layer counts require lower T_rel values, and increased surface refinement improves thickness fraction:

Configuration Layers Refinement Levels T_rel Thickness Fraction
Conservative 2 1-3 0.40 95%
Balanced 6 1-3 0.30 88%
High-resolution (A) 10 1-3 0.22 72%
High-resolution (B) 10 2-3 0.22 84%

Configuration (B) demonstrates that increasing the minimum surface refinement level from 1 to 2 improves thickness fraction by 12 percentage points for the same layer count.

High-Curvature Challenges

In high-curvature regions of the aortic arch, layer growth faces fundamental geometric limitations. Despite optimised parameters (T_rel=0.22, levels 2-3), boundary layer growth fails in areas of tight curvature and complex geometry transitions. This is a geometric constraint rather than a parameter deficiency: the concave inner wall of the arch provides insufficient space for multiple prismatic layers to grow without collision Jasak 1996.

Performance Summary

Recent validation runs confirm consistent results:

  • 3 layers, T_rel = 0.35: 95.3% thickness fraction, 2.88 effective layers
  • 5 layers, T_rel = 0.35: 87.3% thickness fraction, 4.37 effective layers
  • 10 layers, T_rel = 0.20: 78.2% thickness fraction, 7.82 effective layers

Key Findings

Parameter Scaling Relationships

Thickness Scaling: T_rel values decrease from 0.40 for 2 layers to 0.22 for 10 layers, confirming that higher layer counts require proportionally lower thickness demands.

Surface Refinement Impact: Increasing surface refinement levels from 1-3 to 2-3 can improve thickness fraction by up to 17%.

Quality Preservation: All configurations maintain mesh quality criteria, showing that good boundary layers can be achieved without relaxing geometric constraints.

Fundamental Limitations

Curvature Constraints: No parameter optimization can fully overcome layer growth failure in regions of high curvature and complex geometry transitions.

Thickness Fraction Ceiling: The 78-84% thickness fraction limit for 8-10 layers reflects physical limitations rather than parameter deficiencies.

Geometric Reality: Curvature-induced layer pruning cannot be eliminated by parameter adjustment alone.

Troubleshooting

Auto-detection Issues

# Override with your patch names
python auto_layers.py --T-rel 0.35 --n-layers 5 \
    --wall-name my_wall --inlet-name my_inlet

# Custom geometry location
python auto_layers.py --T-rel 0.35 --n-layers 5 \
    --geometry-dir constant/surfaces

# Missing blockMeshDict
python auto_layers.py --T-rel 0.35 --n-layers 5 \
    --dx-base 0.0005  # Specify base cell size manually

Poor Thickness Fraction

  • Try lower T_rel (reduce by 20-30%)
  • Use fewer layers with higher T_rel
  • Increase surface refinement levels

Geometry Setup

your-case/
├── constant/triSurface/     # Primary location (OpenFOAM standard)
│   ├── wall.stl        # Main wall (auto-detected)
│   ├── inlet.stl       # Inlet boundary  
│   ├── outlet1.stl     # Outlets (auto-discovered)
│   └── outlet2.stl
├── system/
│   └── blockMeshDict   # Background mesh (optional)
└── # Run toolkit here

# Alternative: constant/geometry/ also supported for compatibility

Toolkit Components

  • auto_layers.py - Main automation script
  • scripts/generate_dicts.py - Dictionary generator with auto-detection
  • scripts/find_interior_point.py - Ray-casting point finder
  • scripts/metrics_logger.py - Thickness fraction analyzer
  • system/ - OpenFOAM template files

Limitations & Considerations

Current Limitations

  • File Naming Dependency: Requires standard STL naming conventions for auto-detection
  • Geometry Location: Searches constant/triSurface/ first, then constant/geometry/ as fallback
  • Base Cell Size: Requires either blockMeshDict or manual --dx-base specification
  • Geometry Focus: Optimized for pipe-like internal flows (vascular, industrial)
  • OpenFOAM Version: Tested with OpenFOAM 12
  • Complex Topologies: External flows or unusual geometries may need different approaches

Physical Constraints

  • High Curvature Regions: Will always present challenges for excessive layer counts
  • Layer Count Limits: Diminishing returns above 10 layers due to geometric constraints
  • Surface Quality Dependency: Input STL quality affects final mesh quality

Integration Notes

This toolkit complements cardiovascular CFD workflows by: - Providing reliable boundary layer generation for vessel geometries - Reducing the expertise barrier for mesh generation - Enabling systematic parameter studies and optimization - Supporting both research and production applications

Resources & Documentation

  • GitHub Repository - Complete source code and examples
  • Validation Geometry - Vascular Model Repository data used for testing
  • OpenFOAM Integration - Compatible with standard OpenFOAM workflows

Citation

If you use this toolkit in your research, please cite:

@software{snappy_layer_toolkit_2025,
  title={snappyHexMesh Boundary Layer Toolkit},
  author={Jie Wang}, 
  year={2025},
  url={https://github.com/JieWangnk/snappy-layer-toolkit}
}

Transform your boundary layer meshing from hours to minutes through systematic automation and validated parameter relationships.

Reference: Jasak 1996 — FVM error analysis (PhD thesis, Imperial College).

Found an issue or have a suggestion for this page?

Open a GitHub issue