Encyclopaedia Index

### (p) Handling slabwise arrays in DO loops

Suppose that density, DEN1, and temperature, TMP1, have been stored as FFV's by the command STORE(DEN1,TMP1) in the SATELLITE; suppose further that it is desired to calculate the density from the temperature and the pressure (P1) from the ideal-gas law. Then, one means of doing so is as follows:

DO 10 IX=1,NX
DO 10 IY=1,NY
10 F(INDYX(DEN1)) = VARYX(P1)/(GASCON*VARYX(LBNAME('TMP1')))

Somewhat more economical, because it reduces the time spent in LBNAME, as mentioned above, is:

ITEM=LBNAME('TMP1')
DO 10 IX=1,NX
DO 10 IY=1,NY
10 F(INDYX(DEN1)) = VARYX(P1)/(GASCON*VARYX(ITEM))

There is, however, an appreciable amount of computational work also within the INDYX and VARYX functions. This can be dispensed with if L0F is used directly as follows:

L0DEN=L0F(DEN1)
L0TEM=L0F(LBNAME('TMP1'))
L0P1=L0F(P1)
DO 10 IX=1,NX
DO 10 IY=1,NY
ICELL=IY+NY*(IX-1)
10 F(L0DEN+ICELL) = F(L0P1+ICELL)/(GASCON*F(L0TEM+ICELL)))

Finally it may be recognised that ICELL increases by 1 for each pass through the inner loop; consequently the double loop may be replaced by a single one as follows:

NXNY=NX*NY
DO 10 ICELL=1,NXNY
10 F(L0DEN+ICELL) = F(L0P1+ICELL)/(GASCON*F(L0TEM+ICELL))

The last version is the least expensive computationally, and it is agreeably simple. It is to be recommended whenever the computation is indeed required for the whole slab. If the density values need to be set for only a part of the slab, however, a double loop would still be appropriate as follows:

ICELL=IYL+NY*(IXF-2)
DO 10 IX=IXF,IXL
DO 10 IY=IYF,IYL
ICELL=ICELL+1
10 F(L0DEN+ICELL) = F(L0P1+ICELL)/(GASCON*F(L0TEM+ICELL))

This might well be judged too complex to justify the computer-time saving.

If users had wished to insert the density into a two-dimensional array which they had themselves introduced, for example by way of the declaration:

DIMENSION UUDEN(20,30)

either a double loop would be used, as in:

DO 10 IX=IXF,IXL
DO 10 IY=IYF,IYL
ICELL=ICELL+1
10 UUDEN(IY,IX) = F(L0P1+ICELL)/(GASCON*F(L0TEM+ICELL))

or, if the whole slab were in question, one might employ:

DO 10 ICELL=1,NXNY
IY=1+MOD(ICELL-1,NY)
IX=1+(ICELL-1)/NY
10 UUDEN(IY,IX) = F(L0P1+ICELL)/(GASCON*F(L0TEM+ICELL))

However, the PHOENICS user who was more concerned with speed of writing than speed of computation might well prefer the conceptu- ally simpler form:

DO 10 IX=1,NX
DO 10 IY=1,NY
10 UUDEN(IY,IX) = VARYX(P1)/(GASCON*VARYX(LBNAME('TEM')))

To avoid conflict with FORTRAN variable names used in EARTH commons, user-introduced variables should adhere to the following prefix conventions:

'G' for names of REAL variables and arrays.
'J' for names of INTEGER variables and arrays.
'G' or 'J' for names of LOGICAL variables.

However, the following variable names beginning with G are already used by EARTH, and so are not be used:-

GENK, GALA, GREAT, GRND, GRND1,.....GRND10,GRSP1,...GRSP10.

wbs