OpenFOAM Mesh Generation

Category: Open-Source CAE | Revised 2026-10-02
CAE visualization for openfoam mesh theory - technical simulation diagram
OpenFOAM Mesh Generation

Theory: meshing tools and wall treatment

Overview

🙋

OpenFOAM has no GUI mesher. How are meshes made?

🎓

By instructions in text dictionaries. The basic tool is blockMesh: write vertex coordinates, block (hexahedron) divisions and grading in system/blockMeshDict to get a structured mesh. For complex shapes, blockMesh builds a box-shaped background mesh and snappyHexMesh, given STL surfaces, finishes in three stages: (1) split cells finely at surfaces and chosen regions (castellatedMesh), (2) move cell points onto the surface (snap), and (3) extrude thin cell layers from walls (addLayers). Meshes from external meshers can also be converted. Whatever the method, finish with checkMesh to look for distorted cells (non-orthogonality, skewness) and negative volumes.

Grading, first cell and y+

$$ g = r^{1/(N-1)},\qquad \Delta y_1 = h\,\frac{g-1}{g^N - 1},\qquad u_\tau = U\sqrt{C_f/2},\quad C_f = 0.073\,Re^{-1/4},\qquad y^+ = \frac{(\Delta y_1/2)\,u_\tau}{\nu} $$

r is the last-to-first cell ratio given in blockMesh simpleGrading, N the cell count, h the wall-to-centre length, Δy₁ the first cell thickness, u_τ friction velocity, C_f the channel friction coefficient (Dean's correlation) and ν kinematic viscosity. y+ is at the first cell centre.

Coffee Break Trivia

A preference for hexahedra

As its name suggests, snappyHexMesh centres OpenFOAM meshing on hexahedra. OpenFOAM's finite volume method handles arbitrary polyhedra, but hexahedra need fewer cells for the same accuracy and, aligned with the flow, add less numerical diffusion. snappyHexMesh carves a hexahedral background mesh to the geometry, keeping most cells hexahedral even for complex shapes. Only cells along the surface become polyhedra, and their quality often sets the quality of the whole mesh.

Worked examples

Air ν = 1.5×10⁻⁵ m²/s; Dean Re is based on the full 50 mm channel height, not hydraulic diameter here. For r = 1, Δy₁ = h/N. Acceptable y+ depends on wall treatment; the buffer-layer warning is not a prohibition for every all-y+ function. Post-processing commands vary by release.

Example 1: 50 mm channel, air at 10 m/s (40 cells over the half-height)

Reynolds number 33,333, friction coefficient 0.0054, friction velocity 0.52 m/s, viscous length ν/u_τ about 29 µm.

Grading rFirst celly+Centre cellVerdict
1625 µm10.80.62 mmBuffer layer: suits neither
10158 µm2.71.58 mmSlightly coarse
4058 µm1.02.3 mmGood for wall resolution
20016 µm0.283.19 mmToo fine at wall, coarse at centre

For wall functions y+ ≈ 30 is a common target: a first cell of about 1.7 mm, or about 14 uniform cells over the half-height.

🙋

Forty uniform cells look fine and safe. Why 'suits neither'?

🎓

Because y+ ≈ 11 lies in the buffer layer, between the viscous sublayer (y+ < 5) and the log-law region (y+ > 30). Wall functions set wall shear stress assuming the first cell is in the log layer, so placing it in the buffer layer misjudges friction and heat transfer. Low-Reynolds models that resolve the wall need the first cell at y+ ≈ 1 or below, with several cells across the viscous layer, so y+ ≈ 11 is too coarse. OpenFOAM's kOmegaSST can be paired with treatments valid across all y+, such as nutUSpaldingWallFunction, but the buffer layer still carries the largest error. After solving, always map wall y+ with the yPlus utility (postProcess -func yPlus) and check it is in the intended range.

Example 2: snappyHexMesh refinement levels and layers (8 mm background)

Level01234
Cell size8 mm4 mm2 mm1 mm0.5 mm

Adding 5 layers with expansionRatio 1.2 and finalLayerThickness 0.5 (relative) at a level-3 (1 mm) wall gives, from the outside, 0.50, 0.42, 0.35, 0.29 and 0.24 mm: 1.79 mm total with a 0.24 mm first layer (y+ ≈ 4 for the Example 1 flow). For y+ ≈ 1, add layers or raise the wall refinement level.

Practical workflow

  1. Estimate friction velocity from flow conditions and set the first cell thickness for the chosen wall treatment.
  2. Build the background (or whole) mesh in blockMesh with the computed grading.
  3. Refine surfaces and key regions with snappyHexMesh and set layer count and thickness.
  4. Check non-orthogonality, skewness and negative volumes with checkMesh and fix trouble spots.
  5. After solving, check the y+ distribution and confirm results hold across two mesh refinements.
Coffee Break Trivia

“One cell at 70° non-orthogonality”

checkMesh often reports just a few cells with maximum non-orthogonality above 70°. It is tempting to ignore a few, but pressure-equation convergence is dragged by such cells, and they often seed divergence. Increasing nNonOrthogonalCorrectors in fvSolution compensates, but fixing those cells is the sure cure. checkMesh -allGeometry -allTopology writes the offending cells as a cellSet; viewing them in ParaView quickly shows which feature or setting is to blame.

Common mistakes

Mistakes and fixes

MistakeEffectFix
First cell in the buffer layerFriction and heat transfer errorsAim for y+ ≈ 1 or ≥ 30
Not checking y+Wall treatment and mesh mismatchMap it with yPlus
Layers missing in placesLocally high y+Tune layer settings and quality limits
Leaving non-orthogonal cellsPressure fails to convergeLocate via cellSet and fix
Holes or overlaps in STLInside and outside mixedCheck with surfaceCheck
🙋

I'd like to learn related topics.

Frequently asked questions

How are OpenFOAM meshes made?

Simple shapes are built from hexahedral blocks with blockMesh; complex shapes start from a blockMesh background mesh that snappyHexMesh cuts to the STL geometry, refines and adds wall layers to. Meshes from external tools (Gmsh, ANSYS Meshing, etc.) can be converted with gmshToFoam or fluentMeshToFoam. Finish by checking quality with checkMesh.

How do I size the first wall cell?

Choose y+ (wall distance divided by the viscous length) to suit the turbulence model's wall treatment: y+ ≈ 1 to resolve the wall, roughly 30–300 for wall functions. For air at 10 m/s in a 50 mm channel the viscous length is about 29 µm, so y+ ≈ 1 needs a first cell of about 58 µm (cell centre at about 29 µm).

snappyHexMesh layers aren't added properly.

Layer addition is skipped locally where there is no room to extrude along the geometry. Review the layer settings (number of layers, expansionRatio, finalLayerThickness) and the quality constraints (meshQualityControls), first reducing the layer count to see whether layers cover every surface. Confirm how many layers went onto each patch from the log or checkMesh output.

References and scope of verification

Numbers are educational reference calculations under the stated assumptions. Sources document theory and setup, not proof that these numerical values were reproduced in each package. Engineering decisions require validation for the actual conditions.

Related fields

Structural AnalysisFluid AnalysisThermal Analysis
Rate this article
Thank you for your feedback!
Helpful
More details
Report error
Helpful
0
More details
0
Report error
0