Definition of a Cogeometry

There are a lot of different technical realizations of the dual concept. So, a simple dualization leads to a function which returns for a given simplex and a segment of the related codimension their intersection index. Such a realization may be easier to use in theoretical considerations, but not for implementation. We try to find here a variant which allows easy implementation and usage.

The Continuous Case

Now we want to introduce the definition of a cogeometry for exact real arithmetics. But, at first, let's consider shortly how we use some notions like in general and natural. They look very informal, but have a well-defined formal sense.

The notion in general may be formalized using the concept of transversality. In this concept we distinguish between the "generic situation" of "transverse intersection" and "degenerated situations". They may be characterized by two properties:

That means the generic situation defines an open, dense subset in the set of all possible situations. Usually it is very easy to find in a concrete situation what is the generic situation and what is degenerated. In the generic situation, a sub-manifold of dimension k has an intersection with a sub-manifold of codimension l if k >=l. It is a smooth sub-manifold of dimension (k-l), and the intersection is transverse. That means, the tangential space in the intersection point will be generated by the tangential subspaces of the two sub-manifolds. Pre-images of sub-manifolds will be sub-manifolds.

To obtain formal results it is necessary to fix the related spaces of manifolds. It is always possible to use smooth manifolds and functions. To obtain the correct number of derivatives which has to be defined is more complicate, especially it depends on the dimensions of the involved manifolds. The basic result is the theorem of Sard [Sard1942] . Related results and techniques which allow to establish such results you can find in [Hirsch1976] .

There will be different possibilities to handle the degenerate cases. In a degenerate situation we have different possible results which may be obtained as the limit from different directions. There are different strategies:

The strategy used here is not relevant for the problems of implementation, because the problem of degenerate cases will be covered by another serious problem --- the rounding errors. That's why we simply use the first strategy and define the cogeometry only for the generic case. Compared with the other strategies, we sometimes have to add "in general" even if the other strategies may allow to omit this.

The notion natural will be used to describe an important property of a construction related with mappings. Assume we have a construction which allows to create some object on Y for a given object on X and a mapping f: X --> Y. This construction is natural if a composition property will be fulfilled: If we consider the composition of f with g: Y --> Z, the construction for the composition of the mappings leads to the same object on Z as the composition of the constructions for the two mappings.

In the following, we use the short, informal notions "in general" and "natural" having in mind that they may be transformed into exact results. We do not give these exact formulations because they will be straightforward from point of view of theoretical mathematics, and the main interest of the "theoretical part" is to show that the concept of cogeometry is very natural from theoretical point of view.

Let's now introduce the basic object. The required properties of these objects we define later.

A k-segment S_k
is a closed submanifold with boundary of codimension k.
A k-simplex
is a continuous mapping from the standard k-dimensional reference simplex into X. In the case of a smooth manifold, it makes sense to consider only smooth mappings.
A side of a k-simplex
is a (k-1)-simplex defined by the mapping of the related side of the reference simplex. To avoid exceptions we define the side of a 0-simplex as the empty object.
A k-flag
consists of a point p (called position), a sequence of (k+1) segments (S_0,...,S_k) and k orthogonal directions (d(1),...,d(k)). To avoid exceptions we define the flag also for k = -1 as the empty object.
An intersection of a k-simplex
may be a k-flag with position in the simplex --- an inner intersection --- or a (k-1)-flag on a side of the simplex --- a boundary intersection.
The intersection function f(k)
allows to find intersections of k-simplices. Input is a k-simplex and an inititial intersection of the simplex. The result is another intersection of the same simplex which we call the continuation of the first intersection through the simplex.
A cogeometry G(X)
is a sequence of functions f(k) for k >= 0.
Before we define the properties required for these objects, let's define them for the case of a n-dimensional geometry described by a smooth cell complex. We consider only smooth simplices.

In this case, the position of a k-flag is inside the segmentS_k and is a boundary point for all S_i with i < k, S_i is part of the boundary of S_j for i > j, the direction d(i) is in p tangential to S_j for j < i, orthogonal to S_j . It points into S_i-1.

For an inner intersection, we require not only that the position of the flag is inside the simplex, but also that the projections of the flag directions into the plane of the simplex define a non-degenerate volume. This allows to define an orientation of the intersection.

Now let's define the intersection function f(k). The input flag defines a point on some (k-1)-segment S_k-1. Consider the intersection of the k-simplex with this segment, especially the component containing the initial point. In the generic situation we obtain a smooth 1-dimensional manifold, and the initial intersection is one of the two ends of this curve. The position of the return value is the second end of this curve. The related flag we obtain using the continuation of the flag along the curve. For degenerate cases we do not define the function.

This description may fail, if it is not possible to continue the flag because of a change of the neighbourhood relations in some intermediate point of the curve. To avoid this effect we have to require that such intermediate points must be part of some boundary of codimension k. For an arbitrary geometry, this may be obtained by further subdivision of the related boundaries into parts with identical neighbourhood relations.

Let's define now the properties of a cogeometry. The strategy we use to fix these properties is to find properties which are fulfilled for our example. Let's list at first the most obvious properties:

Obviously these properties make sense for every geometry. Especially the last allows to localize the problem: The geometry will be completely defined by the results of f(k) for arbitrary small simplices.

To complete the definition, we have to add a condition which describes the local behaviour of the geometry. This may be a condition of the following type:

or another set of local regularity conditions which allows to build such a homeomorphism. Different variants of this condition allow to define different classes of smoothness of a cogeometry.

The Codimension of a Cogeometry

The codimension of a cogeometry is the highest codimension of a segment of the cogeometry. For a cogeometry of codimension k it is not possible to define input values for f(l) with l > k+1. So, such a cogeometry will be completely defined by the sequence of the f(l) between 0 and k+1. Because of this simplification it is useful to have information about the codimension. We have the following obvious properties of the codimension: Thus, for the most interesting operations we can compute the codimension explicitly.

Connection to Morse Theory

There is a natural connection between the cogeometry and Morse functions (see [Morse1934] , [Milnor1963] ): A Morse function on a space X defines a cogeometry. Each segment of this cogeometry will be related to a singularity of the Morse function. The segment may be defined as the set of points so that the limit of the gradient flow is the related singularity. The codimension of the segment is obviously the index of the singularity.

This connection shows that a cogeometry is a very natural object from mathematical point of view. It also shows that a cogeometry may be defined also for spaces of infinite dimension. A space which allow to define a Morse function on it, allows also to define a cogeometry. This shows that the class of spaces which allow a cogeometry is greater than the class of spaces which allow a standard geometry description.

The Implementation in Finite Precision Arithmetics

Now let's consider some modifications of the concept for the continuous case which will be necessary or useful for an implementation of the concept.

Affine Simplices

At first, for simplices we consider instead of arbitrary smooth mappings only affine mappings. At a first look, this seems to be a restriction, because this requires an affine structure on the basic space X we consider. But because the geometry will be defined by the results for arbitrary small simplices, and for such small simplices we have some transformation into some standard situation, the affine structure will not have any influence. For a manifold without affine structure we can simply use the affine structure of some local coordinates. The usage of other coordinates does not influence the limit of arbitrary small simplices.

Usually in applications we consider only the n-dimensional Euclidean space, so we have some well-defined global affine structure. That's why, to use only affine simplices makes the interface much more simpler to use. Instead of the definition of a mapping we have to define only the coordinates of the corners of the simplex.

Finite Distances Instead of Infinitesimal Directions

To define a flag, we have to define a sequence of segments and infinitesimal directions. In finite precision arithmetics, we use instead a sequence of points (k, k-1,...,0) so that: There are some advantages of this method:

Rounding Error Handling

In an implementation of the interface we have to manage two problems:

The main problem is that the result of a call may be used for later input. So, the result must have properties which allow the continuation of the computation if it will be used later as input. The typical situation is that we have some expression f which in the continuous situation leads to one answer if f > 0 and to another if f < 0, in the case f = 0 the answer is not defined. In the case of finite precision, not only the case f = 0 is a problem, but also very small values of f, because different rounding errors for f may lead to a different classification of the situation in different parts of the algorithm. This usually leads to a fatal error in the program.

The strategy to avoid such situations is to make a small modification of the result if the exact result is in such a dangerous neighbourhood of a degeneration. The modification must be small enough compared with the required accuracy of boundary computation, but it must be large enough to avoid an incorrect classification if it will be used later as input.

Thus, if the required accuracy is large enough compared with the possible rounding errors, this technique allows to avoid fatal errors. It also does not require a special handling for the degenerated situations where the result is not defined in the exact, continuous case.

Remark that the case of a degenerated simplex is not dangerous, if the side containing the input flag itself is not degenerated. There will be simply a smaller set of possible output --- there may be no k-flag inside the simplex and no (k-1)-flag on degenerated sides.

Subdivision into Two Different Functions

For a theoretical consideration it looks very nice if we have only one function for every dimension. But in the real implementation it becomes easier two distinguish two functions: The idea of the simplification is that for the first variant we implement only one special case --- the flag on the first side of the simplex. This makes the implementation simpler, but for the calling function it is not difficult to use a point order for the simplex corner so that the flag lies on the first side. For the other variant, we can use a default implementation: Subdivide the simplex into smaller simplices so that the flag lies on the border between the sub-simplices. Use the first variant of f(k) to find the continuation. While the continuation was found on the inner border between the two sub-simplices, we have to continue the search in the other sub-simplex.

Nonorthogonal Flag Directions

The orthogonality condition for the flag directions require a special consideration. These problems may be solved using the convention that the directions must not be orthogonal, but only their projections have to be not degenerated. But in this case we obtain a new problem --- the projection of the directions on the simplex plane may lead to an incorrect result for the orientation of the intersection. This problem may be solved by the following convention: Very often the flag will be used only in combination with the same simplex. The previous rules allow to use also other simplices if these simplices are in the same plane. Our general strategy to handle rounding errors guarantees that the orientation of the projection will be the same also for a slightly different plane caused by rounding errors.

We see that the orthogonal variant is easier to use because it allows to use any plane which contains the given flag and leads to a non-degenerated projection of the flag direction. It is not necessary to hold information about the plane containing the given flag.

C++ Interface and OOP

The contravariant geometry description is very natural from object-oriented point of view: This leads to a natural C++ implementation. The cogeometry will be defined as an abstract class, the functions f(k) will be virtual methods. A concrete geometry description will be a derived class which contains all necessary data of the geometry. In principle, for all functions f(k) there is some default implementation which may be used if no better implementation is available. This default implementation describes a boundary which is not further subdivided into parts.

Special Conventions for Codimension 0 and 1

The case f(0) may be in principle considered as the degenerated case of the general intersection function f(k) for k = 0, but this is not very useful because there is no (-1)-flag and there are no sides for the 0-simplex. So, let's define f(0) separately: That means, it returns a pair which consists of the initial point and the region containing this point. The nontrivial part of this operation is to find the region containing the given point.

The function f(1) in principle may be used as defined, but we use here also some modification. Every smooth boundary face lies between two regions. Thus, if for every higher codimension the number of flags containing a given boundary point is not bounded, it is well-defined for codimension 1. That's why it seems natural to return above flags in a single call of f(1) instead of calling f(1) always two times from above sides of the edge. We simply have to add one new output point --- the point 0 of the "other side" of the flag.

Attribute Handling

Necessary part of the description of a physical situation is the attribute description. An attribute may be an arbitrary application-dependent information. An attribute has a result type (scalar, vector, integer) and can depend on geometrical data (points, segments). The physical sense of the attribute is defined by the application and hidden from the geometry description. That's why it is a good idea to separate the geometry description and the attribute description whenever possible. For many types of attributes this is possible.

Consider, for example, attributes which depend on the segment but are constant on this segment like material data of a region or boundary conditions on a boundary face. In this case, the geometry description returns a pointer (or a small positive integer) as the identifier of the segment, and the related attributes may be described by components of the related object (or by arrays over the possible integer values). In this case, we have a clear modular subdivision between geometry description and application data.

Another interesting class of attributes are space-dependent attributes. In principle, they may be described independently of the geometry description. But often this leads to problems. The reason is that they have to be evaluated once for every point which will be considered in the application. If this may be done later, this does not cause problems. But often the values may be used in the process itself. For example, the refinement criterion used for grid generation may depend on such an attribute. That's why the attribute must be evaluated in the process of grid generation. Or the attribute value of an initial geometry may be used to define another geometry (for example the induced geometry of a mapping defined by this attribute). In this case, the attribute must be evaluated in the process of geometry description itself. Thus, a separate description may lead to problems.

This situation is a special case of another class of attributes where it is not so easy to separate the geometry description and the attribute description. These are attributes which depend not only on the segment, but also on the point of the segment. This class of application also often occurs in applications. For example, many functions are defined only on some regions. Boundary concentrations and other functions defined only on a boundary also often have to be considered. Another example are functions which are continuous only inside a given region, but with different boundary limits for different regions (for example concentrations with segregation boundary conditions).

Because of this deep interaction with the geometry description it is necessary to have a general scheme to manage such attributes. Let's consider now this interaction. At first, remark that we have also a natural functional behaviour for the attributes. Indeed, for the geometry induced by a mapping f:X --> Y on X and for given attributes of the original geometry on Y related induced attributes may be defined in a natural way: The attribute value of a point in X is simply the attribute value of it's image in Y.

For the standard geometry description, such attribute data may be described by functions over the cells of the cell complex. The resulting attribute description is not very modular --- a small modification of the mapping (another parametrization) requires a modification of the related attribute description on the cell. We also obtain the same incorrect functional behaviour as for the cell complex itself. Indeed, a mapping f: X --> Y and an attribute description on a cell complex in X defines a natural attribute description on the image of the cell complex in Y. So, not only the construction of the cell complex which describes the induced geometry, but also the transfer of the attribute description becomes a complicate problem.

In the case of the contravariant geometry description, we can manage attributes using the following simple technique: We use a data type for the point which contains also the attribute values of the point. The function f(k) has to compute also these attribute values for the output points.

In principle, this technique may be considered as a special case of an induced geometry: We have to consider the embedding of a lower-dimensional space into a higher-dimensional space defined by the graph of the attribute functions. This interpretation shows that it is possible to combine this technique with other operations using the composition of mappings. For example, the attribute values of some geometry may be used to define a mapping which may be used to define an induced geometry.

Our scheme leads to a natural implementation for the interpolation of function values for a given grid. The functionsf(k) have to find the intersections of a simplex with the related boundary. Using our technique, this function also has to evaluate the function values. But this is a very natural place to interpolate the function values, because the majority of data we need for the interpolation of the function values in the grid (especially the element which contains the point) we need also if we have to find only the intersection point in the grid.