Carotid wall

The wall of the examples/carotid.py hex mesh, smoothed as a free-standing surface on the example’s own tessellation with the open rim frozen, as built or with perturbed input.

Key points

  • The hard case: a real, strongly curved, open wall (hexmesh.boundary_mesh(mesh, "wall")), smoothed by examples/smoother/quad/cs_wall_surface.py.

  • The smoother does not touch the hexes: no interior node follows a moved vertex, so these are not volume-mesh numbers.

  • Not every number ends better: as built, the worst quad can get worse while the mean and the tail improve; perturbed, most of the damage is recovered. The verdict lines under the table say which.

  • Perturbed input: every movable vertex shifted by up to 0.2 of its local edge length, then put back on the surface.

The numbers

run

quads

inverted

overlapping

min scaled J

mean scaled J

worst 5 % scaled J

as built

1440

0 → 0

6 → 0

0.6921 → 0.6034

0.9828 → 0.9910

0.9370 → 0.9706

perturbed input

1440

0 → 0

0 → 0

0.5787 → 0.6117

0.9405 → 0.9908

0.8304 → 0.9698

  • as built: min scaled J fell (0.6921 → 0.6034), mean scaled J rose (0.9828 → 0.9910), worst 5 % rose (0.9370 → 0.9706); no quad is inverted or overlapping at the end.

  • perturbed input: min scaled J rose (0.5787 → 0.6117), mean scaled J rose (0.9405 → 0.9908), worst 5 % rose (0.8304 → 0.9698); no quad is inverted or overlapping at the end.

Run python examples/smoother/quad/cs_wall_surface.py to reproduce; it prints these numbers.

The hexes

  • examples/smoother/quad/cs_carotid_hex.py re-runs the examples/carotid.py recipe at order 1 with each station’s wall ring replaced by the smoothed wall: an order-1 rebuild, not a propagation. Only the wall surface is smoothed; the hexes are regenerated from it (the carotid recipe re-run), not smoothed themselves. Every layer comes from the wall ring; the original’s high-order curvature is not carried.

  • The shared seam ring (the last wall ring of every leg, where the three legs meet) is held fixed, like the open rim; left free, the last layer of one leg inverts (the seam-ring-free row under Hex quality).

  • Exterior: every named face coloured by boundary group, one checkbox each. Cross-section: one leg and the trifurcation, by scaled Jacobian or wall layer. Switch original / rebuild; drag to orbit.

Hex quality

mesh

hexes

min scaled J

mean

worst 5 %

inverted

order-7 sampling: min / inverted

original (carotid recipe)

7200

0.0960

0.9167

0.7951

0

0.0960 / 0

smoothed wall, seam ring free

7200

-0.1253

0.9169

0.7903

7

-0.1253 / 7

rebuilt on the smoothed wall (seam ring held)

7200

0.0216

0.9184

0.7963

0

0.0216 / 0

Scaled Jacobian of the order-1 hexes, read at their 8 corners (the straight-sided hex a .re2 file holds). The last column re-reads the same trilinear map on an 8^3 lattice, the solver’s order: it agrees with the corner reading to 3 decimals in every row.

With the same layers, the rebuild on the smoothed wall moved the hexes’ worst corner reading from 0.0960 to 0.0216, the mean from 0.9167 to 0.9184 and the worst 5 % from 0.7951 to 0.7963; 0 hexes are inverted at the corners before and 0 after (order-7 sampling: 0 and 0). The wall faces themselves improve more than the hexes do: wall scaled J (against the tessellation) min 0.692 → 0.731, worst 5 % 0.937 → 0.957, largest neighbour size ratio 1.94 → 1.51, overlapping wall quads 6 → 0. The enclosed volume changes by +0.083 %.

Smoothing leaves the first layer as it was: first layer over local radius, median 0.0548 → 0.0550, min 0.0319 → 0.0304, max 0.0726 → 0.0726.

With the shared seam ring left free, the same rebuild inverts 7 hexes (min -0.125).

The worst hex fell in quality (min 0.0960 → 0.0216) while the mean rose and the worst 5 % rose: read the minimum first.

Layers

  • Set by the construction’s radial fractions (RADIAL, top of the script), measured from the wall inward along core-to-wall lines; the rebuild keeps the original’s four layers.

  • A property of the construction, not of the surface, which is why smoothing leaves the first layer as it was.

RADIAL (constants at the top of examples/smoother/quad/cs_carotid_hex.py) is the original’s: [0.0, 0.4, 0.7, 0.9, 1.0], 4 layers between the core square and the wall, the wall layer 0.10 of the gap. The rebuild keeps exactly this layering.

mesh

layers

first layer, fraction of the core-to-wall gap

first layer / local radius: min

median

max

original wall

4

0.100

0.0319

0.0548

0.0726

smoothed wall, rebuilt

4

0.100

0.0304

0.0550

0.0726

The first layer is measured as each wall hex’s edge into the volume, against the mean radius of its station’s wall ring (1440 wall hexes in both). Its thickness over the local radius is essentially unchanged, so the smoothed wall leaves the original boundary layer intact: the layering is a property of the construction, not of the surface.

Cost

  • Wall-clock timers around the script’s own stages, from reading the tessellation to the rebuilt hexes: a single run and a rough estimate, taken with OMP_NUM_THREADS=1 (without it some parts use several threads and the seconds differ).

  • Stage 4 builds the original hexes (each station’s ring stack and wall fit included); stage 8 is the same build on the smoothed wall’s rings.

Measured on a laptop, running serial (one process, no parallelism); numbers vary by machine and run.

stage

seconds

share of the total

1 read the tessellation (TriMesh)

0.00

0.0 %

2 seam fields, cut into legs

0.02

0.4 %

3 seam rings, leg rings, spine

0.19

3.5 %

4 O-grid sections, extrusion, welds, tags (original hexes)

0.53

9.6 %

5 extract the wall quads

0.00

0.1 %

6 smoother set-up (gate, overlaps, surface, normals)

0.03

0.6 %

7a smoothing: laplace

0.03

0.5 %

7b smoothing: optimize

2.50

45.0 %

7c smoothing: local lifts

0.00

0.0 %

8 rebuild the hexes on the smoothed wall

0.64

11.4 %

9 quality readings (original and rebuilt)

1.58

28.5 %

10 export (original and rebuilt, .vtu)

0.02

0.3 %

total of the stages above

5.56

100 %

Smoothing (7) vs building the original hexes (4) and rebuilding them (8): 2.54 s vs 0.53 s and 0.64 s.

1 read the tessellation (TriMesh)0.0 %
2 seam fields, cut into legs0.4 %
3 seam rings, leg rings, spine3.5 %
4 O-grid sections, extrusion, welds, tags (original hexes)9.6 %
5 extract the wall quads0.1 %
6 smoother set-up (gate, overlaps, surface, normals)0.6 %
7a smoothing: laplace0.5 %
7b smoothing: optimize45.0 %
7c smoothing: local lifts0.0 %
8 rebuild the hexes on the smoothed wall11.4 %
9 quality readings (original and rebuilt)28.5 %
10 export (original and rebuilt, .vtu)0.3 %

The stage that takes the most time is smoothing: optimize (45 % of the stages listed). Smoothing the wall (7) takes 46 % of them, which is more expensive than either building the hexes or rebuilding them: it costs 4.7 times the original build (4) and 4.0 times the rebuild (8). One run, serial, a rough estimate; the same script on another machine, or again on this one, gives other seconds and other shares. The work outside the table (other smoothing variants, the perturbed input and their readings, the figure: 15.2 s here) is what makes the script’s own total longer than the table’s.

Run python examples/smoother/quad/cs_carotid_hex.py to reproduce; it prints these numbers, the timing table at the end (TIMING at the top of the script switches it off).

Notes and caveats
  • The tessellation is itself an approximation of the vessel, so the normals the metric uses carry its chord error.

  • Folded or overlapping inputs are a known limitation of the smoother.

  • The wall is too large for the data to keep a stage history, so the viewer shows only the input and the final state.

  • The smoothed wall in the rebuild is the one above, held fixed at the open rim and the shared seam ring; the rebuilt hexes’ wall faces are that wall.

  • The tables are regenerated by docs/_ext/gen_smoother_quad_assets.py and docs/_ext/gen_smoother_quad_hexviews_assets.py; nothing is typed in.