      SUBROUTINE WARRAY(LU,FILE,FORM,LMIN,VMIN,LMAX,VMAX,NOUT,OUT)
      CHARACTER*(*) FILE,FORM
      LOGICAL LMIN,LMAX
      INTEGER LU,NOUT
      REAL VMIN,VMAX,OUT(NOUT)
C
C SUBROUTINE DESIGNED TO WRITE A GIVEN ARRAY INTO THE FILE.
C
C INPUT:
C     LU...   LOGICAL DEVICE NUMBER OF THE OUTPUT FORMATTED FILE.
C             THE FILE IS NOT OPEN OR CLOSED HERE, THUS IT SHOULD BE
C             ALREADY OPEN.
C     FILE... DESTINATION FILENAME.  IF NOT BLANK, THE FILE WILL BE
C             OPENED AND CLOSED.  IF BLANK, THE FILE IS ASSUMED TO BE
C             ALREADY OPEN, AND WILL NOT BE CLOSED IN THIS SUBROUTINE.
C     FORM... FORM OF THE OUTPUT FILE: EITHER 'FORMATTED' OR
C             'UNFORMATTED'.
C     LMIN... TRUE IF THE NULL VALUES ARE TO BE WRITTEN IN PLACE OF
C             ARRAY ELEMENTS LESS THAN OR EQUAL TO VMIN, OTHERWISE
C             FALSE.
C             FORMATTED OUTPUT:
C               THE NULL VALUES ARE TREATED AS DEFAULT VALUES WHEN READ
C               BY LIST-DIRECTED INPUT (FREE FORMAT).
C               EXAMPLE: 124 NULL VALUES ARE WRITTEN AS '    124*'.
C             UNFORMATTED OUTPUT:
C               THE VALUES OF 999999 ARE WRITTEN IN PLACE OF THE NULL
C               VALUES.
C     LMAX... TRUE IF THE NULL VALUES ARE TO BE WRITTEN IN PLACE OF
C             ARRAY ELEMENTS GREATER THAN OR EQUAL TO VMAX, OTHERWISE
C             FALSE.
C     VMIN,VMAX... TRADE-OFF LIMITS.
C     NOUT... DIMENSION OF THE ARRAY OUT.
C     OUT...  ARRAY TO BE WRITTEN.
C
C NO OUTPUT.
C
C DATE: 1993, DECEMBER 14
C CODED BY LUDEK KLIMES
C
C-----------------------------------------------------------------------
C
C     LOCAL STORAGE LOCATIONS:
C
      CHARACTER*14 FORMAT
      INTEGER IFORM1,IFORM2,IMIN,IADR
      REAL OUTMIN,OUTMAX,VMINA,VMAXA
C
C     FORMAT..STRING CONTAINING THE OUTPUT FORMAT, E.G. LIKE (10F08.3).
C     IFORM1,IFORM2... DEFINE FORMAT TO WRITE THE TRAVEL TIMES.
C             LIMITS: 0.LE.IFORM2.LE.9, IFORM2+1.LE.IFORM1.LE.99.
C     IMIN... LOOP LOWER BOUND, LOCALLY ALSO LOOP VARIABLE.
C     IADR... LOOP VARIABLE.
C     OUTMIN,OUTMAX... MINIMUM AND MAXIMUM DEFINED ELEMENT TO DETERMINE
C             THE BEST FORMAT FOR PRINTING.
C     VMINA,VMAXA... LOCAL STORAGE LOCATIONS FOR VMIN, VMAX.
C
C.......................................................................
C
      IF(FILE.NE.' ') THEN
        WRITE(*,'(2A)') '+WRITING: ',FILE(1:MIN0(LEN(FILE),70))
        OPEN(LU,FILE=FILE,FORM=FORM)
      END IF
C
C     FORMATTED OR UNFORMATTED OUTPUT:
      IF(FORM.EQ.'FORMATTED') THEN
C
C       MINIMUM AND MAXIMUM ELEMENTS:
        OUTMIN=0.
        IF(LMIN) THEN
          VMINA=VMIN
          DO 11 IADR=1,NOUT
            IF(OUTMIN.GT.OUT(IADR)) THEN
              IF(OUT(IADR).GT.VMINA) THEN
                OUTMIN=OUT(IADR)
              END IF
            END IF
   11     CONTINUE
        ELSE
          DO 12 IADR=1,NOUT
            IF(OUTMIN.GT.OUT(IADR)) THEN
              OUTMIN=OUT(IADR)
            END IF
   12     CONTINUE
        END IF
        OUTMAX=0.
        IF(LMAX) THEN
          VMAXA=VMAX
          DO 13 IADR=1,NOUT
            IF(OUTMAX.LT.OUT(IADR)) THEN
              IF(OUT(IADR).LT.VMAXA) THEN
                OUTMAX=OUT(IADR)
              END IF
            END IF
   13     CONTINUE
        ELSE
          DO 14 IADR=1,NOUT
            IF(OUTMAX.LT.OUT(IADR)) THEN
              OUTMAX=OUT(IADR)
            END IF
   14     CONTINUE
        END IF
C
C       SETTING OUTPUT FORMAT FOR THE ARRAY:
        IFORM1=MAX0(INT(ALOG10(AMAX1(OUTMAX,0.001))+1.001),0)
        IF(OUTMIN.LT.0.) THEN
          IFORM1=MAX0(INT(ALOG10(AMAX1(-OUTMIN,0.001))+2.001),1,IFORM1)
        END IF
C       HERE, IFORM1 IS THE NUMBER OF DIGITS LEFT TO THE DECIMAL POINT.
        IFORM2=MAX0(6-IFORM1,0)
C       IFORM2 IS THE NUMBER OF DECIMAL PLACES.
        IFORM1=IFORM1+IFORM2+1
C       IFORM1 IS THE WIDTH OF THE OUTPUT FIELD FOR ONE ELEMENT.
        FORMAT='(10(1X,F00.0))'
        FORMAT( 9: 9)=CHAR(ICHAR('0')+IFORM1/10)
        FORMAT(10:10)=CHAR(ICHAR('0')+MOD(IFORM1,10))
        FORMAT(12:12)=CHAR(ICHAR('0')+IFORM2)
C       OUTPUT FORMAT IS SET.
C
C       PRINTING LOOP:
C       INITIAL VALUE OF THE FIRST ELEMENT TO PRINT
        IADR=1
C       BEGINNING OF THE LOOP
   20   CONTINUE
C
C         TRADE OFF (SEARCHING FOR UNDEFINED ELEMENTS):
          IMIN=IADR
          IF(LMIN) THEN
            IF(LMAX) THEN
              DO 21 IADR=IMIN,NOUT
                IF(OUT(IADR).LE.VMINA.OR.OUT(IADR).GE.VMAXA) THEN
                  GO TO 29
                END IF
   21         CONTINUE
            ELSE
              DO 22 IADR=IMIN,NOUT
                IF(OUT(IADR).LE.VMINA) THEN
                  GO TO 29
                END IF
   22         CONTINUE
            END IF
          ELSE
            IF(LMAX) THEN
              DO 23 IADR=IMIN,NOUT
                IF(OUT(IADR).GE.VMAXA) THEN
                  GO TO 29
                END IF
   23         CONTINUE
            ELSE
              IADR=NOUT+1
            END IF
          END IF
   29     CONTINUE
C         IADR IS THE FIRST UNDEFINED ELEMENT.
C
C         WRITING THE ARRAY (DEFINED ELEMENTS):
          IF(IMIN.EQ.1.AND.IADR.GT.NOUT) THEN
            WRITE(LU,FORMAT) OUT
            GO TO 90
          ELSE
            WRITE(LU,FORMAT) (OUT(IMIN),IMIN=IMIN,IADR-1)
            IF(IADR.GT.NOUT) THEN
              GO TO 90
            END IF
          END IF
C
C         SEARCHING FOR THE NEXT DEFINED ELEMENTS:
          IMIN=IADR
          IF(LMIN) THEN
            IF(LMAX) THEN
              DO 31 IADR=IADR,NOUT
                IF(OUT(IADR).GT.VMINA.AND.OUT(IADR).LT.VMAXA) THEN
                  GO TO 39
                END IF
   31         CONTINUE
            ELSE
              DO 32 IADR=IADR,NOUT
                IF(OUT(IADR).GT.VMINA) THEN
                  GO TO 39
                END IF
   32         CONTINUE
            END IF
          ELSE
            IF(LMAX) THEN
              DO 33 IADR=IADR,NOUT
                IF(OUT(IADR).LT.VMAXA) THEN
                  GO TO 39
                END IF
   33         CONTINUE
            ELSE
              IADR=NOUT+1
            END IF
          END IF
   39     CONTINUE
C         IADR IS THE FIRST DEFINED ELEMENT.
C
C         WRITING THE ARRAY (UNDEFINED ELEMENTS):
          WRITE(LU,'(I7,A)') IADR-IMIN,'*'
          IF(NOUT.LT.IADR) THEN
            GO TO 90
          END IF
C
        GO TO 20
      ELSE
C
C       NULL VALUES:
        IF(LMIN) THEN
          VMINA=VMIN
          IF(LMAX) THEN
            VMAXA=VMAX
            DO 51 IADR=1,NOUT
              IF(OUT(IADR).LE.VMINA.OR.VMAXA.LE.OUT(IADR)) THEN
                OUT(IADR)=999999.
              END IF
   51       CONTINUE
          ELSE
            DO 52 IADR=1,NOUT
              IF(OUT(IADR).LE.VMINA) THEN
                OUT(IADR)=999999.
              END IF
   52       CONTINUE
          END IF
        ELSE
          IF(LMAX) THEN
            VMAXA=VMAX
            DO 53 IADR=1,NOUT
              IF(VMAXA.LE.OUT(IADR)) THEN
                OUT(IADR)=999999.
              END IF
   53       CONTINUE
          END IF
        END IF
C
C       WRITING THE ARRAY:
        WRITE(LU) OUT
C
      END IF
   90 CONTINUE
      IF(FILE.NE.' ') THEN
        CLOSE(LU)
      END IF
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RARRAY(LU,FILE,FORM,LDEF,DEF,N,ARRAY)
      CHARACTER*(*) FILE,FORM
      LOGICAL LDEF
      INTEGER LU,N
      REAL DEF,ARRAY(N)
C
C SUBROUTINE DESIGNED TO READ THE ARRAY FROM THE DISK.
C
C INPUT:
C     LU...   LOGICAL UNIT NUMBER TO BE USED.
C     FILE... SOURCE FILENAME.  IF NOT BLANK, THE FILE WILL BE
C             OPENED AND CLOSED.  IF BLANK, THE FILE IS ASSUMED TO BE
C             ALREADY OPEN, AND WILL NOT BE CLOSED IN THIS SUBROUTINE.
C     FORM... FORM OF THE OUTPUT FILE: EITHER 'FORMATTED' OR
C             'UNFORMATTED'.
C     LDEF... TRUE IF THE NULL VALUES ARE TO BE REPLACED BY THE GIVEN
C             DEFAULT VALUE DEF.
C             IF FORM='FORMATTED' AND LDEF=.FALSE., THE ARRAY ELEMENTS
C             CORRESPONDING TO NULL VALUES REMAIN UNCHANGED.
C     DEF...  DEFAULT VALUE.
C     N...    ARRAY DIMENSION (NUMBER OF ELEMENTS TO READ).
C
C OUTPUT:
C     ARRAY.. ARRAY HAVING BEEN READ.
C
C DATE: 1993, DECEMBER 14
C CODED BY LUDEK KLIMES
C
C-----------------------------------------------------------------------
C
      INTEGER I
      REAL AUX
C
      IF(FILE.NE.' ') THEN
        WRITE(*,'(2A)') '+READING: ',FILE(1:MIN0(LEN(FILE),70))
        OPEN(LU,FILE=FILE,FORM=FORM,STATUS='OLD')
      END IF
C
      IF(FORM.EQ.'FORMATTED') THEN
        IF(LDEF) THEN
          AUX=DEF
          DO 10 I=1,N
            ARRAY(I)=AUX
   10     CONTINUE
        END IF
        READ(LU,*) ARRAY
      ELSE
        READ(LU) ARRAY
        IF(LDEF) THEN
          IF(DEF.LT.899999.OR.1111110.LT.DEF) THEN
            AUX=DEF
            DO 20 I=1,N
              IF(999998.LT.ARRAY(I)) THEN
                ARRAY(I)=AUX
              END IF
   20       CONTINUE
          END IF
        END IF
      END IF
C
      IF(FILE.NE.' ') THEN
        CLOSE(LU)
      END IF
      RETURN
      END
C
C=======================================================================
C
