Up to Pisces Online Documentation

Adaptive Grid 2D Algorithm

( AGrid )

Overview

This algorithm locates a level set of an arbitrary 2D function. It should locate all components of the level set, even fairly small ones, and treats singularities well (though not perfectly).

How Adaptive Grid Works

A traditional method of locating the zero set of a function is to break the domain into a grid (like graph paper), and then for each square in the grid, look along the edges of the square for zeros of the function. This is usually done by evaluating the function at the corners of the square and looking for edges that have a sign change; provided the function is continuous, there will be a zero somewhere along such an edge. The position of the zero is approximated using the values of the function at the corners, usually via linear interpolation. Once the positions of the zeros along the edges of the squares are located, these zeros are joined by line segments through the interior of the square. Taken over all the squares in the grid, these line segments represent an approximation to the actual zero set of the function. To get a better approximation, one uses a finer grid.

The main drawback of this approach is that in order to obtain improved resolution, the grid must be made finer over the entire domain, including part of the domain that are far from the zero set, so a lot of work will be done even where it is unnecessary. The main idea of AGrid is to begin with a fairly course initial grid, and then refine it only where it is necessary. This allows for higher resolution in the neighborhood of singularities, for example, while still allowing for lower resolution in places where the level curve can be represented adequately by longer linear segments.

An algorithm of this sort requires a subdivision criterion that determines when a portion of the grid should be divided, and when subdivision is no longer necessary. AGrid employs several different tests in order to decide if a subdivision is needed, and these are divided into three groups: tests based on the behavior of the function along the edges of the grid; tests based on the line segments used to approximate the zero set within a region of the grid; and tests based on the subdivisions occurring within neighboring regions of the grid. If any of the tests along any edge of the region requires subdivision, the region is subdivided. Likewise, if the approximation to the zero set requires more subdivision, or if the neighboring regions suggest that subdivision is needed, then the region will be subdivided, otherwise it is no longer divided and the approximations to the zero set that it contains are added into the final representation of the zero set. The tests themselves are controlled by the parameters described below.

Controlling the algorithm from Pisces

AGrid Panel Image
The AGrid algorithm uses a triangular mesh which is obtained by taking a rectangular domain and dividing it into two triangles. Each of these triangles is then subdivided, and the resulting triangles subdivided again, and so on for a total of MIN_DEPTH times (giving 2*2^MIN_DEPTH initial triangles). A setting of 4 gives a good starting configuration. If the zeros along the edges of a triangle all pass these tests, then an approximation to the zero set within the triangle is given by the line segment joining the zeros on the boundary edges. Before this approximation is accepted, it is also tested for accuracy; its midpoint is determined, and the function value at this point is calculated, and it is tested against ABS_INTERP, and REL_INTERP (here the average of the absolute values of the function at each of the corners of the triangles is used for comparison). If the value passes both tests, then the approximated zero set is accepted, otherwise the triangle is subdivided.

Reasonable values for ABS_INTERP and REL_INTERP depend on the function you are actually using, but 0.01 for ABS_INTERP and 0.05 for REL_INTERP make good starting places. Set SHOW_DIVISIONS to 1 and increase the values if subdivisions are occurring where they are not needed, or decrease them if not enough division occurs near the zero set.

For an edge where the sign of the function differs on the endpoints, we know there is a zero somewhere on the edge; but if the signs are the same, there still might be a zero on the edge, so we need a criterion for when to subdivide such edges. First, we compute a point on the edge that is likely to be where the function is closed to zero along the edge (this calculation is based on the values of the function at the endpoints). The function is evaluated at this point; if its sign is different from that at the endpoints, then the triangle will be subdivided. Otherwise, the value is divided by the length of the edge; if the result is greater than MAX_H2W, then the function is considered to be too far from zero over that edge, and we assume there is no zero along that edge, so no subdivision is required. Otherwise, we compare the value of the function at that point to the value of the linear function connecting the values at the endpoints of the edge; if these differ by more than MODEL_CLOSE times the width of the edge, then the triangle will be subdivided. The idea here is that we are using a linear approximation to model the actual function, and if it is close enough to the value of the function, then the fact that the linear model doesn't have a zero indicates that the actual function doesn't have a zero on the edge. (The actual formula used is a bit more complicated than the one given above, and is explained in detail in the complete documentation for the algorithm.)

Reasonable values for MAX_H2W and MODEL_CLOSE depend on the actual function you are using, but values of 2 for MAX_H2W and 0.1 for MODEL_CLOSE are good starting points. Decreasing either of these parameters will cause more subdivisions to occur. Note that ABS_INTERP and REL_INTERP only come into play on edges where the function values at the endpoints have opposite signs, and MODEL_CLOSE and MAX_W2H only come into play when they have the same sign.

Known Bugs

None?

Bug Reports

software@geom.umn.edu

Algorithm Implemented by

Daniel B. Krech

Acknowledgements

Dan Krech not only implemented the algorithm, but also developed the portion of the algorithm that subdivides a triangle based on the size of its neighbors.

This code is based on an algorithm developed by Davide Cervone at the Geometry Center, though this implementation does not include all the features of the complete algorithm. The full algorithm uses tangent information to improve the results, and to locate and identify singularities and non-transverse zeros.


[Pisces] The Pisces Home Page

[HOME] The Geometry Center Home Page

Comments to: pisces@geom.umn.edu
Created: Tue Jun 6 16:27:25 CDT 1995 by Davide Cervone
Converted to html on July 25, 1995 by Erik Streed
Last Modified: July 25, 1995
Copyright © 1995 by The Geometry Center, all rights reserved.