---
title: Imported meshes
summary: A mesh read from a Gmsh or NPZ file must behave exactly like a generated one. The study reads genuine Gmsh files, tests the node-ordering tables, the operator identities on unstructured curved meshes in 2-D and 3-D, and solves a flow with an adjoint derivative on an imported mesh.
section: verification
order: 11
level: 2
study: imported_mesh
keywords: [Gmsh, mesh import, unstructured, face orientation, node ordering, NPZ]
---
<!-- gyre docs: expanded Markdown of verification/imported-meshes.md (generated tables, verification numbers and chart data are written out). Base level of this page: L2 Practice; passages at another level are bracketed by 'begin level N' / 'end level N' comments and start with [LN Name]. Built from revision ceb1f4b0be. -->

**Verification status: Imported meshes** (study `imported_mesh`): **PASSED**, 29 of 29 checks passed, 184.5 s.

A mesh read from a file must behave exactly like a generated one, including unstructured topology, where neighbouring elements use different local axes. (i) Every Gmsh fixture of the test suite is read; the files are genuine Gmsh output (tools/make_mesh_fixtures.py), and on the straight-sided ones every high-order node must be the multilinear image of the element's vertices, which tests the node-ordering tables for quadrilaterals of degree 1 to 5 and hexahedra of degree 1 to 4. (ii) On curved unstructured meshes from Gmsh in 2-D and 3-D, and on a 3-D mesh whose elements were randomly re-oriented and passed through a file, a uniform flow must remain steady, the residuals of a perturbed state must sum to zero, and the inviscid residual of a continuous state must not depend on the Riemann solver away from the boundary (the jump across every face is zero only if its nodes are matched with the right ones of the neighbour; the viscous terms cancel in this comparison, so it is made for the Euler equations only). The coupling of the viscous terms across faces (gradient traces of the neighbour, lifted jumps) is tested separately, for both sets of equations: a rough state with varying velocity and temperature and a jump on every face must give the same residual, node by node, when every element of the mesh is stored in other, randomly chosen local axes. (iii) The coarse annulus of the cylinder case, written to a Gmsh file after randomly re-orienting its elements and read back through a case specification, must give the force coefficients of the generated mesh to solver tolerance. (iv) Laminar flow past a cylinder in a channel (Re = 40, M = 0.2, slip walls) is solved on the unstructured example mesh at degree 2, and the adjoint derivative of the drag coefficient with respect to the Mach number is compared with a central finite difference of re-converged flows.

| Check | Value | Expected | Result |
|---|---|---|---|
| usable Gmsh fixtures read | 15 of 15 | all | pass |
| unusable Gmsh fixtures (triangles, binary, untagged) refused with a message | 3 of 3 | all | pass |
| straight-sided fixtures cover quadrilaterals of degree 1–5 and hexahedra of degree 1–4 | 9 | = 9 (dimension, degree) pairs | pass |
| node ordering: largest distance of a node of a straight-sided mesh from the multilinear map of its vertices | 4.4409e-15 | < 1e-13 (round-off; coordinates of order one) | pass |
| straight-sided meshes: relative error of the area / volume | 3.0585e-16 | < 1e-12 (the quadrature is exact for multilinear elements) | pass |
| every straight-sided fixture is unstructured: fewest face pairs with a non-identity orientation | 44 | > 0 | pass |
| curved quadrilateral meshes (circular hole): area error at geometry degree pg + 1 relative to pg, largest | 0.147256 | < 1 (the boundary interpolant converges with the degree) | pass |
| MSH 2.2 and MSH 4.1 files of one periodic mesh: largest node difference | 0 | < 1e-12 | pass |
| periodic node pairs of the file became topology (slave nodes) | 13 | > 0, and no boundary group on the periodic sides | pass |
| hole_quad_p3.msh (Gmsh, curved, 2-D), inviscid: perturbed state is not trivial (max \|Rw\|) | 0.415774 | > 1e-3 | pass |
| hole_quad_p3.msh (Gmsh, curved, 2-D), viscous: perturbed state is not trivial (max \|Rw\|) | 0.435898 | > 1e-3 | pass |
| hole_quad_p3.msh (Gmsh, curved, 2-D): face pairs with a non-identity orientation | 48 | > 0 | pass |
| hole_hex_p2.msh (Gmsh, curved, 3-D), inviscid: perturbed state is not trivial (max \|Rw\|) | 0.620272 | > 1e-3 | pass |
| hole_hex_p2.msh (Gmsh, curved, 3-D), viscous: perturbed state is not trivial (max \|Rw\|) | 0.306193 | > 1e-3 | pass |
| hole_hex_p2.msh (Gmsh, curved, 3-D): face pairs with a non-identity orientation | 72 | > 0 | pass |
| periodic warped 3x3x3 box, re-oriented, written and read back, inviscid: perturbed state is not trivial (max \|Rw\|) | 0.115116 | > 1e-3 | pass |
| periodic warped 3x3x3 box, re-oriented, written and read back, viscous: perturbed state is not trivial (max \|Rw\|) | 0.120425 | > 1e-3 | pass |
| periodic warped 3x3x3 box, re-oriented, written and read back: face pairs with a non-identity orientation | 74 | > 0 | pass |
| re-oriented 3-D box read from a file: relative face orientations present | 8 | = 8 (all) | pass |
| free stream on imported meshes: largest max \|Rw\| | 4.4409e-15 | < 1e-12 | pass |
| conservation on imported meshes: largest \|sum of Rw\| of a perturbed state | 1.3767e-14 | < 1e-12 (residuals of order 0.1 to 1) | pass |
| neighbour matching on imported meshes (inviscid): largest \|Rw(Roe) − Rw(LLF)\| off the boundary for a continuous state | 9.9920e-16 | < 1e-12 (zero jump across every correctly matched face; residuals of order 0.1 to 1) | pass |
| neighbour coupling on imported meshes, Euler and Navier–Stokes: largest difference of the residual of a rough state between two descriptions of the mesh (elements re-oriented) | 2.4813e-14 | < 1e-12 (round-off; residuals of order 0.1 to 1) | pass |
| the rough state exercises the viscous terms: smallest max \|Rw(Navier–Stokes) − Rw(Euler)\| | 0.0227105 | > 1e-3 (velocity and temperature vary; far above the bound of the coupling check) | pass |
| generated and imported annulus: both solves converged | yes | true | pass |
| imported annulus: face pairs with a non-identity orientation | 42 | > 0 (elements were re-oriented before writing) | pass |
| force and moment coefficients, \|imported − generated\| (largest) | 2.1316e-14 | < 1e-10 (both solves reduce the residual by 1e-12) | pass |
| cylinder in a channel (examples/meshes/cylinder_channel_p3.msh), Re = 40, p = 2: converged | yes | true | pass |
| cylinder in a channel: dcd/dmach, adjoint vs central finite difference (rel.) | 1.1825e-07 | < 1e-6 | pass |

Run notes: Measured in this run: the largest free-stream residual on the imported meshes was 4.4e-15, the largest conservation defect 1.4e-14 and the largest dependence of the inviscid residual of a continuous state on the Riemann solver 1.0e-15. The residual of a rough state changed by at most 2.5e-14 when the elements were re-oriented, with and without viscous terms; the viscous terms contributed between 2.3e-02 and 1.4e-01 to that residual. Conservation alone would not notice a wrong index map between two straight faces (their normals are constant); the Riemann-solver comparison (trace matching, an inviscid test: the viscous terms cancel in it), the comparison of two descriptions (which includes the gradient traces and lifted jumps of the viscous discretization) and the solves of parts (iii) and (iv) do. The annulus written to a file with re-oriented elements (42 of 84 face pairs with a non-identity orientation) gave force coefficients within 2.1e-14 of those on the generated mesh. On the example mesh the adjoint derivative of the drag coefficient with respect to the Mach number differs from the central difference by a relative 1.2e-07. The Gmsh fixtures contain only two of the eight relative face orientations of hexahedra (see the table); all eight occur in the re-oriented box, which is written by Gyre's own writer, not by Gmsh.

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:46:10-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [imported_mesh.json](../data/verification/imported_mesh.json).

A generated mesh is a structured block: neighbouring elements share their local axes. A mesh
from a file is unstructured, so two elements can meet with any relative orientation of their
common face, and the file's node ordering has to be mapped onto Gyre's tensor-product lattice.
The study tests those two things, then the whole path from a file to forces and derivatives.

## Reading Gmsh files

**Table: Gmsh fixtures (tests/data/meshes)** (Imported meshes)

| file | dim | geometry degree | elements | nodes | face pairs with non-identity orientation | min scaled Jacobian | distance from the multilinear map | relative area / volume error | format / outcome |
|---|---|---|---|---|---|---|---|---|---|
| hole_hex_p2.msh | 3 | 2 | 78 | 896 | 72 | 0.138625 | — | 4.3003e-05 | gmsh-4.1 |
| hole_quad_p2.msh | 2 | 2 | 136 | 600 | 48 | 0.361963 | — | 2.7250e-06 | gmsh-4.1 |
| hole_quad_p3.msh | 2 | 3 | 136 | 1308 | 48 | 0.361963 | — | 4.0127e-07 | gmsh-2.2 |
| hole_quad_p4.msh | 2 | 4 | 136 | 2288 | 48 | 0.361963 | — | 1.0421e-09 | gmsh-4.1 |
| periodic_channel_p3_v2.msh | 2 | 3 | 24 | 247 | 0 | 0.886508 | — | — | gmsh-2.2 |
| periodic_channel_p3_v4.msh | 2 | 3 | 24 | 247 | 0 | 0.886508 | — | — | gmsh-4.1 |
| reject_binary.msh | — | — | — | — | — | — | — | — | refused: binary MSH files are not supported: save as ASCII (Mesh.Binary = 0, or `gmsh -format msh41 |
| reject_triangles.msh | — | — | — | — | — | — | — | — | refused: the mesh contains triangles. Gyre needs an all-quadrilateral (2-D) or all-hexahedral (3-D) |
| reject_untagged.msh | — | — | — | — | — | — | — | — | refused: 32 boundary faces belong to no physical group (the first one is near (3, -1.125)). Give ev |
| straight_hex_p1.msh | 3 | 1 | 60 | 126 | 44 | 0.310302 | 0 | 1.5292e-16 | gmsh-2.2 |
| straight_hex_p2.msh | 3 | 2 | 60 | 720 | 44 | 0.310302 | 1.3323e-15 | 0 | gmsh-4.1 |
| straight_hex_p3.msh | 3 | 3 | 60 | 2142 | 44 | 0.310302 | 2.2204e-15 | 0 | gmsh-2.2 |
| straight_hex_p4.msh | 3 | 4 | 60 | 4752 | 44 | 0.310302 | 4.4409e-15 | 3.0585e-16 | gmsh-4.1 |
| straight_quad_p1.msh | 2 | 1 | 120 | 144 | 44 | 0.473634 | 0 | 1.2234e-16 | gmsh-4.1 |
| straight_quad_p2.msh | 2 | 2 | 120 | 528 | 44 | 0.473634 | 1.3323e-15 | 0 | gmsh-2.2 |
| straight_quad_p3.msh | 2 | 3 | 120 | 1152 | 44 | 0.473634 | 1.3323e-15 | 2.4468e-16 | gmsh-4.1 |
| straight_quad_p4.msh | 2 | 4 | 120 | 2016 | 44 | 0.473634 | 2.4425e-15 | 2.4468e-16 | gmsh-2.2 |
| straight_quad_p5.msh | 2 | 5 | 120 | 3120 | 44 | 0.473634 | 3.1086e-15 | 2.4468e-16 | gmsh-4.1 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:46:10-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [imported_mesh.json](../data/verification/imported_mesh.json).

<!-- begin level 2 (Practice) -->
**[L2 Practice] What the fixtures are and what they prove**

The files under `tests/data/meshes` are genuine Gmsh output, produced by
`tools/make_mesh_fixtures.py`. The reader is therefore tested against Gmsh's node ordering,
not against Gyre's own writer.

* **Node ordering.** On the straight-sided fixtures every high-order node must be the
  multilinear image of the element's vertices, to round-off. A wrong entry in an ordering table
  moves a node by a fraction of an element. The fixtures cover quadrilaterals of degree 1 to 5
  and hexahedra of degree 1 to 4, which is every element type the reader accepts.
* **Area and volume.** The quadrature of a multilinear element is exact, so the measure of each
  straight-sided mesh must match the geometry to round-off.
* **Curved boundaries.** On the meshes with a circular hole, the error of the area must fall
  when the geometry degree is raised.
* **Format versions and periodicity.** The MSH 2.2 and MSH 4.1 files of one periodic mesh must
  give the same nodes, and the periodic node pairs of the file must become periodic topology
  with no boundary group on the periodic sides.
* **Refusal.** Files with triangles, a binary file and a file with untagged boundary faces must
  be refused with a message.

<!-- end level 2 -->

## Operator identities on unstructured meshes

**Table: Free stream, conservation and neighbour coupling on imported meshes** (Imported meshes)

| mesh | p | equations | elements | interior face pairs | non-identity orientation | relative orientations present | free stream max \|Rw\| | perturbed nodes | perturbed elements | max \|Rw\| of the perturbed state | \|sum of Rw\| (conservation) | max \|Rw\| of the continuous state (inviscid) | max \|Rw(Roe) − Rw(LLF)\| off the boundary (inviscid) | non-identity orientation after re-orienting | max \|Rw\| of the rough state | max \|Rw(Navier–Stokes) − Rw(Euler)\| of the rough state | max \|Rw − Rw re-oriented\| of the rough state |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hole_quad_p3.msh (Gmsh, curved, 2-D) | 3 | Euler | 136 | 244 | 48 | 2 of 2 | 4.4409e-15 | 1956 of 2176 | 136 | 0.415774 | 6.0785e-15 | 0.374242 | 9.9920e-16 | 131 | 0.825899 | — | 2.4758e-14 |
| hole_quad_p3.msh (Gmsh, curved, 2-D) | 3 | Navier–Stokes | 136 | 244 | 48 | 2 of 2 | 4.4409e-15 | 1344 of 2176 | 84 | 0.435898 | 1.3767e-14 | — | — | 131 | 0.857855 | 0.108184 | 2.4813e-14 |
| hole_hex_p2.msh (Gmsh, curved, 3-D) | 2 | Euler | 78 | 172 | 72 | 2 of 8 | 1.0527e-15 | 1162 of 2106 | 78 | 0.620272 | 3.9101e-15 | 0.732109 | 5.2736e-16 | 156 | 0.846379 | — | 7.3830e-15 |
| hole_hex_p2.msh (Gmsh, curved, 3-D) | 2 | Navier–Stokes | 78 | 172 | 72 | 2 of 8 | 1.0527e-15 | 162 of 2106 | 6 | 0.306193 | 5.2173e-15 | — | — | 156 | 0.853996 | 0.139857 | 7.3830e-15 |
| periodic warped 3x3x3 box, re-oriented, written and read back | 2 | Euler | 27 | 81 | 74 | 8 of 8 | 5.2633e-16 | 729 of 729 | 27 | 0.115116 | 5.4123e-16 | 0.113226 | 2.6368e-16 | 67 | 0.181751 | — | 4.4686e-15 |
| periodic warped 3x3x3 box, re-oriented, written and read back | 2 | Navier–Stokes | 27 | 81 | 74 | 8 of 8 | 5.2633e-16 | 729 of 729 | 27 | 0.120425 | 1.8596e-15 | — | — | 67 | 0.18704 | 0.0227105 | 4.4756e-15 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:46:10-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [imported_mesh.json](../data/verification/imported_mesh.json).

<!-- begin level 2 (Practice) -->
**[L2 Practice] Four tests, and what each can see**

The meshes are a curved 2-D Gmsh mesh, a curved 3-D Gmsh mesh, and a periodic warped 3-D box
whose elements were randomly re-oriented, written to a file and read back.

* **Free stream.** A uniform flow must leave the residual at round-off.
* **Conservation.** The residuals of a perturbed state must sum to zero. This test alone would
  not notice a wrong index map between two straight faces, whose normals are constant.
* **Neighbour matching.** For a continuous state the inviscid residual must not depend on the
  Riemann solver away from the boundary: the jump across a face is zero only if its nodes are
  matched with the right nodes of the neighbour. The viscous terms cancel in this comparison,
  so it is an Euler test.
* **Neighbour coupling, including the viscous terms.** A rough state with varying velocity and
  temperature and a jump on every face must give the same residual, node by node, when every
  element of the mesh is stored in other, randomly chosen local axes. This covers the gradient
  traces of the neighbour and the lifted jumps of the viscous discretization, for the Euler and
  the Navier–Stokes equations. A companion check requires that the viscous terms contribute to
  that residual, so the comparison is not vacuous.

Each configuration also has a check that the perturbed state is not trivial and that the mesh
has face pairs with a non-identity orientation.

<!-- end level 2 -->

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] Face orientations that Gmsh does not produce**

Two hexahedra can meet in eight relative face orientations. The table lists which of them
occur in each mesh; the run notes state how many the Gmsh fixtures contain. All eight are
required of the re-oriented box, and that mesh is written by Gyre's own writer, not by Gmsh.
The complete set of orientations is therefore tested on the operator, through a file, but not
on files from an external generator.

<!-- end level 3 -->

## From a file to forces and derivatives

**Table: Cylinder Re = 40 on the generated annulus (12 x 4, p = 2) and on the same mesh read from a file** (Imported meshes)

| quantity | generated | imported | difference |
|---|---|---|---|
| cd | 1.69824 | 1.69824 | 2.1316e-14 |
| cl | -2.0933e-14 | -2.1852e-14 | 9.1940e-16 |
| cm | -2.8159e-15 | -6.9159e-15 | 4.1000e-15 |
| Newton steps | 13 | 13 | — |
| final / reference residual | 4.0911e-14 | 3.5832e-14 | — |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:46:10-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [imported_mesh.json](../data/verification/imported_mesh.json).

**Chart: Residual histories on generated and imported meshes** (Imported meshes). History chart of |Rw| against nonlinear iteration, y axis log; 3 series. The table holds the plotted data. The histories of the generated and of the imported annulus coincide.

| series | nonlinear iteration | \|Rw\| |
|---|---|---|
| annulus, generated | 0 | 28.3595 |
| annulus, generated | 1 | 18.8413 |
| annulus, generated | 2 | 15.4035 |
| annulus, generated | 3 | 5.38765 |
| annulus, generated | 4 | 4.32122 |
| annulus, generated | 5 | 1.04459 |
| annulus, generated | 6 | 0.203824 |
| annulus, generated | 7 | 0.0763292 |
| annulus, generated | 8 | 0.00731001 |
| annulus, generated | 9 | 1.0453e-04 |
| annulus, generated | 10 | 1.0185e-06 |
| annulus, generated | 11 | 8.2949e-09 |
| annulus, generated | 12 | 5.3854e-11 |
| annulus, generated | 13 | 1.1602e-12 |
| annulus, re-oriented and read from a file | 0 | 28.3595 |
| annulus, re-oriented and read from a file | 1 | 18.8413 |
| annulus, re-oriented and read from a file | 2 | 15.4035 |
| annulus, re-oriented and read from a file | 3 | 5.38765 |
| annulus, re-oriented and read from a file | 4 | 4.32122 |
| annulus, re-oriented and read from a file | 5 | 1.04459 |
| annulus, re-oriented and read from a file | 6 | 0.203824 |
| annulus, re-oriented and read from a file | 7 | 0.0763292 |
| annulus, re-oriented and read from a file | 8 | 0.00731001 |
| annulus, re-oriented and read from a file | 9 | 1.0453e-04 |
| annulus, re-oriented and read from a file | 10 | 1.0185e-06 |
| annulus, re-oriented and read from a file | 11 | 8.2949e-09 |
| annulus, re-oriented and read from a file | 12 | 5.3709e-11 |
| annulus, re-oriented and read from a file | 13 | 1.0162e-12 |
| cylinder in a channel (Gmsh mesh) | 0 | 24.7737 |
| cylinder in a channel (Gmsh mesh) | 1 | 13.8753 |
| cylinder in a channel (Gmsh mesh) | 2 | 8.51098 |
| cylinder in a channel (Gmsh mesh) | 3 | 5.12228 |
| cylinder in a channel (Gmsh mesh) | 4 | 3.3529 |
| cylinder in a channel (Gmsh mesh) | 5 | 2.0295 |
| cylinder in a channel (Gmsh mesh) | 6 | 0.910516 |
| cylinder in a channel (Gmsh mesh) | 7 | 0.36902 |
| cylinder in a channel (Gmsh mesh) | 8 | 0.0892722 |
| cylinder in a channel (Gmsh mesh) | 9 | 0.0363698 |
| cylinder in a channel (Gmsh mesh) | 10 | 0.00262342 |
| cylinder in a channel (Gmsh mesh) | 11 | 3.1460e-05 |
| cylinder in a channel (Gmsh mesh) | 12 | 3.0281e-07 |
| cylinder in a channel (Gmsh mesh) | 13 | 2.5325e-09 |
| cylinder in a channel (Gmsh mesh) | 14 | 1.9079e-11 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:46:10-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [imported_mesh.json](../data/verification/imported_mesh.json).

<!-- begin level 2 (Practice) -->
**[L2 Practice] The same mesh, generated and imported**

The coarse annulus of the cylinder case is written to a Gmsh file after its elements were
randomly re-oriented, and read back through a case specification with `mesh.generator: file`.
Both solves must converge, and the force and moment coefficients must agree with those on the
generated mesh to solver tolerance. This exercises the case path for mesh files (boundary
conditions per group, reference quantities) and the solver on a mesh with non-identity
orientations.

<!-- end level 2 -->

**Table: Cylinder in a channel on examples/meshes/cylinder_channel_p3.msh** (Imported meshes)

| quantity | value |
|---|---|
| elements | 284 |
| geometry degree | 3 |
| degrees of freedom | 10224 |
| face pairs with a non-identity orientation | 104 of 528 |
| Newton steps | 14 |
| final / reference residual | 7.7014e-13 |
| cd | 3.21039 |
| cl | 2.2180e-04 |
| cm (about the cylinder axis) | -0.00200862 |
| dcd/dmach, adjoint | 0.331089 |
| dcd/dmach, central difference (step 0.0001) | 0.331089 |
| relative difference | 1.1825e-07 |

Provenance: gyre 0.4.0; revision `39979fcf90` (commit `39979fcf902ad6116eb550b881b4278d4599c8e2`); 2026-11-12T11:46:10-0500; device cpu; quick suite. **Revision check: Same code as this build.** Produced by 39979fcf902ad6116eb550b881b4278d4599c8e2. Every commit between it and the commit this site was built from (ceb1f4b0bed41de53e586df10858079f5a2bcdd8) changes only documentation text, evidence records or bookkeeping: the code is the same. Full record: [imported_mesh.json](../data/verification/imported_mesh.json).

<!-- begin level 2 (Practice) -->
**[L2 Practice] An unstructured mesh from Gmsh**

Laminar flow past a cylinder in a channel ($Re = 40$, $M = 0.2$, slip walls) is solved at
degree 2 on `examples/meshes/cylinder_channel_p3.msh`, an unstructured mesh of cubic
quadrilaterals. The solve must converge, and the adjoint derivative of the drag coefficient
with respect to the Mach number must match a central finite difference of re-converged flows.

<!-- end level 2 -->

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] What this study does not cover**

* **No flow solve on an imported 3-D mesh.** The 3-D evidence is the operator identities above;
  the 3-D solver path is tested on a generated mesh in
  [Three-dimensional consistency](three-dimensional.md).
* **No comparison with a reference solution on the channel mesh.** That case shows that the
  solver converges and that the adjoint is consistent with the discrete problem; it is not an
  accuracy study.
* **Mesh quality.** The reader refuses elements with a non-positive Jacobian determinant and
  reports the smallest scaled Jacobian. It does not judge whether a valid mesh resolves the
  flow.
* **The NPZ format and malformed files** are covered by the unit tests in
  `tests/test_meshio.py` ([Testing strategy](../engineering/testing-strategy.md)), not by this
  study.

<!-- end level 3 -->

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] Reproduce it**

```bash
gyre verify --only imported_mesh
gyre mesh info examples/meshes/cylinder_channel_p3.msh
```

The second command prints the summary of the example mesh: size, geometry degree, boundary
groups, quality numbers and content hash.

<!-- end level 3 -->
