November 05 2004

Abstract

A brief description of how to use AMR.

This thorn is a regridding thorn to work with Carpet. It is meant to directly replace the standard CarpetRegrid thorn and many of the parameters are based directly on standard parameters that people already use. However, this thorn is meant to provide full Adaptive Mesh Reﬁnement (AMR). The thorn is not complete by itself; as described below, an error indicator needs to be given.

As those that use mesh reﬁnement will know, the question of where to put the reﬁned grids is as much art as science. The crucial points are the following:

- We wish to reﬁne as few points as possible. The reason for this is to reduce memory overhead and to reduce runtime. The latter is particularly important as the runtime is essentially dominated by the ﬁnest level(s).
- We wish to create as few new grids as possible. The reason for this is that the ghost zones required for the boundaries of the grids are, in a sense, a waste of computational time. Therefore the larger the boundaries the more time the code will spend ﬁlling zones that have no beneﬁt for the evolution. The more grids, the larger the boundary for any given beneﬁt.
- We wish to place the reﬁned grid(s) where they will do the most good; that is, where the error is highest. This allows us to get a (more) uniform error over the whole domain.

Therefore the problem to be solved is to balance requirements (1) and (2) in a sensible way whilst ensuring that the error is minimized as required by point (3).

The process by which this is achieved is twofold:

- An approximation to the error is found. For “true” AMR this is usually meant to be an approximation to the truncation error found using Richardson extrapolation and a shadow heirachy. However, this can be expensive and may not work well at low resolutions (particularly in the Carpet case when a large number of buﬀer zones are in use). Instead a separate approximation can be used (often called an error indicator instead of a true error estimate) based on certain physical properties of the solution, such as a curvature based method (such as is used in Paramesh).
- The points marked in error are then “clustered” into Cartesian boxes. The Cartesian boxes can either be pre-determined (as in Paramesh) or computed on-the-ﬂy, as done here. It might be that a box is reﬁned only if a certain fraction of its points are marked in error (I believe this is the Paramesh approach) or that every point marked in error is contained in a reﬁned box, which is the approach taken here.

Essentially, this thorn requires somebody else to compute the approximation to the error and to store it in a grid function. It will then cluster the points in error, providing Carpet with a new grid structure.

For those that want the real details, this is basically an implementation of the clustering algorithm of Berger and Rigoutsos [1].

As a user you should just replace CarpetRegrid with CarpetAdaptiveRegrid in your parameter ﬁle and set the appropriate parameters correctly:

- Carpet::domain_from_coordbase. This must be set to "yes". It follows that you must set your domain using the coordbase parameters. Some examples can be found in the par/ directory of this thorn.
- min_width. This describes the minimum width of a grid in any direction. Note that if the entire global domain is smaller than this in a given direction then it will be ignored for that direction (local domain sizes will be treated in the correct, processor independent manner). The value of this should be set dependent on the number of Carpet ghost_zones and buffer_zones you are using; for example, with 3 ghost_zones and 6 buffer_zones I would set this to be at least 20 ($>2\times \left(3+6\right)$).
- min_fraction. This describes the minimum fraction of points marked in error that a candidate reﬁned box should have before it is accepted. Note that this may be ignored if the result would be to produce a box that is too small. This should not be set too high or the algorithm will produce large numbers of small boxes; I would recommend a value between 0.5 and 0.8.
- max_error. If the absolute value of the grid function being used as an approximation to the error is above this the point is marked in error; if not, the point is marked as ﬁne. Sensible values depend entirely on the method used to compute the error approximation and you’ll almost certainly need to experiment.
- error_var. The name of the grid function containing the approximation to the error. Should have the form Thorn::Var. Should be a real grid function with storage, probably with only one timelevel, and almost certainly should have the tags table entry tags=’Prolongation="None"’ (otherwise the error function will be the same on diﬀerent reﬁnement levels, which is not what you want).
- regrid_every. How often the regridding algorithm is called; semantically it’s identical to the parameter in CarpetRegrid. Again, the value of this parameter probably requires some experimentation. Note, however, that successively reﬁning a region many times at short notice often does not give good results, as it is similar to repeatedly interpolating the grid functions in that region.
- pad. When the error is computed and points are marked in error or not, the result is “padded” by a certain number of points. This ensures that it doesn’t try to regrid a single point - this will always be padded out to something larger. It also ensures that if the computation of the error estimate was non-local (i.e., required taking derivatives) then inter-processor boundaries don’t cause problems. It also ensures that if a feature is near the threshold of being reﬁned the error doesn’t have “gaps” where points fall just below the threshold. Finally, it ensures that the reﬁned grid is big enough to allow the interesting feature to move within it. The value for this should be set with these considerations in mind; typically I would choose 4-8 points but if regrid_every is large, or the features are moving rapidly on the grid, or you have a large number of ghost_zones, then you may wish to increase it to 12 or more.
- verbose and veryverbose. Prints large amounts of debugging information about the grid locations. I wouldn’t use these unless you want to debug.
- refinement_levels. The number of reﬁnement levels to be set up initially, including the base grid. Again this follows the semantics of CarpetRegrid. At the initial time the grid structure is determined not from the error function (as it may not have been computed as yet) but instead from this parameter and the coordinates parameter: