The General Relativity Package



next up previous contents index
Next: Ordinary Differentiation Up: No Title Previous: shift()

The General Relativity Package

 

This chapter describes the functions in REDTEN that comprise the General Relativity package for managing the family of related objects that are constructed from the metric tensor (assumed symmetric). The user has already encountered the metric() function and seen how it can be used to make a metric tensor either from a rank-2 indexed object or directly from the line-element. We shall repeat the examples of the RW metric to illustrate the use of the GR package.

Constructing the metric tensor from the RW line-element can be done as   follows:

 
#: ds2 := d(t)^2-rt^2*(d(om)^2+s^2*(d(th)^2+sin(th)^2*d(ph)^2));

               2   2        2        2   2  2       2        2   2  2
ds2 :=  - d(om)  rt  - d(ph)  sin(th)  rt  s  + d(t)  - d(th)  rt  s

#: metric (ds2);

 computing g1
 INVERT finished.

  g1
There are several functions to compute the various objects of interest starting from a metric. These are christoffel1(), christoffel2(), riemann(), ricci(), riccisc(), riccisc(), einstein(), and weyl(). The workings of these are so similar that they can be described together, special features of each function will be noted.

Each function takes one optional argument, the name to use when creating its output. The actual object name is made by concatinating the current-metric name and the user name (or the default name), separated by a _ symbol (these names may seem unweildly, see §4.3 below for a simplifying interface). If the user does not supply a name, the default name is used which is stored on the function name used as a lisp variable. For example, the default name for the Christoffel symbol of the first kind is found on the variable christoffel1. The defaults are c1, c2, R, ric, ricsc, G, and C for the functions listed above (these are set in the sys.env source file).

Each function stores the name of the object it creates on the property list of the current-metric under a key which is the functions' own name. Thus, the name of the object created by christoffel1() is stored on the metric under the key christoffel1. When these functions are called, they look first at the current-metric to see if the desired object already exists, if it does its name is returned immediately. If it does not exist, then it is created. If the object exists but the user provided a name, then it is recomputed with the new name.

These functions construct a family of related objects derived from the metric tensor, and some REDTEN functions can operate on the family as a whole. The names of family members for any object can be seen by calling the symbolic-mode function getfam().

Since each function except christoffel1() calls the others to get the objects it needs, the user does not necessarily need to build the objects one at a time (but see §5.1 for an important consideration). For example, we can compute all the objects in a direct line from the metric tensor to the Weyl tensor with the single command:

 
#: weyl();

computing g1_C
  computing g1_ricsc
    computing g1_ric
      computing g1_R
        computing g1_c1
        christoffel1 finished. 
        computing g1_c2
        christoffel2 finished.
      riemann finished.
    ricci finished.
  riccisc finished.
** this space is conformally flat

 g1_C
The Ricci scalar is created as an indexed scalar by riccisc(). If the Weyl tensor can be seen to be zero then weyl() will report that the space is conformally flat. If the Ricci tensor is zero then ricci() will report that the metric is a vacuum solution. For complicated metrics it may take some simplification before these objects reduce to zero, so the messages may not appear. Each function write-protects its output, so that the user cannot accidentally make inconsistent changes; see also mapfi() and protect().

The output of each function is the name of an indexed object. If desired, the function can be wrapped in the function calling operator fn() allowing it to be used with an index directly. This lets the user to make indexed expressions that do not rely on the exact names of the various objects; a better method is described in the section on generic names below. For example, to compute the Einstein tensor and examine a component in the same command can be done by: einstein() fn()

 
#: fn(einstein(),[1,1]);
computing g1_G
einstein finished.

                 2
 2 rt    rt + rt   + k
     t,2        t

The fn() operator accepts a function and the index to be attached to the output of the function (which must be an indexed object name) as its two arguments.





next up previous contents index
Next: Ordinary Differentiation Up: No Title Previous: shift()



John Harper
Wed Nov 16 13:34:23 EST 1994