# Relaxed dedup tolerance vs sliver-tet buckling hypothesis Date: 2026-05-05 Branch: `main` Experiment scope: ~30 min bounded side experiment. ## Question Finding 4 of the prior buckling work (commit `7e45df3` convergence study) left two competing hypotheses for the spurious low-eigenvalue / non-monotonic buckling modes seen on the previously-meshed dome: 1. **Sliver-tet hypothesis** — the tet-mesher produced near-degenerate elements at panel-junction kink-lines because the corner-dedup tolerance (30 mm) was too tight against the OBJ's geometric drift; the spurious modes are mesh-quality artefacts that would disappear on a cleaner mesh. 2. **Kink-line singularity hypothesis** — the panel junctions are geometrically C0 (a sharp ridge in the tet-volume idealisation); the buckling operator therefore sees a curvature singularity at every joint, and *no* tet refinement can produce a clean buckling spectrum without first physically modelling the joint (a finite chamfer, a rib, or a shell-mesh of the mid-surface). The convergence study suggested (2). This experiment was the cheapest possible direct test of (1): relax the corner-dedup tolerance from 30 mm to 100 mm (matching the looser policy used by the shell mid-surface mesher in `src/zomestruct/fea/midsurface_mesh.py:103` of 300 mm), re-run gmsh on the highest-resolution OBJ, and observe the resulting buckling spectrum. ## Method Modified `tools/build_assembly_mesh.py` to expose `--dedup-tol-mm` as a CLI argument (default 30 mm, preserving prior behaviour). The underlying `build_assembly_mesh(...)` in `src/zomestruct/fea/assembly_mesh.py` already accepts a `dedup_tol_mm` parameter, so this is a pure tool-layer change with zero source-module modifications. Invocation: ``` python3 tools/build_assembly_mesh.py --dedup-tol-mm 100 ``` (Captured in `reports/build_assembly_mesh_relaxed_tol.txt`.) ## Result: gmsh STILL refuses to mesh The relaxed tolerance got the corner-network builder further along — the log shows the network condensed from 173 unique corners (at 30 mm tol) to 116 unique corners (at 100 mm tol), with average panels-per-corner rising from 1.62 to 2.41, and the post-classification facet count dropping from 1022 to 938. So tolerance relaxation *did* visibly affect the input PLC. But gmsh's tetgen back-end raised the **identical** error: ``` PLC Error: A segment and a facet intersect at point ``` at the same call site: ``` src/zomestruct/fea/assembly_mesh.py:441 → gmsh.model.mesh.generate(3) ``` So the geometric defect that tetgen objects to is *not* a corner-merging issue. It is an edge-pierces-facet condition that survives any reasonable amount of corner snapping, because the surface mesh that the panel-fit pipeline emits has segments that geometrically cross facets in the interior of the assembly skin, not just at corners. Two consequences: - **Mesh build outcome:** failure. n_tets, n_nodes, n_neg_jacobian: N/A. - **Buckling re-run (Step 3):** skipped per bounded-experiment protocol. No new ccx_buckle eigenvalues to compare. The Finding-4 sequences stand: - old-OBJ snow baseline modes: 4.886 / 13.71 / 16.22 / 31.92 - old-OBJ uplift baseline modes: 3.356 / 4.57 / 11.43 / 483.5 ## Verdict on the sliver-tet hypothesis **Inconclusive on its own**, **but the relaxation hypothesis (1') — that loosening dedup tolerance recovers a usable tet mesh — is falsified.** Specifically: - We could not refute (1) directly because we never produced a competing buckling spectrum. - We did refute the corollary that motivated this experiment: that tolerance relaxation alone is sufficient to recover meshability at the highest OBJ resolution. It is not. The PLC defect persists at 100 mm tolerance. - The convergence-study reading — that the kink-line singularity is fundamental, not a tolerance artefact — is **reinforced**. The tet-pipeline cannot consume the panel assembly cleanly without upstream geometric reconciliation (rib/chamfer modelling, or switching to a mid-surface shell formulation, both of which the in-house shell solver path is already pursuing). ## Implication: stop investing in the tet-buckling pipeline For the permit appendix, the buckling FE result should be reported from the mid-surface shell formulation, not the tet pipeline. The tet pipeline has now hit two distinct failure modes against the highest-resolution OBJ: 1. At 30 mm tol it failed with the same PLC error (commit `f0a9f31`). 2. At 100 mm tol it fails with the same PLC error (this experiment). Spending more agent-hours on tolerance sweeps is bounded waste. The shell mid-surface solver path (already operational; see `reports/shell_dome_*.vtu`) is the correct vehicle for the buckling permit deliverable. ## One-paragraph statement for the permit appendix > The tetrahedralised volume FE used for an early buckling sanity check > at 30 mm corner tolerance produced a non-monotonic eigenvalue > sequence whose lowest mode was traced to mesh artefacts at panel-edge > kink lines rather than physical instability. A bounded follow-up > experiment that relaxed the corner-merge tolerance to 100 mm > confirmed the underlying defect is geometric (the assembled panel > skin contains edge–facet intersections that tetgen cannot > tetrahedralise at any reasonable tolerance), not a meshing-parameter > issue. The reported buckling load multipliers for the permit therefore > rely on the mid-surface shell formulation, where panel joints are > represented by C0 ridge segments with explicit shell continuity and > the buckling operator is well-posed. The tetrahedral pipeline is > retained only for cross-checking static stress fields away from > joints. ## Files in this commit - `tools/build_assembly_mesh.py` — added `--dedup-tol-mm` CLI argument (default 30 mm, backward compatible). - `reports/build_assembly_mesh_relaxed_tol.txt` — captured failure log. - `reports/2026-05-05--relaxed-tol-buckling.md` — this document. No source modules under `src/zomestruct/fea/*` were modified. No other tools were modified. `tools/ccx_buckle.py` was not invoked because Step 2 failed.