To make use of this metric we must first set the correct coordinates as above, and then create an appropriate indexed object and enter values for its components. Since this is a metric tensor, it will have two covariant tensor indices, and will be symmetric:
#: mkobj ('h, '(-1 -1), '((1 1 2)), '(), 'metric); h a b #: depend rt, t; #: let s = sin(sqrt(k)*om)/sqrt(k);Notice that we have set up the object so that the itype is metric, and have used an empty list for the undesired implicit parameter. It is common to use the name g for a metric, but in REDTEN it has been made into a ``generic'' (qv) name, and should not be disturbed; we shall use h in this example instead. We have also set up the time-dependence of rt (using rt instead of R, since R is generic too) and defined a let rule to evaluate . This last part could be done as easily with a REDUCE assignment.
There are two ways to enter the values of the components of h. The first method involves the expected assignment operation, where the left-hand side, referring to a specific element with a fixed index, is assigned the value on the right hand side. Unlike the normal REDUCE assignment operation which uses the symbol :=, the REDTEN indexed assignment operation uses the symbol ==. Attempting to assign a value to an indexed object element with the := operator will result in a REDUCE Missing Operator error mclear() message. We can proceed as follows:
#: h[0,0] == 1; 1 #: h[1,1] == -rt^2; 2 -rt #: h[2,2] == -s^2*rt^2; 2 2 - sin(sqrt(k) om) rt ------------------------- k #: h[3,3] == -sin(th)^2*s^2*rt^2; 2 2 2 - sin(sqrt(k) om) sin(th) rt ---------------------------------- kAs each value is entered, the system then reads the object to determine the actual value stored for that component, since it is possible for the assignment to fail due to symmetries or write-protection of the object. These are explicit components for h, and since h was not declared as an ``implicit'' object, any missing components are taken as 0. If any component already had a non-zero value, that value is overwritten (unless the object is write-protected).
When a large number of elements are to be assigned to the same object, a more convenient method is to use the function ias(). This function takes an indexed object as input and guides the user through the assignment process. At its simplest, ias() attempts to assign to the whole object, keeping in mind the intrinsic symmetries that are present. The user may also attach an index that indicates the assignments are to be to a particular row or column of the object. Using ias() the assignment to h would proceed as follows:
#: ias(h); h[0,0] = 1; h[0,1] = ; h[0,2] = ; h[0,3] = ; h[1,1] = -rt^2; h[1,2] = ; h[1,3] = ; h[2,2] = -s^2*rt^2; h[2,3] = ; h[3,3] = -sin(th)^2*s^2*rt^2; hAt each prompt the user may enter the desired value; a semi-colon alone is equivalent to zero. If the user types nil then the assignment process is terminated, and any remaining unassigned components will be unchanged.
The function iclear() can be used to remove all of the components of several indexed objects (and the multiplier), without disturbing any of the other properties.
So far we have created only a rank-2 object with some symmetries and values, the rest of the structure associated with a metric is not yet present. The function metric() is used to fully qualify an object as a metric: it attaches the required properties, adjusts some system variables and creates the metric inverse. We may apply metric() to h very simply:
#: metric(h); invert finished. hAt the end of this process h has been declared the ``current-metric'', and its name is installed in the system variable currentmetric. Among other things, this means that h will be used by shift() when raising or lowering tensor indices. The generic metric g will also refer to this object (see 4.3). The metric inverse will be given the name h_inv, it is created from the metric by the matrix function invert() (qv). The indexed object passed to metric() must be a rank-2 covariant object, and is assumed to be symmetric. If it is actually diagonal (as this example is), the symmetry will be adjusted to reflect this. A diagonal symmetry helps the system to run faster for many operations involving the metric, particularly in the raising and lowering of indices with shift().
metric() can also be used to create a new indexed object suitable for filling with metric coefficients. To do this, give metric() no arguments, the object it creates will have a name in the usual sequence of metric objects described below. After the user has entered the metric coefficients, metric() should be called again as demonstrated above to finish the job of setting up the metric. In this situation, the newly created object must be accessed by name, it is not the target of the generic metric, since it is not yet a proper metric.
A package for General Relativity is included in REDTEN (described in Chapter 4), and allows the user to enter a metric directly from the line-element:
#: 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 ds2 := ( - d(om) k rt - d(ph) sin(sqrt(k) om) sin(th) rt 2 2 2 2 + d(t) k - d(th) sin(sqrt(k) om) rt )/k #: metric (ds2); computing g1 invert finished. g1In this case, the metric name is defined by the system. It will have the form g<sequence number>, where <sequence number> is initially 1, and increments for every new metric that is created in this fashion. An optional second argument allows the user to specify the name that will be used instead for the metric. This method is more convenient for simple metrics that are ordinarily presented in the form of a line-element, while the first method is often useful for very complicated metrics that are too troublesome to express in line-element form.
The line-element is written as a REDUCE expression containing the differential operator d(). This operator computes the total derivative of its argument with respect to the current coordinates; if the argument is one of the coordinate names, d() returns unevaluated. By examining the expression for d() operators the system can determine the structure of the metric, and can also tell if the metric is diagonal or simply symmetric.
metric()
Once the elements of the metric are in place, one needs a way to examine the object to ensure all is well.