59 | | * Step 1 |
60 | | * '''{{{ApplyOverlaps(n)}}}''' -- After initializing level {{{n}}} with prolongated data from level {{{n-1}}}, {{{AMR()}}} copies over data from the previous generation of grids on level {{{n}}}. This higher-resolution data is preferable to data prolongated from the previous level, so {{{AMR()}}} uses it wherever it is available. |
61 | | * '''{{{ApplyPhysicalBCs(n)}}}''' -- Apply physical boundary conditions to level {{{n}}}. |
62 | | * '''{{{SetErrFlags(n)}}}''' -- Determine which regions to refine. Refinement regions are determined by the physical processes involved, as well as specific conditions imposed by the problem modules. |
63 | | * '''{{{BackupNodes(n+1)}}}''' -- Caches the nodes on the child level (n+1). We are about to create the new level {{{n+1}}} nodes, and the data referenced by the backed-up nodes will be used when {{{ApplyOverlaps(n+1)}}} is called (see above). |
64 | | * '''{{{CreateChildrens(n)}}}'''-- This routine creates child nodes on level {{{n+1}}} using the refinement flags set on level {{{n}}}. The use of "Childrens" here is not a typo; {{{CreateChildrens()}}} is so named because it applies the {{{CreateChildren(Info)}}} subroutine to each grid on level {{{n}}}. |
65 | | * '''{{{InheritOldNodeOverlapsChildren(n)}}}''' -- Nested grids mean that spatial relationships (overlaps and neighbors) are inherited from parent grids. This routine passes information about the previous generation of {{{n+1}}} grids to the new grids created by {{{CreateChildrens(n)}}}. This routine is ''only'' executed on step 1 of the {{{AMR()}}} execution loop. |
66 | | * '''{{{InheritNewNodeOverlapsChildren(n)}}}''' -- The children of previous level {{{n}}} grids will also need to send their data to the children of new level {{{n}}} grids. |
67 | | * '''{{{InheritNeighborsChildren(n)}}}''' -- The children of neighboring grids on level {{{n}}} will likely be neighbors on level {{{n+1}}}. This routine passes neighbor information from level {{{n}}} to level {{{n+1}}}. |
68 | | * '''{{{AdvanceGrids(n)}}}''' -- Performs the hyperbolic advance step on the grids of level {{{n}}}. This is where our numerical solvers come in. |
69 | | * '''{{{AMR(n+1)}}}''' -- Launches AMR routine on the child level |
70 | | * '''{{{ApplyChildrenData(n)}}}''' -- The inverse of {{{ProlongateParentData()}}}, this routine restricts data from the child grids onto their parent grids, providing a more accurate solution on the coarser level. |
71 | | * '''{{{SyncFluxes(n)}}}''' -- To enforce mass conservation and the DivB constraint, the fluxes at grid boundaries need to be synchronized. |
72 | | * '''{{{AccumulateFluxes(n)}}}''' - Accumulates the fluxes used on level {{{n}}} to send back to the parent grids on level {{{n-1}}}. |
73 | | |
74 | | * Step 2 |
75 | | * !UpdateOverlaps - On the second step we don't need to receive overlap data from the previous generation of grids, however we do need to 'ghost' data with our current overlap grids or neighbors. So we think of our neighbors as our current overlaps. (Note we use the same nodelist but point to it twice with node%neighbors and node%overlaps - this is the reason we have to just !NullifyNeighbors later) |
76 | | * !ApplyOverlaps - Need to ghost data from current overlaps (neighbor grids) |
77 | | * ApplyPhysicalBCs - Apply physical boundary conditions. |
78 | | * !SetErrFlags - Determine which regions to refine |
79 | | * !AgeNodesChildren - Because of the nested grids giving us inherited relationships, we need to backup the relationships connecting us to the previous child grids on level n+1, as well as backing up the nodes themselves |
80 | | * !BackupNodes - Since we are about to create a new set of child nodes, we need to backup the previous nodes on the child level (n+1) |
81 | | * !CreateChildrens - Create child nodes on level n+1 |
82 | | * !InheritOverlapsOldChildren - Nested grids mean that spatial relationships (overlaps/neighbors) are inherited from parent grids. On the second step the previous generation of level n+1 grids are the old children of the current generation of level n grids. |
83 | | * !InheritOverlapsNewChildren - This inherits the relationships going the other way. The old children of level n grids will need to send their data to the new children of level n grids. |
84 | | * !InheritNeighborsChildren - Neighbors of children will be children of neighbors |
85 | | * !AdvanceGrids - Performs hyperbolic advance of data structures |
86 | | * AMR(n+1) - Launches AMR routine on the child level |
87 | | * !ApplyChildrenData - Inverse of !ProlongateParentData - Applies restricted data from child grids to improve solution on coarser parent grids. |
88 | | * !SyncFluxes - To enforce mass conservation and DivB constraint - common fluxes used at grid boundaries need to be synchronized. |
89 | | * !AccumulateFluxes - We need to accumulate the used fluxes to send back to our parent grids. |
90 | | * !NullifyNeighbors - Since we called !UpdateOverlaps we linked to the same nodelist with two sets of pointers (overlaps and neighbors) so we need to just nullify one of them - and destroy the other. (The destruction happens later in !BackupNodes) |
91 | | * !CoarsenDataForParent - Finally we need to coarsen our data for parent grids. |
92 | | |
93 | | |
94 | | = Book Keeping = |
95 | | Now we will add in eight routines that add functionality and perform some basic book keeping |
| 59 | |
| 60 | ==== Step 1 ==== |
| 61 | * '''{{{ApplyOverlaps(n, step)}}}''' -- After initializing level {{{n}}} with prolongated data from level {{{n-1}}}, {{{AMR()}}} copies over data from the previous generation of grids on level {{{n}}}. This higher-resolution data is preferable to data prolongated from the previous level, so {{{AMR()}}} uses it wherever it is available. |
| 62 | * '''{{{ApplyPhysicalBCs(n)}}}''' -- Apply physical boundary conditions to level {{{n}}}. |
| 63 | * '''{{{SetErrFlags(n)}}}''' -- Determine which regions to refine. Refinement regions are determined by the physical processes involved, as well as specific conditions imposed by the problem modules. |
| 64 | * '''{{{BackupNodes(n+1)}}}''' -- Caches the nodes on the child level {{{n+1}}}. We are about to create the new level {{{n+1}}} nodes, and the data referenced by the backed-up nodes will be used when {{{ApplyOverlaps(n+1)}}} is called (see above). |
| 65 | * '''{{{CreateChildrens(n)}}}'''-- This routine creates child nodes on level {{{n+1}}} using the refinement flags set on level {{{n}}}. The use of "Childrens" here is not a typo; {{{CreateChildrens()}}} is so named because it applies the {{{CreateChildren(Info)}}} subroutine to each grid on level {{{n}}}. |
| 66 | * '''{{{InheritOldNodeOverlapsChildren(n)}}}''' -- Nested grids mean that spatial relationships (overlaps and neighbors) are inherited from parent grids. This routine passes information about the previous generation of {{{n+1}}} grids to the new grids created by {{{CreateChildrens(n)}}}. This routine is ''only'' executed on step 1 of the {{{AMR()}}} execution loop. |
| 67 | * '''{{{InheritNewNodeOverlapsChildren(n)}}}''' -- The children of previous level {{{n}}} grids will also need to send their data to the children of new level {{{n}}} grids. |
| 68 | * '''{{{InheritNeighborsChildren(n)}}}''' -- The children of neighboring grids on level {{{n}}} will likely be neighbors on level {{{n+1}}}. This routine passes neighbor information from level {{{n}}} to level {{{n+1}}}. |
| 69 | * '''{{{AdvanceGrids(n)}}}''' -- Performs the hyperbolic advance step on the grids of level {{{n}}}. This is where our numerical solvers come in. |
| 70 | * '''{{{AMR(n+1)}}}''' -- Launches AMR routine on the child level |
| 71 | * '''{{{ApplyChildrenData(n)}}}''' -- The inverse of {{{ProlongateParentData()}}}, this routine restricts data from the child grids onto their parent grids, providing a more accurate solution on the coarser level. |
| 72 | * '''{{{SyncFluxes(n)}}}''' -- To enforce mass conservation and the DivB constraint, the fluxes at grid boundaries need to be synchronized. |
| 73 | * '''{{{AccumulateFluxes(n)}}}''' -- Accumulates the fluxes used on level {{{n}}} to send back to the parent grids on level {{{n-1}}}. |
| 74 | |
| 75 | ==== Step 2 ==== |
| 76 | * '''{{{UpdateOverlaps(n)}}}''' -- On the second step we don't need to receive overlap data from the previous generation of grids. We do, however, need to 'ghost' data with our current overlap grids or neighbors. So we treat our neighbors as our current overlaps; in effect, we use the same node list for neighbor operations and overlap operations. This is the reason why we use the {{{NullifyNeighbors()}}} routine later on instead of deleting the node list. |
| 77 | * '''{{{ApplyOverlaps(n, step)}}}''' - Brings over ghost data from the neighbor grids, which are the current overlaps. This neighbor grid data has been advanced by the {{{AdvanceGrids()}}} subroutine, and thus is more accurate than the extrapolated data within the grid's ghost zones. |
| 78 | * '''{{{ApplyPhysicalBCs(n)}}}''' -- Apply physical boundary conditions to level {{{n}}}. |
| 79 | * '''{{{SetErrFlags(n)}}}''' -- Determine which regions to refine. Refinement regions are determined by the physical processes involved, as well as specific conditions imposed by the problem modules. |
| 80 | * '''{{{AgeNodesChildren(n)}}}''' - Because of the nested grids giving us inherited relationships, we need to backup the relationships connecting us to the previous child grids on level {{{n+1}}}, as well as backing up the nodes themselves. |
| 81 | * '''{{{BackupNodes(n+1)}}}''' -- Caches the nodes on the child level {{{n+1}}}. We are about to create the new level {{{n+1}}} nodes, and the data referenced by the backed-up nodes will be used when {{{ApplyOverlaps(n+1)}}} is called (see above). |
| 82 | * '''{{{CreateChildrens(n)}}}'''-- This routine creates child nodes on level {{{n+1}}} using the refinement flags set on level {{{n}}}. The use of "Childrens" here is not a typo; {{{CreateChildrens()}}} is so named because it applies the {{{CreateChildren(Info)}}} subroutine to each grid on level {{{n}}}. |
| 83 | * '''{{{InheritOverlapsOldChildren(n)}}}''' -- Nested grids mean that spatial relationships (overlaps/neighbors) are inherited from parent grids. On the second step the previous generation of level {{{n+1}}} grids are the old children of the current generation of level {{{n}}} grids. |
| 84 | * '''{{{InheritOverlapsNewChildren(n)}}}''' -- This inherits the relationships going the other way. The old children of level n grids will need to send their data to the new children of level n grids. |
| 85 | * '''{{{InheritNeighborsChildren(n)}}}''' -- The children of neighboring grids on level {{{n}}} will likely be neighbors on level {{{n+1}}}. This routine passes neighbor information from level {{{n}}} to level {{{n+1}}}. |
| 86 | * '''{{{AdvanceGrids(n)}}}''' -- Performs the hyperbolic advance step on the grids of level {{{n}}}. This is where our numerical solvers come in. |
| 87 | * '''{{{AMR(n+1)}}}''' -- Launches AMR routine on the child level |
| 88 | * '''{{{ApplyChildrenData(n)}}}''' -- The inverse of {{{ProlongateParentData()}}}, this routine restricts data from the child grids onto their parent grids, providing a more accurate solution on the coarser level. |
| 89 | * '''{{{SyncFluxes(n)}}}''' -- To enforce mass conservation and the DivB constraint, the fluxes at grid boundaries need to be synchronized. |
| 90 | * '''{{{AccumulateFluxes(n)}}}''' -- Accumulates the fluxes used on level {{{n}}} to send back to the parent grids on level {{{n-1}}}. |
| 91 | * '''{{{NullifyNeighbors(n)}}}''' -- On the second step, each node's neighbor list and overlap list is pointing to the same list (the node's neighbor list). This routine nullifies the neighbor list pointers without destroying the nodes they point to. In effect, this turns the current generation's neighbor lists into the next generation's overlap lists. On the next step, the {{{BackUpNodes()}}} routine will destroy the overlap nodes. |
| 92 | * '''{{{CoarsenDataForParent(n)}}}''' -- Now that both advance steps are complete for this level, it's time to coarsen the cell-centered data back down to the {{{n-1}}} level grids. |
| 93 | |
| 94 | [[BR]] |
| 95 | == Round 2: Refined Bookkeeping and Elliptic Solvers == |
| 96 | |
| 97 | Now that we have constructed a simple AMR routine, we will add a few routines to improve MHD calculations and simplify AMR tree management. We will also add the elliptic solver step to the code, expanding the capabilities of our AMR routine. |