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)
IADD=IYF-1+NY-IYL
DO 10 IX=IXF,IXL
ICELL=ICELL+IADD
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:
either a double loop would be used, as in:
DO 10 IX=IXF,IXL
ICELL=ICELL+IADD
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