2-D fault zones reach the domain boundary: the ribbon outcrops (#549) - #552
Conversation
The 3-D outcrop machinery brought one dimension down. The ribbon assembly is clipped to the domain box in OCC under the same specify-long contract (polylines may run past the domain), skin edges left exactly in one wall line become the outcrop band, and the carve opens onto that wall. The 2-D case is simpler than the 3-D one that ships: the clipped skin is still a closed loop, so the band splits it into band + open interior chain, and the cap degenerates from a wall-annulus meshing problem to two straight wall segments — the outcrop fill is one simply-connected polygon, the cavity ring with its wall span replaced by the interior chain (_outcrop_ring_splice). The splice segments and the band are relabelled with what the deleted wall span carried, full closures included, gated by an exact count. Refusals keep their teeth: an interior ribbon whose cavity reaches the wall still refuses, a zone meeting two walls refuses (box-edge outcrop bands are not built, matching 3-D), and a ribbon meeting one wall in two bands refuses. Wall vertices become deletable only in the open wall's line, and never at a domain corner. Tests: the band census with its interior-twin negative control, the P2 Poisson quadratic-exact oracle on the outcropped mesh, refusal coverage, and np=2 parallel forms (band present, no top-wall edge left unlabelled, refusals collective; also run at np=4). Underworld development team with AI support from Claude Code
|
Adversarial review (self-review, posted per our convention). We went looking for ways this breaks; findings with evidence. 1. Exact-coordinate wall identity — inherited limitation, worth knowing. Band identification, the deletable-wall mask, and the splice all test 2. Chain orientation at the splice. The chain is oriented by comparing its two end t-coordinates against the left corner. Ambiguity would need the two ends equidistant from the corner, which requires them coincident — excluded because both ends lie strictly inside the corner interval and are distinct band endpoints. No tiebreak needed. 3. Labels on ghost copies after the target-rank relabel. The relabel runs on the surgery rank only. This is safe for the same reason the skin labelling is: the gathered region is rank-interior (the shared-point check refuses otherwise), so every point the relabel touches exists only on the target rank. Evidence: the np=2 and np=4 runs assert no owned top-wall edge is missing its label, and pass. 4. A wall span deleted beyond the band. Wall vertices outside the band interval but within carve reach are deleted and their span is replaced by the straight splice segments — geometry preserved exactly because the wall is straight (finding 1's restriction is load-bearing here). The relabel count gate ( 5. What we could not break in testing: the interior contract (18 serial tests incl. the pre-existing 14, unchanged), area conservation (bitwise gate to 1e-9 relative, exercised in every test), the fill's verbatim-segment gates (any subdivision of a splice segment would refuse), and the three refusals each assert their message. 6. One deliberate asymmetry. Underworld development team with AI support from Claude Code |
There was a problem hiding this comment.
Pull request overview
Enables 2‑D place_thin_volume “ribbon” fault zones to legally reach (and outcrop on) a domain boundary by clipping the OCC assembly to the domain box and wiring the outcrop/band machinery that already exists for 3‑D. The PR also generalizes band extraction logic across dimensions and adds an assembly={"fuse","fragment"} option (default "fuse") to avoid sliver‑seam meshes in tangential overlaps.
Changes:
- Add specify‑long (box‑clipped) OCC assembly support for 2‑D ribbons and implement 2‑D outcrop handling (band identification, ring splice, explicit wall relabel).
- Generalize
_split_skin_bandto work for both 3‑D (triangles) and 2‑D (edges), and addassemblyboolean selection ("fuse"default) in both 2‑D and 3‑D assembly paths. - Add serial + parallel tests for 2‑D outcropping ribbons and for the
"fuse"vs"fragment"sliver negative control; update developer docs and add a design note.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/underworld3/utilities/place_surface.py |
Adds 2‑D assembly clipping and outcrop/band plumbing; makes band split dimension‑free; introduces assembly={"fuse","fragment"} handling. |
tests/test_0855_place_thin_volume.py |
Adds regression tests for tangential merge slivering (fuse vs fragment) and for 2‑D outcropping ribbon embedding + oracle solve. |
tests/parallel/ptest_0855_place_thin_volume_parallel.py |
Adds np≥2 coverage for 2‑D outcrop embedding and collective refusal behavior. |
docs/developer/subsystems/conforming-surfaces-and-fault-zones.md |
Documents the new assembly behavior and rationale (seams vs slivers). |
docs/developer/index.md |
Registers the new design note in the developer docs toctree. |
docs/developer/design/fault-zone-hybrid-architecture.md |
Adds a design note describing a hybrid zone/contact approach and records measured motivation for fused assemblies. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Closes #549 (the ribbon half; the fault_split contact side is a separate design decision, tracked there).
What this does
A 2-D fault zone specified past a domain wall now embeds, with its clipped edge on the wall. This is the 3-D outcrop machinery (#525/#526) brought one dimension down:
_occ_assembly_2dgains thebox=clip of its 3-D twin — same specify-long contract (polylines may protrude; the assembly is intersected with the domain rectangle in OCC and snapped to exact wall values after meshing).cad_areais computed after the boolean, so the meshed-vs-CAD area gate holds unchanged._split_skin_bandis now dimension-free: facets are triangles against wall planes in 3-D, edges against wall lines in 2-D. One wall only, as before._outcrop_chain_2dsplits it into the band and an open interior chain; and the cap degenerates from a wall-annulus meshing problem to two straight wall segments. The outcrop fill is therefore one simply-connected polygon — the cavity ring with its wall span replaced by the interior chain (_outcrop_ring_splice) — with no separate cap fill at all.What still refuses
Tests
Base
Branched from
developmentwith #541 (feature/fuse-zone) merged in, because #541 rewrites_occ_assembly_2d— the clip is written against the fuse-era code. Once #541 merges this PR's diff reduces to the outcrop work alone; it should land after #541.Underworld development team with AI support from Claude Code