Skip to main content

NAO


NAO Interface Class NARegularGrid

Overview


The NARegularGrid class is a base class representing all regular grids. Regular grids seem to be one of those things that everyone knows when they see one, but for which good precise definitions don't exist. The definition of a NARegularGrid includes tensor products of stretched one-dimensional grids, but the interface also supports grids with cells missing, or with extra cells. So both of the grids below are covered by the class:
I don't know what you call the second (but its regular under this definition 8-)} The green edges are to be identifed with each other, as are the magenta edges.

In addition to the interface to the general celluar complex that a discrete manifold presents, a NARegularGrid provides information about neighboring vertices in each of the coordinate directions, and mesh spacings in the same directions. In two dimensions this means that the cells are quadrilaterals, and except for edge cells where there are no neighbors in one direction, there are four immediate neighbors of each vertex, and functions which define the mesh spacing in the "x" and "y" directions.


User's Guide


To use this class, include the header file
NAO/RegGrid.h
and link against library
libNAOBase.a
The following member functions are available when classes are derived from this interface class, in addition to those provided by the parent class NARegion.

Pure Virtual Member Functions, which must be provided by derived classes:

Virtual Member Functions, which may or may not be provided by derived classes:
non Virtual Member Functions, which are provided by this base class and may not be replaced by a derived class:
The following classes are children of this base class:

Programmer's Guide


There is no additional data associated with the NARegularGrid base class, only the additional interfaces that it defines.

The first set of interfaces

provide information about the neighbors of a vertex. For each coordinate direction, there are two neighbors, one in the positive direction (the next vertex), and the other in the other direction (the previous vertex). The figure below shows this for a three dimensional mesh:

Vertices on the boundaries of the grid may be missing one or mor of these neighbors. In that case, the convention is that the neighbor queries return an invalid vertex number, -1.

For a regular three dimensional grid, indexed by (i,j,k), each running bewteen (0,0,0) and (nx,ny,nz), we have that the index of a vertex is

I= i + nx*(j+ny*k)

The neighors are easily found
next(I,0) = I+1
prev(I,0) = I-1
next(I,1) = I+nx
prev(I,1) = I-nx
next(I,2) = I+nx*ny
prev(I,2) = I-nx*ny

Boundaries can be dealt with in a couple of ways. Notice that
i=mod(I,nx)
j=mod(floor(I/nx),ny)
k=floor(I/nx/ny)

I have found that these interfaces are easy to implement, much more so than the routines that ask for a global numbering of the edges and faces in a three dimensional regular grid.

The second set of new interfaces

provides information about the mesh spacing, as a function of position in the grid. Notice that we have separated the topological information about the grid to which the first set of interfaces allows access, from this spacing information.

Each coordinate direction has a spacing. For "rectangular" meshes, where the spacing between grid points is constant, the meaning of the spacing is clear. I'm not sure how those who implement regular grids with variable mesh spacings will choose to interpret these functions.


Example


Particular examples can be found in documentation for the child classes of this base class. As an example of the base class, let me show how they can be used to implement a finite difference stencil, since that was the main motivation for the interfaces.

Consider the difference scheme

(L f)_{i+1/2,j+1/2,k+1/2} = (f_{i+1,j,k}-f_{i,j,k})/|x_{i+1,j,k}-x_{i,j,k}|
+ (f_{i,j+1,k}-f_{i,j,k})/|x_{i,j+1,k}-x_{i,j,k}|
+ (f_{i,j,k+1}-f_{i,j,k})/|x_{i,j,k+1}-x_{i,j,k}|

This might be done in the following way:


  NAFunction *Fhx=grid->getMeshSpacingFn(0);
  NAFunction *Fhy=grid->getMeshSpacingFn(1);
  NAFunction *Fhz=grid->getMeshSpacingFn(2);

  int n=grid->getNumberOfVertices();
  for(i=0;i<n;i++)
   {
    g[i]=0;

    i1=grid->getNextNeighboringVertex(i,0);
    grid->getVertex(i1,v1);
    Fhx->evaluate(v1,hx1);
    grid->getVertex(i,v);
    Fhx->evaluate(v,hx);
    h=.5*(hx1->getDoubleCoordinate(0)+hx->getDoubleCoordinate(0));
    g[i]+=(f[i1]-f[i])/h;

    i1=grid->getNextNeighboringVertex(i,1);
    grid->getVertex(i1,v1);
    Fhy->evaluate(v1,hy1);
    grid->getVertex(i,v);
    Fhy->evaluate(v,hy);
    h=.5*(hy1->getDoubleCoordinate(0)+hy->getDoubleCoordinate(0));
    g[i]+=(f[i1]-f[i])/h;

    i1=grid->getNextNeighboringVertex(i,2);
    grid->getVertex(i1,v1);
    Fhz->evaluate(v1,hz1);
    grid->getVertex(i,v);
    Fhz->evaluate(v,hz);
    h=.5*(hz1->getDoubleCoordinate(0)+hz->getDoubleCoordinate(0));
    g[i]+=(f[i1]-f[i])/h;
   }

I've left out a couple of things, and haven't done other things I might to speed this up a bit, or to handle boundaries, but I think the main idea is clear.


Related Classes and Subroutines


The parent of this Interface class:

Siblings of this Interface class:

Children of this Interface class:

The Finite Difference classes are based on functions defined on regular grids. See for example, the classes:


Created: Fri Oct 9 14:44:21 EDT 1998

[Comments | NAO home page ]

[Research home page]

[ IBM home page | Order | Privacy | ContactIBM | Legal ]