Emit a solver-ready Mesh3D_t from an adaptively refined, 2:1-balanced octree forest,
the direct analogue of SELF_AdaptiveMesh_2D. This closes the 3-D adaptive-refinement
loop: with the indicator flagging elements, the forest mutating, and Balance2to1
balancing it, EmitMesh produces the nonconforming mesh - leaf geometry,
conforming-face connectivity, and a mortar table for the 2:1 hanging faces - that the
3-D mortar solver machinery already handles.
Each leaf of the forest becomes an element (in leaf-list order). For every leaf face
the 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 face (sideInfo(3)=nbr, (4)=10*face+flip)
one-level-finer face -> this leaf is the BIG face of a 2:1 mortar; the four small
elements are the finer neighbour node's children on the
shared face
one-level-coarser face -> this leaf is a SMALL face; filled when its big face is
processed
Mortar faces 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 14-row layout documented on Mesh3D_t
(big elem/face; small elem + 10*face+flip per sub-face in big-face quadrant order;
four sub-face global side ids), with the small-face flips inherited from the shared
face's flip and the quadrant-to-child pairing given by faceQuadPerm/childOfFace.
Decomposition: 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.
Inverse of a SELF face flip: the flip that maps donor-face indices back to
receiver-face indices. Flips 0..4 and 6 are involutions; 5 and 7 invert each other.
Arguments
Type
Intent
Optional
Attributes
Name
integer,
intent(in)
::
f
Return Value integer
Subroutines
public subroutine EmitMesh(forest, baseMesh, outMesh)
Build outMesh (a conforming-or-mortar Mesh3D_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.