Emit a solver-ready Mesh2D_t from an adaptively refined, 2:1-balanced quad-forest (AMR
Stage 4b). This closes the adaptive-refinement loop: with the Stage-1 indicator flagging
elements, Stage 2b mutating the forest, and Stage 4a balancing it, EmitMesh produces the
nonconforming mesh - leaf geometry, conforming-side connectivity, and a mortar table for the
2:1 hanging faces - that the existing mortar solver machinery already handles.
Each leaf of the forest becomes an element (in leaf-list order). For every leaf face the
Stage-4a FaceNeighbor query classifies the face and drives the emitted connectivity:
domain boundary -> sideInfo(3)=0, sideInfo(5)=base BC id
same-level leaf -> conforming interior side (sideInfo(3)=neighbour, (4)=10*side+flip)
one-level-finer face -> this leaf is the BIG side of a 2:1 mortar; the two small elements
are the finer neighbour node's children on the shared face
one-level-coarser face-> this leaf is a SMALL side; filled when its big side is processed
Mortar sides carry sideInfo(1)=mortar index and sideInfo(3)=sideInfo(5)=0 so the conforming
side-exchange machinery skips them, exactly as in the hand-built SimpleMortarMesh. The mortar
table follows the same 8-row layout (big elem/side; small elem + 10*side+flip per sub-edge;
two sub-edge global side ids), with sub-edge 1 covering the big edge coordinate [-1,0] and
sub-edge 2 covering [0,1], and the small-side flips inherited from the base face flip.
Decomposition (AMR Stage 5): every rank builds the same GLOBAL connectivity and mortar
tables deterministically from the (rank-replicated) forest, generates a fresh contiguous
decomposition over the leaf list - leaf-list order is Morton order within each root tree, so
contiguous ranges are space-filling-curve partitions - and stores only its local slice of
the element-sized arrays, exactly as the built-in mesh constructors do. sideInfo(3) carries
global element ids, nUniqueSides is the global side count, and mortarInfo/nMortars are
replicated in full with global ids on every rank, which is what SideExchange/MortarExchange
require. Repartitioning is implicit: each epoch's emitted mesh is re-decomposed over the new
leaf list, so equal-count partitions move with the refinement.
Nodes of different colours represent the following:
Solid arrows point from a submodule to the (sub)module which it is
descended from. Dashed arrows point from a module or program unit to
modules which it uses. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Nodes of different colours represent the following:
Solid arrows point from a submodule to the (sub)module which it is
descended from. Dashed arrows point from a module or program unit to
modules which it uses. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
public subroutine EmitMesh(forest, baseMesh, outMesh)
Build outMesh (a conforming-or-mortar Mesh2D_t) from a 2:1-balanced forest. baseMesh is
the mesh the forest was initialised from (supplies BC metadata and the communicator; on
nRanks > 1 the forest must be rank-replicated so every rank emits identical global
tables). The forest must already be balanced (MaxLevelJump <= 1); EmitMesh does not
mutate it.