c
c     Copyright (c) 1999,2000, Compaq Computer Corporation
c
c     See the file "license.terms" for information on usage and redistribution
c     of this file, and for a DISCLAIMER OF ALL WARRANTIES.
c
      subroutine read_useout(batchmode, read_error)
      implicit none
c
      include 'const.h'
      include 'sysdep.cmn'
      include 'mesh.cmn'
      include 'data.cmn'
      include 'io.cmn'
      include 'plot.cmn'
c
c     read MINIMOS 5.0 USEOUT type binary file
c
      logical batchmode, read_error
c
c     locals
c
      integer i
c
      call read_useout_bin(batchmode, read_error)
c
      if ( read_error ) goto 10000
c
c     compute some stuff related to mesh...
c
c     set up boundary limits information
      call coord_limits
c
      nxm = nx - 1
      nym = ny - 1
      nytotm = nytot - 1
c
c     inverse mesh spacing...
c
      do 210 i=1,nxm
210      edxyz(i,1) = 1.0/(xyz(i+1,1) - xyz(i,1))
      do 211 i=1,nytotm
211      edxyz(i,2) = 1.0/(xyz(i+1,2) - xyz(i,2))
      do 212 i=1,nz-1
212      edxyz(i,3) = 1.0/(xyz(i+1,3) - xyz(i,3))
c
c     average mesh spacing...
c
      dxyzm(1,1)  = (xyz(2,1)  - xyz(1,1))/2.0
      dxyzm(nx,1) = (xyz(nx,1) - xyz(nx-1,1))/2.0
      do 220 i=2,nxm
220      dxyzm(i,1) = (xyz(i+1,1) - xyz(i-1,1))/2.0
c
      dxyzm(1,2)     = (xyz(2,2)  - xyz(1,2))/2.0
      dxyzm(nytot,2) = (xyz(nytot,2) - xyz(nytot-1,2))/2.0
      do 221 i=2,nytotm
221      dxyzm(i,2) = (xyz(i+1,2) - xyz(i-1,2))/2.0
c
      dxyzm(1,3)     = (xyz(2,3)  - xyz(1,3))/2.0
      dxyzm(nz,3) = (xyz(nz,3) - xyz(nz-1,3))/2.0
      do 222 i=2,nz-1
222      dxyzm(i,3) = (xyz(i+1,3) - xyz(i-1,3))/2.0
c
      call load_useout_specific
c
      if( lfirst_read ) then
         lfirst_read = .FALSE.
         prev_plane_type = plane_type
         prev_binfilename = binfilename
         prev_binfiletype = binfiletype
      endif
      if( prev_binfiletype .ne. binfiletype ) then
         oned_lfirst = .TRUE.
         twod_lfirst = .TRUE.
         threed_lfirst = .TRUE.
      endif
      datafile_loaded = .TRUE.
c
10000 return
      end
c
      subroutine read_useout_bin(batchmode, read_error)
      implicit none
c
      include 'const.h'
      include 'sysdep.cmn'
      include 'mesh.cmn'
      include 'data.cmn'
      include 'io.cmn'
      include 'plot.cmn'
      include 'bincodes.cmn'
c
c     read double precision USEOUT binary file
c
      logical batchmode, read_error
c
c     locals
c
      integer i, j, ilen, ioerr, string_len,
     1        ierr, local_record, nrecl
      logical lskip
      character*1 answer
      character*(PM_MAX_PATHLEN) expanded_name
c
      write(luttyo,10)
10    format(' ','Reading USEOUT binary file...',$)
c
      nrecl=0
      call pm_open_file(binfil, binfilename,
     1               'OLD','UNFORMATTED','READ','NONE','NONSHARED',
     2               nrecl, ioerr, ierr)
      if( ierr .ne. 0 ) goto 10000
      local_record = 0
c
c     get stem of binary file name
      call get_filestem(binfilename, binfilestem)
c
100   continue
c
      local_record = local_record + 1
c
c     clear out arrays
      do 45 j=1,3
         do 45 i=1,ARRAYSIZE
            xyz(i,j) = 0.0
            edxyz(i,j) = 0.0
            dxyzm(i,j) = 0.0
45    continue
      do 51 j=1,MENUSIZE
         in_binary_file(j) = .FALSE.
51       continue
c
c     1. first read title from binary file
      read(binfil,err=10010,iostat=ioerr,end=10020) title
c
      if( batchmode ) then
         if( local_record .eq. datafile_record ) then
            lskip = .FALSE.
            write(luttyo,55) datafile_record, title
55          format(' ','Extracting useout record ',i5,' with label:'/
     1             ' ',2x,a)
         else
            lskip = .TRUE.
         endif
      else
         write(luttyo,60) title
60       format(' ','Useout record found with label:'/3x,a)
         call get_char(answer,'Extract or Skip? (E/S) [S] ',0)
         call upcase(answer)
         if( answer .eq. 'E' ) then
            lskip = .FALSE.
         else
            lskip = .TRUE.
         endif
      endif
c
c     2. now nx, ny
c     Note: Useout reverses x and y
      read(binfil,err=10010,iostat=ioerr) ny,nx
      nz = 1
      nt = ny
      nyoxm = 0
      nytot= ny
      nxsp = 1
      nxsoxm = 1
      plane_index = 1
      prev_plane_type = plane_type
      plane_type = XY_PLANE
      xyz(1,3) = -xw/2.0
c     Data file has 2D data
      three_d = .FALSE.
c
c     Is array storage large enough?
      if( MAX(nx,nytot,nz) .gt. COMP_ARRAYSIZE .or.
     1    (nx*nytot) .gt. WORK2DSIZE .or.
     2    (nx*nytot) .gt. NUM_DATA_ARRAYS*ARR2DSIZE ) then
         write(luttyo,10050)
10050    format(' ','Error: input file too large for POSTMINI arrays')
         read_error = .TRUE.  ! go back
         close(unit=binfil)
         return
      endif
c
      nxy=nx*ny
      nxytot=nx*nytot
c
c     3. read lateral spacing
      read(binfil,err=10010,iostat=ioerr) (work_dbl(i),i=1,nytot)
      do 200 i=1,ny
200      xyz(i,2) = SNGL(work_dbl(i))
c
c     4. read transversal spacing
      read(binfil,err=10010,iostat=ioerr) (work_dbl(i),i=1,nx)
      do 210 i=1,nx
210      xyz(i,1) = SNGL(work_dbl(i))
c
c     Load generic mesh pointers, depending on plane type
c
      call set_3d_index_limits
      cut_plane_axis = charb
c
      call allocate_rect_arrays(nx,ny,1,ierr)
      if( ierr .ne. 0 ) then
c        Failure during array allocation
         write(luttyo,10050)
         read_error = .TRUE.
         close(unit=binfil)
         return
      endif
c     Zero array (not really necessary)
      call zero_real_array(arrdat,nx*ny,1)
c
c     This variable must be set by all read routines...
      data_is_trigrid = .FALSE.
c
c     5. Load data array
      call read_3d_plane(binfil,work_dbl,arrdat,nx,ny,nz,nyoxm,
     1                   plane_index,plane_type,ni,nj,
     2                   ARRAYSIZE,ierr,ioerr)
      if( ierr .ne. 0 ) goto 10010
      in_binary_file(1) = .TRUE.
c
      if( lskip ) goto 100
c
      datafile_record = local_record
      write(luttyo,110)
110   format(' ','...done')
      read_error = .FALSE.
c
      close(unit=binfil)
      goto 10100
c
c     errors of commission/omission
c
c     I/O error on open of binary file
10000 continue
      call expand_filename(binfilename,expanded_name)
      ilen = string_len(expanded_name)
      write(luttyo,10001) ioerr, expanded_name(1:ilen)
10001 format(/' ','FORTRAN I/O error #',i5,' on open of binary file:'/
     1       ' ',a)
      write(luttyo,10002)
10002 format(' ','Check for these errors:'/
     1       ' ','   - Incorrect file, directory or disk name'/
     1       ' ','   - You must have read permission on the file'/)
      read_error = .TRUE.  ! go back and get new name...
      goto 10100
c
c
c     I/O error on read of binary file
10010 write(luttyo,10011) ioerr
10011 format(/' ','FORTRAN I/O error #',i5,' on read of binary file')
      if( ioerr .eq. 24 ) then       ! End-of-file during read
         write(luttyo,10012)
10012    format(' ','Unexpected end-of-file during read...'/
     1          ' ','File may not be a MINIMOS binary file'/)
      else if( ioerr .eq. 35 ) then  ! Not binary file format
         write(luttyo,10013)
10013    format(' ','File is probably not a FORTRAN binary file...'/)
      else if( ioerr .eq. 67 ) then  ! Not enough data in record
         write(luttyo,10014)
10014    format(' ','Insufficient data in record'/)
      else if( ioerr .eq. -1 ) then  ! End of file at start of read
         write(luttyo,10015)
10015    format(' ','Unexpected end-of-file'/
     1     ' ','File may not have been written completely by MINIMOS'/)
      endif
      read_error = .TRUE.  ! go back and get new name...
      close(unit=binfil)
      goto 10100
c
10020 continue
      write(luttyo,10021)
10021 format(' ','End-of-file reached')
      if( batchmode ) then
         write(luttyo,10022) datafile_record
10022    format(' ','Error: could not find record number: ',i5)
      else
         call get_char(answer,
     1      'Read file over from beginning? (Y/N) [Y] ',0)
         call upcase(answer)
         if( answer .ne. 'N' ) then
            rewind(binfil)
            local_record = 0
            goto 100
         endif
      endif
      read_error = .TRUE.  ! go back and get new name...
      close(unit=binfil)
      goto 10100
c
10100 continue
      return
      end
c
      subroutine load_useout_specific
      implicit none
c
c     Load descriptive arrays with MINIMOS specific data
c
      include 'const.h'
      include 'sysdep.cmn'
      include 'data.cmn'
c
c     Data varies linear or logarithmic
      logical LOG, LIN
      parameter (LOG = .TRUE., LIN = .FALSE.)
c     Data has value in oxide, or not
      logical OX, NO_OX
      parameter (OX = .TRUE., NO_OX = .FALSE.)
c     Data jumps at oxide interfaces
      logical JUMP, NO_JUMP
      parameter (JUMP = .TRUE., NO_JUMP = .FALSE.)
c     Data is 1D or 2D
      logical ONED, TWOD
      parameter (ONED = .TRUE., TWOD = .FALSE.)
c
c     Number of menu items
      max_menu_num = 1
c     Array index of net doping (none in this case)
      net_dop_array_index = 0
c
      call load_desc_arr(1, title,'USEOUT',
     1                   ' ',' ',' ','.useout',
     2                   LIN,OX,NO_JUMP,TWOD,1)
      return
      end
