| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| type(SEMQuad), | public, | pointer | :: | activeGeom | => | null() | geometry the model currently runs on |
| type(Mesh2D), | public, | pointer | :: | activeMesh | => | null() | mesh the model currently runs on |
| type(Mesh2D), | public, | pointer | :: | baseMesh | => | null() | caller-owned; metadata source for EmitMesh |
| real(kind=prec), | public | :: | coarsenThreshold | = | 0.0_prec | ||
| type(QuadTreeMesh2D), | public | :: | forest | ||||
| type(SEMQuad), | public, | pointer | :: | genGeom | => | null() | Cumulative geometry-reuse accounting (AMR Stage 6c), so a run can report what fraction of elements avoided regeneration rather than leaving the payoff to be estimated. |
| type(SEMQuad), | public, | pointer | :: | geomA | => | null() | |
| type(SEMQuad), | public, | pointer | :: | geomB | => | null() | |
| integer, | public | :: | geomSlot | = | 0 | Scratch geometry holding just the elements an epoch actually changed, generated compacted and then scattered into place. Persistent and resized, so it allocates only when an epoch changes more elements than any epoch before it. |
|
| type(RefinementIndicator2D), | public | :: | indicator | ||||
| type(Lagrange), | public, | pointer | :: | interp | => | null() | the model's solution interpolant |
| integer, | public | :: | ivar | = | SELF_AMR_ALLVARS | driving variable for the indicator |
|
| integer, | public | :: | maxLevel | = | 1 | refinement-level cap |
|
| integer(kind=int64), | public | :: | nGeomGenerated | = | 0 | ||
| integer(kind=int64), | public | :: | nGeomReused | = | 0 | ||
| integer, | public | :: | nHalo | = | 1 | refine-flag halo-expansion passes |
|
| logical, | public | :: | ownsActive | = | .false. | whether activeMesh was emitted by us (vs the caller's) Two long-lived geometry buffers, alternated each epoch (AMR Stage 6c). Geometry is now resized in place rather than allocated and freed per epoch, which is what lets Stage 6b's amortization apply to it; alternating means the PREVIOUS epoch's geometry is still intact while the new one is filled, which the incremental reuse path needs. geomSlot records which buffer activeGeom currently is, or 0 while it is still the caller's geometry. |
|
| real(kind=prec), | public | :: | refineThreshold | = | 0.0_prec |
Perform one adaptation epoch on the model (see the module documentation). On return, adapted reports whether the mesh changed; when it did, the model is already rebound to the new mesh with the solution transferred (conservatively), and the caller should re-evaluate its time step (RecommendedTimeStep) before the next ForwardStep. When the leaf set is unchanged the model is untouched.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(AMRController2D), | intent(inout) | :: | this | |||
| class(DGModel2D_t), | intent(inout) | :: | model | |||
| logical, | intent(out) | :: | adapted |
Fill newGeom for the emitted mesh, reusing the previous epoch's geometry for every element that did not change and generating only the rest (AMR Stage 6c). nReused reports how many elements were copied rather than computed.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(AMRController2D), | intent(inout) | :: | this | |||
| type(Mesh2D), | intent(in) | :: | newMesh | |||
| type(TransferPlan2D), | intent(in) | :: | plan | |||
| type(SEMQuad), | intent(inout) | :: | newGeom | |||
| integer, | intent(out) | :: | nReused |
Release the forest, the indicator, and any controller-emitted mesh/geometry. The caller-owned base mesh/geometry are untouched. A model still pointing at a controller-emitted mesh must not be used after this call.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(AMRController2D), | intent(inout) | :: | this |
Attach the controller to an initialized model. The model's current mesh becomes the forest's base mesh (level 0); its geometry interpolant drives the indicator and the solution transfer. Thresholds are the sigma = log10 modal-energy-ratio cut-offs of the refinement indicator (refineThreshold > coarsenThreshold; see SELF_RefinementIndicator_2D). ivar is the driving solution variable (or SELF_AMR_ALLVARS). maxLevel >= 0 caps the refinement depth; nHalo >= 0 sets the refine-flag halo width in elements.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(AMRController2D), | intent(out) | :: | this | |||
| class(DGModel2D_t), | intent(in) | :: | model | |||
| real(kind=prec), | intent(in) | :: | refineThreshold | |||
| real(kind=prec), | intent(in) | :: | coarsenThreshold | |||
| integer, | intent(in) | :: | ivar | |||
| integer, | intent(in) | :: | maxLevel | |||
| integer, | intent(in) | :: | nHalo |
Select the geometry buffer to fill this epoch: whichever of the two is not currently active, so the previous epoch's geometry stays intact and readable (AMR Stage 6c).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(AMRController2D), | intent(inout) | :: | this | |||
| integer, | intent(in) | :: | nElem | |||
| type(SEMQuad), | intent(out), | pointer | :: | geom | ||
| integer, | intent(out) | :: | slot |
Level-based explicit-stability time step: refinement halves the element scale per level, so a time step dtBase that is stable on the base (level-0) mesh scales to dtBase / 2**MaxLevel on the current forest. Deterministic and exact for the quadtree (child elements are exact half-scale subdivisions); no geometry reduction is needed.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(AMRController2D), | intent(in) | :: | this | |||
| real(kind=prec), | intent(in) | :: | dtBase |
type :: AMRController2D
type(QuadTreeMesh2D) :: forest
type(RefinementIndicator2D) :: indicator
type(Mesh2D),pointer :: baseMesh => null() !! caller-owned; metadata source for EmitMesh
type(Mesh2D),pointer :: activeMesh => null() !! mesh the model currently runs on
type(SEMQuad),pointer :: activeGeom => null() !! geometry the model currently runs on
type(Lagrange),pointer :: interp => null() !! the model's solution interpolant
logical :: ownsActive = .false. !! whether activeMesh was emitted by us (vs the caller's)
!! Two long-lived geometry buffers, alternated each epoch (AMR Stage 6c). Geometry is now
!! resized in place rather than allocated and freed per epoch, which is what lets Stage 6b's
!! amortization apply to it; alternating means the PREVIOUS epoch's geometry is still intact
!! while the new one is filled, which the incremental reuse path needs. geomSlot records
!! which buffer activeGeom currently is, or 0 while it is still the caller's geometry.
type(SEMQuad),pointer :: geomA => null()
type(SEMQuad),pointer :: geomB => null()
integer :: geomSlot = 0
!! Scratch geometry holding just the elements an epoch actually changed, generated compacted
!! and then scattered into place. Persistent and resized, so it allocates only when an epoch
!! changes more elements than any epoch before it.
type(SEMQuad),pointer :: genGeom => null()
!! Cumulative geometry-reuse accounting (AMR Stage 6c), so a run can report what fraction of
!! elements avoided regeneration rather than leaving the payoff to be estimated.
integer(int64) :: nGeomReused = 0
integer(int64) :: nGeomGenerated = 0
integer :: ivar = SELF_AMR_ALLVARS !! driving variable for the indicator
integer :: maxLevel = 1 !! refinement-level cap
integer :: nHalo = 1 !! refine-flag halo-expansion passes
real(prec) :: refineThreshold = 0.0_prec
real(prec) :: coarsenThreshold = 0.0_prec
contains
procedure,public :: Init => Init_AMRController2D
procedure,public :: Free => Free_AMRController2D
procedure,public :: Adapt => Adapt_AMRController2D
procedure,public :: RecommendedTimeStep => RecommendedTimeStep_AMRController2D
procedure,private :: NextGeomBuffer => NextGeomBuffer_AMRController2D
procedure,private :: BuildGeometry => BuildGeometry_AMRController2D
endtype AMRController2D