Many routines, especially the iterative solvers, need lots of parameters, some of which are input, some output, and some of which enter with one value and are modified by the routines. Examples are the maximum number of iterations to allow, the number of iterations actually completed, logical units for output and errors, etc.
Of course, different routines require different parameters.
I wanted a method with the following attributes.
Since Fortran 77 lacks the ability to bundle integer and real data together, a la C structures or Fortran 90 derived types, JTPACK77 uses two vectors, one integer and one real, containing control and information parameters like those mentioned above. In this document, these vectors will be referred to as iparm and rparm, respectively, although they can have any valid name.
The .F files containing routines that are passed iparmand rparm, for example, include (via the cpp directive #include) the file parmdefines.h and refer to the elements of the vectors by the descriptive names. The C preprocessor then replaces the descriptive names by the actual elements of the vectors when the .F files are converted to .f files.
An excerpt from GMRES.F illustrates this idea:
c
c Compute || b || if needed.
if (ABS(iparm(_JT_ stop_)).eq._JT_ stop_ axb_ .or.
& ABS(iparm(_JT_ stop_)).eq._JT_ stop_ b_) then
bnorm = JT_VectorNorm(iparm(_JT_ norm_), ia(_JT_ nrows_)
, b, status)
else
bnorm = zero
endif
Here I've used a sans serif font for the cpp variables to emphasize the fact that they will be replaced by their appropriate definitions by cpp.
Note that cpp variables have been used to denote both the element of iparm that indicates which stopping test is used (iparm(_JT_ stop_)), but also for two particular values that iparm(_JT_ stop_) can assume (_JT_ stop_ axb_ and _JT_ stop_ b_).
Also note that in addition to iparm, there is another vector in this segment making use of cpp variables, ia. It is the vector containing information about how the coefficient matrix is stored, and is described in detail in Chapter 4.
Preprocessing the above yields the following excerpt from GMRES.f:
c
c Compute || b || if needed.
if (ABS(iparm(7)).eq.1 .or.
& ABS(iparm(7)).eq.2) then
bnorm = JT_VectorNorm(iparm(8), ia(2), b, status)
else
bnorm = zero
endif
Clearly the first code segment is easier to read, easier to maintain, and far less error-prone. Nevertheless, some users may be unwilling or unable to modify the build procedure for the host code to use cpp. So throughout this manual, whenever a cpp variable is described, the current value of the variable is also given. Note, however, that this is not the recommended mode of operation, since the values may change.