| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public | :: | capacity | = | 0 | ||
| integer, | public, | allocatable | :: | child(:,:) | |||
| integer, | public, | allocatable | :: | leaf(:) | |||
| integer, | public, | allocatable | :: | level(:) | |||
| integer, | public | :: | nGeo | = | 0 | ||
| integer, | public | :: | nLeaves | = | 0 | ||
| integer, | public | :: | nNodes | = | 0 | ||
| integer, | public | :: | nRoots | = | 0 | ||
| integer, | public, | allocatable | :: | parent(:) | |||
| integer, | public, | allocatable | :: | quadrant(:) | |||
| integer, | public | :: | quadrature | = | 0 | ||
| integer, | public, | allocatable | :: | rootBC(:,:) | |||
| real(kind=prec), | public, | allocatable | :: | rootCoords(:,:,:,:) | |||
| integer, | public, | allocatable | :: | rootElem(:) | |||
| integer, | public, | allocatable | :: | rootFlip(:,:) | |||
| integer, | public, | allocatable | :: | rootMaterial(:) | |||
| integer, | public, | allocatable | :: | rootNbr(:,:) | |||
| integer, | public, | allocatable | :: | rootNbrSide(:,:) |
Mutate the forest from a per-leaf flag array (indexed over the current leaves in this%leaf order, e.g. the flag array produced by SELF_RefinementIndicator_2D):
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(inout) | :: | this | |||
| integer, | intent(in) | :: | flag(1:this%nLeaves) |
Enforce the 2:1 balance condition: no leaf face may separate elements differing by more than one refinement level. Iterates to a fixed point - in each sweep, any leaf whose equal-or-larger neighbour is a leaf two or more levels coarser triggers refinement of that coarser neighbour; refinement can ripple, so sweeps repeat until nothing changes. The leaf set is rebuilt on return.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(inout) | :: | this |
Grow the node arrays (amortized doubling) so at least need nodes fit.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(inout) | :: | this | |||
| integer, | intent(in) | :: | need |
Find the equal-or-larger face neighbour of node across its local side s using the
classic quadtree ascend/descend search. Returns:
nbr - neighbour node id (0 = physical domain boundary). It is either a LEAF at any level
<= level(node), or an INTERNAL node at exactly level(node) (meaning the shared face
is subdivided on the neighbour side, i.e. finer neighbours exist).
ns - the neighbour's local side that faces node.
nf - the flip between the two shared edges (0 same direction, 1 reversed), inherited
from the base-mesh face where the search crosses a root boundary.
With this, a 2:1 hanging face is exactly "nbr is a leaf with level(nbr) = level(node)-1",
and finer neighbours are exactly "nbr is internal".
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(in) | :: | this | |||
| integer, | intent(in) | :: | node | |||
| integer, | intent(in) | :: | s | |||
| integer, | intent(out) | :: | nbr | |||
| integer, | intent(out) | :: | ns | |||
| integer, | intent(out) | :: | nf |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(inout) | :: | this |
Initialize the forest with one root per base-mesh element (all leaves at level 0). The base geometry (node coordinates) is copied so leaf geometry can be regenerated after any amount of refinement without holding a reference to the mesh. Requires a single-rank mesh (a decomposed mesh only stores its local elements); a rank-replicated forest over a decomposed base is built by gathering the global tables and calling InitGlobal.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(out) | :: | this | |||
| type(Mesh2D), | intent(in) | :: | mesh |
Initialize the forest directly from GLOBAL base-mesh tables (one root per global base element, all leaves at level 0). This is the initialization path for a rank-replicated forest over a decomposed base mesh (AMR Stage 5): every rank passes the same gathered tables and holds an identical forest. rootNbr carries global element ids (0 = physical boundary), rootNbrSide/rootFlip decode the base sideInfo(4) pairing, rootBC the base boundary-condition id per side, and rootMaterial the base material id per element.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(out) | :: | this | |||
| integer, | intent(in) | :: | nRoots | |||
| integer, | intent(in) | :: | nGeo | |||
| integer, | intent(in) | :: | quadrature | |||
| real(kind=prec), | intent(in) | :: | rootCoords(1:2,1:nGeo+1,1:nGeo+1,1:nRoots) | |||
| integer, | intent(in) | :: | rootNbr(1:4,1:nRoots) | |||
| integer, | intent(in) | :: | rootNbrSide(1:4,1:nRoots) | |||
| integer, | intent(in) | :: | rootFlip(1:4,1:nRoots) | |||
| integer, | intent(in) | :: | rootBC(1:4,1:nRoots) | |||
| integer, | intent(in) | :: | rootMaterial(1:nRoots) |
Physical geometry-node coordinates of leaf leafIndex, produced by repeated exact
isoparametric subdivision of its root element along the quadtree path. geomInterp must be a
degree-nGeo Lagrange interpolant on the mesh's geometry (quadrature) nodes - the same
interpolant SELF_MeshRefinement_2D builds. Level 0 leaves return the root geometry directly.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(in) | :: | this | |||
| integer, | intent(in) | :: | leafIndex | |||
| type(Lagrange), | intent(in) | :: | geomInterp | |||
| real(kind=prec), | intent(out) | :: | coords(1:2,1:this%nGeo+1,1:this%nGeo+1) |
Highest refinement level among the active leaves.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(in) | :: | this |
Largest refinement-level difference across any leaf face (0 on a conforming or uniformly refined forest, 1 on a 2:1-balanced adaptive forest). Because FaceNeighbor returns the equal-or-larger neighbour, every level difference is observed from the finer leaf as a coarser leaf neighbour; internal (finer) neighbours contribute nothing from this side.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(in) | :: | this |
Recompute the active leaf set by depth-first traversal from the roots. Traversal (rather than a scan of all nodes) is what makes orphaned nodes left behind by coarsening invisible.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(inout) | :: | this |
Subdivide one leaf node into four children. Does nothing (with a warning) if the node is already refined. The caller is responsible for rebuilding the leaf list afterwards (or calling AdaptFromFlags, which does so).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(QuadTreeMesh2D), | intent(inout) | :: | this | |||
| integer, | intent(in) | :: | node |
type :: QuadTreeMesh2D
! ---- Base-mesh (root) reference data ----
integer :: nGeo = 0
integer :: quadrature = 0
integer :: nRoots = 0
real(prec),allocatable :: rootCoords(:,:,:,:) ! (2,nGeo+1,nGeo+1,nRoots)
! Base-mesh face connectivity at the roots (conforming base assumed). rootNbr(s,r) is the
! base neighbour element of root r across local side s (0 = physical boundary), which is also
! that neighbour's root node id; rootNbrSide / rootFlip decode base sideInfo(4,s,r).
integer,allocatable :: rootNbr(:,:) ! (4,nRoots)
integer,allocatable :: rootNbrSide(:,:) ! (4,nRoots)
integer,allocatable :: rootFlip(:,:) ! (4,nRoots)
integer,allocatable :: rootBC(:,:) ! (4,nRoots) base boundary-condition id per side
integer,allocatable :: rootMaterial(:) ! (nRoots) base material id per root element
! ---- Forest node storage (roots occupy node ids 1:nRoots) ----
integer :: nNodes = 0
integer :: capacity = 0
integer,allocatable :: level(:) ! refinement level (0 at roots)
integer,allocatable :: parent(:) ! parent node id (0 at roots)
integer,allocatable :: quadrant(:) ! child index within parent (1..4; 0 at roots)
integer,allocatable :: rootElem(:) ! base element this node descends from
integer,allocatable :: child(:,:) ! (4,capacity) child node ids (0 => leaf)
! ---- Active leaf set (rebuilt after every mutation) ----
integer :: nLeaves = 0
integer,allocatable :: leaf(:) ! (nLeaves) leaf node ids, root-major DFS order
contains
procedure,public :: Init => Init_QuadTreeMesh2D
procedure,public :: InitGlobal => InitGlobal_QuadTreeMesh2D
procedure,public :: Free => Free_QuadTreeMesh2D
procedure,public :: RefineNode => RefineNode_QuadTreeMesh2D
procedure,public :: AdaptFromFlags => AdaptFromFlags_QuadTreeMesh2D
procedure,public :: RebuildLeaves => RebuildLeaves_QuadTreeMesh2D
procedure,public :: LeafCoords => LeafCoords_QuadTreeMesh2D
procedure,public :: MaxLevel => MaxLevel_QuadTreeMesh2D
procedure,public :: FaceNeighbor => FaceNeighbor_QuadTreeMesh2D
procedure,public :: Balance2to1 => Balance2to1_QuadTreeMesh2D
procedure,public :: MaxLevelJump => MaxLevelJump_QuadTreeMesh2D
procedure,private :: EnsureCapacity => EnsureCapacity_QuadTreeMesh2D
endtype QuadTreeMesh2D