# AMR refinement criteria¶

Several parameters controlling refinement can be set in the setrun function. See Specifying AMRClaw run-time parameters in setrun.py for further description of these. Many of the parameters discussed below are attributes of rundata.amrdata in setrun.py.

Every regrid_interval time steps on each level, the error is estimated in all cells on grids at this level. Cells where some refinement criteria are satisfied are flagged for refinement. Default options for flagging are described below. Additional cells surrounding the flagged cells are also flagged to insure that moving features of the solution (e.g. shock waves) do not escape from the region of refinement before the next regridding time. The number of buffer cells flagged is specified by regrid_buffer_width and the number of steps between regridding on each level is specified by regrid_interval. Typically these are equal (assuming the Courant number is close to 1) and taken to be some small integer such as 2 or 3.

In addition to flagging individual cells based on the behavior of the solution, it is also possible to specify that certain regions of the domain should always be refined to a certain level (and/or never refined above some level). This is described further in Specifying AMR regions. These regions are used in conjunction with the methods described below to determine whether or not a given cell should be flagged for refinement.

The cells that have been flagged are then clustered into rectangular regions to form grids at the next finer level. The clustering is done in light of the tradeoffs between a few large grids (which usually means refinement of many additional cells that were not flagged) or many small grids (which typically results in fewer fine grid cells but more grids and hence more overhead and less efficient looping over shorter rows of cells). The parameter clustering_cutoff in amrNez.data is used to control this tradeoff. At least this fraction of the fine grid cells should result from coarse cells that were flagged as needing refinement. The value clustering_cutoff = 0.7 is usually reasonable.

## Flagging criteria¶

Two possible approaches to flagging individual cells for refinement (based on the behavior of the solution) are built into AMRClaw. (A different default approach is used in GeoClaw, see Flagging criteria in GeoClaw).

### flag2refine¶

One approach to flagging cells for refinement (the default used in most examples) is to set flag2refine == True and specify a tolerance flag2refine_tol. This indicates that the library subroutine $CLAW/amrclaw/src/Nd/flag2refine.f90 should be used to flag cells for refinement. This routine computes the maximum max-norm of the undivided difference of \(q_{i,j}\) based its four neighbors in two space dimensions (or 6 neighbors in 3d). If this is greater than the specified tolerance, then the cell is flagged for refinement (subject to limitations imposed by “regions”). The undivided difference (not divided by the mesh width) is used, e.g. \(|q(m,i+1,j) - q(m,i-1,j)|\) for each component \(m\).

Note that the user can change the criterion used for flagging cells by modifying this routine – best done by copying the library routine to your application directory and modifying the Makefile to point to the modified version.

### Richardson extrapolation¶

The second approach to flagging individual cells is based on using Richardson extrapolation to estimate the error in each cell. This is used if flag_richardson == True. In this case a cell is flagged if the error estimate exceeds the value flag_richardson_tol. Richardson estimation requires taking two time steps on the current grid and comparing the result with what’s obtained by taking one step on a coarsened grid. One time step on the fine grid is re-used, so only one additional time step on the fine grid and one on a coarsened grid are required. It is somewhat more expensive than the flag2refine approach, but may be more useful for cases where the solution is smooth and undivided differences do not identify the regions of greatest error.

**Note:** Both approaches can be used together: if
flag2refine == True and flag_richardson == True
then a cell will be flagged if either of the corresponding specified
tolerances is exceeded.

## Specifying AMR regions¶

In addition to specifying a tolerance or other criteria for flagging
individual cells as described above, it is possible to specify regions of
the domain so that all points in the region, over some
time interval also specified, will be refined to at least some level
*minlevel* and at most some level *maxlevel*.
These are specified through the parameter rundata.regiondata.regions in
setrun.py.
This is a list of lists, each of which specifies a region. A new region can
be added via:

```
rundata.regiondata.regions.append([minlevel,maxlevel,t1,t2,x1,x2,y1,y2])
```

This indicates that over the time period from t1 to t2, cells in the rectangle x1 <= x <= x2 and y1 <= y <= y2 should be refined to at least minlevel and at most maxlevel.

To determine whether a grid cell lies in one of the regions specified, the center of the grid cell is used. If a mapped grid is being used, the limits for the regions should be in terms of the computational grid coordinates, not the physical coordinates.

If a cell center lies in more than one specified region, then the
cell will definitely be flagged for refinement at level L (meaning it should
be covered by a Level L+1 grid) if *L+1 <= minlevel* for any of the regions,
regardless of whether the general flagging criteria hold or not.
This means the smallest of the various *minlevel* parameters for any region
covering this point will take effect. Conversely it will **not**
be flagged for refinement if *L+1 > maxlevel* for **all** regions that cover
this point. This means the largest of the various *maxlevel* parameters for
any region covering this point will take effect.
(However, note that since flagged cells are buffered as described above by
flagging some adjacent cells, a cell may still end up flagged for refinement
even if the above tests say it should not be.)

For example, suppose that amr_levels_max = 6 has been specified along with these two regions:

```
rundata.regiondata.regions.append([2, 5, 10.0, 30.0, 0.0, 0.5, 0.0, 0.5])
rundata.regiondata.regions.append([3, 4, 20.0, 40.0, 0.2, 1.0, 0.2, 1.0])
```

The first region specifies that from time 10 to 30 there should be at least 2 levels and at most 5 levels of refinement for points in the spatial domain 0 < x < 0.5 and 0 < y < 0.5.

The second region specifies that from time 20 to 40 there should be at least 3 level and at most 4 levels of refinement for points in the spatial domain 0.2 < x < 1.0 and 0.2 < y < 1.0.

Note that these regions overlap in both space and time, and in regions of
overlap the *maximum* of the minlevel and also the *maximum* of the
maxlevel parameters applies. So in the above example, from time 20 to 30
there will be at least 3 levels and at most 5 levels in the region of
overlap, 0.2 < x < 0.5 and 0.2 < y < 0.5.

Within these regions, how many levels are chosen at each point will be
determined by the *error flagging criteria*, i.e. by the default
or user-supplied routine flag2refine, or as
determined by Richardson extrapolation, as described above.

Points that are not covered by either region are not constrained by the regions at all. With amr_levels_max = 6 then they might be refined to any level from 1 to 6 depending on the error flagging criteria.

It is easiest to explain how this works by summarizing the implementation:

The regridding algorithm from level L to L+1 loops over all grid cells at Level L and flags them or not based on the following criteria, where (xc,yc) represents the cell center and t is the current regridding time:

- Initialize the flag by applying the error flagging criteria specified by Richardson extrapolation and/or the default or user-supplied routine flag2refine to determine whether this cell should be flagged.
- Loop over all regions (if any) for which (xc,yc,t) lies in the region specified.

TODO: This might be wrong!!!

- If L >= maxlevel for
anysuch region, set flag = False for this cell and go on to the next cell.- If L < minlevel for
everysuch region, set flag = True and go on to the next grid cell.

## Flagging criteria in GeoClaw¶

In GeoClaw, a special flag2refine subroutine is defined.

TODO: need to describe geoclaw flag2refine.