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_mini(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 4.0 or 5.0 (2D or 3D) binary file
c
      logical batchmode, read_error
c
c     locals
c
      integer i
c     Support only MINIMOS4/5 style binary files (double precision)
c
      datafile_loaded = .FALSE.
c
      call input_binfile_double(batchmode, read_error)
c
      if ( read_error ) goto 10000
c
c     compute some stuff related to mesh...
c
      write(luttyo,200)
200   format(' ','Computing E field...interpolating onto 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 e_jcomp(arrdat(arrind(PSI)), arrdat(arrind(E_CONC)),
     1            arrdat(arrind(H_CONC)), arrdat(arrind(DOP_CONC)),
     2            arrdat(arrind(EL)), arrdat(arrind(ET)),
     3            arrdat(arrind(EZ)), arrdat(arrind(EJ)),
     4            arrdat(arrind(E_QUASI_FERMI)),
     5            arrdat(arrind(H_QUASI_FERMI)),
     6            arrdat(arrind(E_LAT_CUR)),arrdat(arrind(E_TRANS_CUR)),
     7            arrdat(arrind(H_LAT_CUR)),arrdat(arrind(H_TRANS_CUR)),
     8            arrdat(arrind(E_MOB)), arrdat(arrind(H_MOB)),
     9            arrdat(arrind(E_CHARGE)),arrdat(arrind(H_CHARGE)),
     A            arrdat(arrind(NET_CHARGE)),
     B            arrdat(arrind(E_LAT_VEL)),arrdat(arrind(E_TRANS_VEL)),
     C            arrdat(arrind(E_VEL_MAG)),
     D            arrdat(arrind(H_LAT_VEL)),arrdat(arrind(H_TRANS_VEL)),
     E            arrdat(arrind(H_VEL_MAG)),in_binary_file,
     F            nintr, ut, temperature, tox,
     G            vs, vb, xl, model, three_d, nonplanar_boundary, chtyp)
      call e_jmag(arrdat(arrind(EL)), arrdat(arrind(ET)),
     1            arrdat(arrind(EZ)), arrdat(arrind(MAG_E)),
     2            arrdat(arrind(E_LAT_CUR)),arrdat(arrind(E_TRANS_CUR)),
     3            arrdat(arrind(E_Z_CUR)), arrdat(arrind(E_CUR_MAG)),
     4            arrdat(arrind(H_LAT_CUR)),arrdat(arrind(H_TRANS_CUR)),
     5            arrdat(arrind(H_Z_CUR)), arrdat(arrind(H_CUR_MAG)),
     6            in_binary_file)
c
      write(luttyo,290)
290   format(' ','...done')
c
      call load_mini_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 input_binfile_double(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     Include large storage arrays
      include 'incore.cmn'
c
c     read double precision binary file
c
      logical batchmode, read_error
c
c     locals
c
      double precision vfb_dbl, tox_dbl, xw_dbl, xl_dbl
      double precision vs_dbl, vg_dbl, vd_dbl, vb_dbl, id_dbl, is_dbl
      double precision ib_dbl, li_dbl, ut_dbl, nintr_dbl
      real hin
      integer i, j, ilen, ioerr, string_len,
     1        nint, imdint, nyox, ierr, nrecl
      integer xbound_low, xbound_hi, ybound_low, ybound_hi, code,
     1        local_record
      character*1 ch
      character*80 dummy_title, appended_data_name
      character*(PM_MAX_PATHLEN) expanded_name
      logical std_binfile, plane_select_err, alloc_err
CC
CC    INCORE
      save nint, imdint
      integer icode, itmp
      logical threed_loaded, do_incore
      save threed_loaded
      data threed_loaded/.FALSE./
CC    END INCORE
c
      write(luttyo,10)
10    format(' ','Reading MINIMOS binary file...',$)
c
c     Append .BIN if no extension
      call add_extension(binfilename,'.bin')
c
CC    INCORE
c     If threed file already loaded, then read from it
      if( threed_loaded .and. binfilename .eq. prev_binfilename .and.
     1    binfiletype .eq. prev_binfiletype ) then
         write(luttyo,60)
60       format(' ','Info: Using 3D MINIMOS file previously read...')
         do_incore = .TRUE.
         icode = 3
      else
         do_incore = .FALSE.
      endif
c
      if( .NOT. do_incore ) then
         nrecl = 0
         call pm_open_file(binfil,binfilename,'OLD','UNFORMATTED',
     1                     'READ','NONE','NONSHARED',
     2                     nrecl, ioerr, ierr)
         if( ierr .ne. 0 ) goto 10000
         local_record = 1
         std_binfile = .FALSE.
      endif
c
c     get stem of binary file name
      call get_filestem(binfilename, binfilestem)
c
c     Multiple bias point branch point
20000 continue
c
c     clear out arrays
      if( .NOT. do_incore ) then
         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
      endif
CC
CC    END INCORE
CC
      do 50 j=1,ARRAYSIZE
         work_dbl(j) = 0.0
         foxo(j) = 0.0
         foxu(j) = 0.0
         fox_x(j) = 0.0
         fox_z(j) = 0.0
50       continue
      do 51 j=1,MENUSIZE
         in_binary_file(j) = .FALSE.
51       continue

CC    INCORE
      if( do_incore ) then
         itmp = plane_type
c        Ask user what plane to select
         if( batchmode ) then
c           Assumes cut_plane_axis and (plane_value or plane_index) have
c           been set before this call.
c           If plane_index = 0, then use plane_value to determine plane_index
c           Else, use plane_index to determine plane_value
c           Also sets plane_type, plane_actual_value
            call batch_select_plane(cut_plane_axis,
     1           plane_index, plane_value, 
     2           plane_type, plane_actual_value,
     3           xyz, nx, nytot, nz, plane_select_err)
            if( plane_select_err ) then
               read_error = .TRUE.
               return
            endif
         else
            call select_plane(plane_type, plane_index, plane_value,
     1                        plane_actual_value, xyz, nx, nytot, nz)
         endif
         prev_plane_type = itmp
c        Branch to code section that reads in 3D data.
         goto 5000
      endif
CC    END INCORE
c
      if( three_d ) then
         threed_loaded = .FALSE.
      endif
c
c     1. first read title from binary file
150   continue
      read(binfil,err=10010,iostat=ioerr) title
c
c     If title(68:76) is 'NONPLANAR', then this binary file has
c     nonplanar mesh data.
      if( title(68:76) .eq. 'NONPLANAR' ) then
         nonplanar_boundary = .TRUE.
      else
         nonplanar_boundary = .FALSE.
      endif
c
c     If title(77:80) is '--3D', then this binary file has
c     3D data in it.
      if( title(77:80) .eq. '--3D' ) then
         three_d = .TRUE.
         icode = 2
      else
         three_d = .FALSE.
         icode = 1
c        Free any dynamic memory we've allocated, and
c        set base address of dynamic arrays to NULL value (0),
c        just to have them set to a fixed value. We will pass incore to
c        subroutine read_3d_plane_core, but the array isn't used
c        in 2d mode, so we should be OK.
         call pm_free_incore_arrays
      endif
c
c     2. now read channel-type, flatband voltage, oxide thickness,
c     channel-width, and channel-length.
c     Also read in model (a Hudson local modifcation)
c     If this causes an error, then rewind the file and start over,
c     assuming a standard binfile format.
      if( std_binfile ) then
         read(binfil,err=1000,iostat=ioerr) chtyp,vfb_dbl,tox_dbl,
     1        xl_dbl,xw_dbl
      else
         read(binfil,err=1000,iostat=ioerr) chtyp,vfb_dbl,tox_dbl,
     1        xl_dbl,xw_dbl,model
      endif
1000  if(ioerr .eq. PM_INSUFF_DATA_IN_REC ) then
c        Insufficient data in record. Assume standard BIN file format
c        Rewind file and start over
         std_binfile = .TRUE.
         rewind(binfil)
         goto 150
      else if( ioerr .ne. 0 ) then
c        Other type of read error
         goto 10010
      endif
      
      vfb = SNGL(vfb_dbl)
      tox = SNGL(tox_dbl)
      xw  = SNGL(xw_dbl)
      xl  = SNGL(xl_dbl)
c
c     3. read bias condition
      read(binfil,err=10010,iostat=ioerr) vs_dbl,vg_dbl,
     1     vd_dbl,vb_dbl,id_dbl,is_dbl,ib_dbl
      vs = SNGL(vs_dbl)
      vg = SNGL(vg_dbl)
      vd = SNGL(vd_dbl)
      vb = SNGL(vb_dbl)
      id = SNGL(id_dbl)
      is = SNGL(is_dbl)
      ib = SNGL(ib_dbl)
c
c     4. read couple of physical constants
      read(binfil,err=10010,iostat=ioerr) li_dbl,ut_dbl,nintr_dbl
      li = SNGL(li_dbl)
      ut = SNGL(ut_dbl)
      nintr = SNGL(nintr_dbl)

c     5. read grid size counters
      if( three_d ) then
         read(binfil,err=10010,iostat=ioerr)
     1        nx,nt,ny,nyox,nytot,nxs,nxg1,
     2        nxg2,nxd,nz,nzsd,nza,nyfox
         nyoxm = nyox - 1
         nxsp = nxs + 1
         nxsoxm = nxd - 1
      else
         read(binfil,err=10010,iostat=ioerr)
     1        nx,nt,ny,nyoxm,nytot,nxsp,nxsoxm
         nz = 1
      endif
c
      if( std_binfile ) then
         if( nt .eq. ny ) then
            model = 3
         else
            model = 1
         endif
      endif
c
c     Is array storage large enough?
      if( MAX(nx,nytot,nz) .gt. ARRAYSIZE .or.
     1  (three_d .and. MAX(nx,nytot,nz) .gt. CORESIZE)) then
         write(luttyo,10050)
10050    format(' ','Error: binary file too large for POSTMINI arrays')
         read_error = .TRUE.  ! go back
         if( .NOT. do_incore ) close(unit=binfil)
         return
      endif
c
c     For 3D case, allocate dynamic storage...
      if( three_d ) then
         call pm_allocate_incore_arrays(alloc_err)
         if( alloc_err ) then
            write(luttyo,10051)
10051       format(' ',
     1             'Error: could not allocate array for 3D binary file')
            read_error = .TRUE.  ! go back
         endif
      endif
c
      nxy=nx*ny
      nxytot=nx*nytot
c     Note: this variable is the index of the top of the gate
c     It is determined (indirectly) in e_jcomp().
      nytop=1
c
c     6. read lateral spacing
      read(binfil,err=10010,iostat=ioerr) (work_dbl(i),i=1,nx)
      do 200 i=1,nx
200      xyz(i,1) = SNGL(work_dbl(i))
c
c     7. read transversal spacing
      read(binfil,err=10010,iostat=ioerr) (work_dbl(i),i=1,nytot)
      do 210 i=1,nytot
210      xyz(i,2) = SNGL(work_dbl(i))
c
c     7a. read width (Z) spacing
      prev_plane_type = plane_type
      if( three_d ) then
         read(binfil,err=10010,iostat=ioerr) (work_dbl(i),i=1,nz)
         do 215 i=1,nz
215         xyz(i,3) = SNGL(work_dbl(i))
c        Ask user what plane to select
         if( batchmode ) then
c           Assumes cut_plane_axis and (plane_value or plane_index) have
c           been set before this call.
c           If plane_index = 0, then use plane_value to determine plane_index
c           Else, use plane_index to determine plane_value
c           Also sets plane_type, plane_actual_value
            call batch_select_plane(cut_plane_axis,
     1           plane_index, plane_value, 
     2           plane_type, plane_actual_value,
     3           xyz, nx, nytot, nz, plane_select_err)
            if( plane_select_err ) then
               read_error = .TRUE.
               if( .NOT. do_incore ) close(unit=binfil)
               return
            endif
         else
            call select_plane(plane_type, plane_index, plane_value,
     1                        plane_actual_value, xyz, nx, nytot, nz)
         endif
      else
c        2D binary file
         plane_index = 1
         plane_type = XY_PLANE
         xyz(1,3) = -xw/2.0
      endif
c
CC    INCORE
c     incore code branches here after plane selection
5000  continue
CC    END INCORE
c
c     Load generic mesh pointers, depending on plane type
c
      call set_3d_index_limits
      call allocate_rect_arrays(ni,nj,NUM_DATA_ARRAYS,ierr)
      if( ierr .ne. 0 ) then
c        Failure during array allocation
         write(luttyo,10050)
         read_error = .TRUE.
         if( .NOT. do_incore ) close(unit=binfil)
         return
      endif
c     Zero arrays
      call zero_real_array(arrdat,ni*nj*NUM_DATA_ARRAYS,1)
      call zero_real_array(interface_charge,ARRAYSIZE,1)
c
      cut_plane_axis = charb
c     This variable must be set by all read routines...
      data_is_trigrid = .FALSE.
c
c     MINIMOS smiling poly flag
      mini_smile = .FALSE.
c
c     7b. Interface information
      if( nonplanar_boundary .or. three_d ) then
CC       INCORE
         if( .NOT. do_incore )
     1      read(binfil,err=10010,iostat=ioerr) nint, fox_nx, fox_nz,
     1                                          imdint
CC       END INCORE
         if( MAX(fox_nx,fox_nz) .gt. ARRAYSIZE .or.
     1     (three_d .and. MAX(fox_nx,fox_nz) .gt. CORESIZE)) then
            write(luttyo,10060)
10060       format(' ',
     1    'Error: nonplanar information too large for POSTMINI arrays')
            read_error = .TRUE.  ! go back
            if( .NOT. do_incore ) close(unit=binfil)
            return
         endif
c        Temporary code to fire wall against use of constant mesh
c        fox with 3D (code doesn't handle this case yet).
         if( three_d .and. imdint .eq. 2 ) then
            write(luttyo,*) 'Error: Can''t handle 3D bin file',
     1                 ' with oxide info on uniform mesh yet'
            read_error = .TRUE.  ! go back
            if( .NOT. do_incore ) close(unit=binfil)
            return
         endif
c
         if( imdint .eq. 1 ) then
            do i=1,fox_nx
               fox_x(i) = xyz(i,1)
            end do
            if( three_d ) then
               do i=1,fox_nz
                  fox_z(i) = xyz(i,3)
               end do
            else
               fox_z(1) = 0.0
            endif
         else if( imdint .eq. 2 ) then
            hin = (xyz(nx,1) - xyz(1,1))/(fox_nx-1)
            do i=1,fox_nx
               fox_x(i) = xyz(1,1) + hin*FLOAT(i-1)
            end do
            if( three_d ) then
               hin = (xyz(nz,3) - xyz(1,3))/(fox_nz-1)
            else
               hin = 0.0
            endif
            do i=1,fox_nz
               fox_z(i) = xyz(1,3) + hin*FLOAT(i-1)
            end do
         else
            write(luttyo,10070)
10070       format(' ',
     1    'Error: nonplanar information has unexpected value of imdint')
            read_error = .TRUE.  ! go back
            if( .NOT. do_incore ) close(unit=binfil)
            return
         endif
c
CC       INCORE
         if( .NOT. do_incore ) then
            read(binfil,err=10010,iostat=ioerr) dummy_title
            read(binfil,err=10010,iostat=ioerr)
     1         (work_dbl(i),i=1,fox_nx*fox_nz)
            if( three_d ) then
               do i=1,fox_nx*fox_nz
                  incore_2d(i,1) = work_dbl(i)
               end do
            endif
         else
            do i=1,fox_nx*fox_nz
               work_dbl(i) = incore_2d(i,1)
            end do
         endif
         call select_line_from_2d(work_dbl, foxo, fox_x, fox_z,
     1                            fox_nx, fox_nz,
     2                            plane_type, plane_index, ARRAYSIZE)
         if( .NOT. do_incore ) then
            read(binfil,err=10010,iostat=ioerr) dummy_title
            read(binfil,err=10010,iostat=ioerr)
     1        (work_dbl(i),i=1,fox_nx*fox_nz)
            if( three_d ) then
               do i=1,fox_nx*fox_nz
                  incore_2d(i,2) = work_dbl(i)
               end do
            endif
         else
            do i=1,fox_nx*fox_nz
               work_dbl(i) = incore_2d(i,2)
            end do
         endif
         call select_line_from_2d(work_dbl, foxu, fox_x, fox_z,
     1                            fox_nx, fox_nz,
     2                            plane_type, plane_index, ARRAYSIZE)
      endif
c
c     8. get doping concentration
      call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,1),
     1                       icode,
     1                       arrdat(arrind(DOP_CONC)),nx,ny,nz,nyoxm,
     2                       plane_index,plane_type,ni,nj,
     1                       ARRAYSIZE,CORESIZE,ierr,ioerr)
      if( ierr .ne. 0 ) goto 10010
      in_binary_file(DOPING_CODE) = .TRUE.

c
c     9. get potential distribution
      call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,2),
     1                   icode,
     1                   arrdat(arrind(PSI)),nx,nytot,nz,0,
     1                   plane_index,plane_type,ni,nj,
     1                   ARRAYSIZE,CORESIZE,ierr,ioerr)
      if( ierr .ne. 0 ) goto 10010
      in_binary_file(POTENTIAL_CODE) = .TRUE.
c
c     10. get minority carrier density
      if( chtyp .eq. 'N' ) then
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,3),
     1                      icode,
     1                      arrdat(arrind(E_CONC)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(ELEC_CC_CODE)  = .TRUE.
         in_binary_file(ELEC_QF_CODE)  = .TRUE.
      else
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,3),
     1                      icode,
     1                      arrdat(arrind(H_CONC)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(HOLE_CC_CODE)  = .TRUE.
         in_binary_file(HOLE_QF_CODE)  = .TRUE.
      endif

      if( three_d ) then
c
c        get majority carrier density
         if( chtyp .eq. 'N' ) then
            call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,4),
     1                   icode,
     1                   arrdat(arrind(H_CONC)),nx,nt,nz,nyoxm,
     1                   plane_index,plane_type,ni,nj,
     1                   ARRAYSIZE,CORESIZE,ierr,ioerr)
            if( ierr .ne. 0 ) goto 10010
            in_binary_file(HOLE_CC_CODE) = .TRUE.
            in_binary_file(HOLE_QF_CODE) = .TRUE.
         else
            call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,4),
     1                   icode,
     1                   arrdat(arrind(E_CONC)),nx,nt,nz,nyoxm,
     1                   plane_index,plane_type,ni,nj,
     1                   ARRAYSIZE,CORESIZE,ierr,ioerr)
            if( ierr .ne. 0 ) goto 10010
            in_binary_file(ELEC_CC_CODE) = .TRUE.
            in_binary_file(ELEC_QF_CODE) = .TRUE.
         endif
      endif
c
c     11. get minority mobility
      if( chtyp .eq. 'N' ) then
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,5),
     1                      icode,
     1                      arrdat(arrind(E_MOB)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(ELEC_MOB_CODE) = .TRUE.
      else
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,5),
     1                      icode,
     1                      arrdat(arrind(H_MOB)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(HOLE_MOB_CODE) = .TRUE.
      endif
c
c     11a. get minority mobility (transverse)
c     Note: we discard transverse mobility now. 17-May-91 jvf
      if( chtyp .eq. 'N' ) then
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,6),
     1                      icode,
     1                      work,nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
CC         in_binary_file(TRANS_ELEC_MOB_CODE) = .TRUE.
      else
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,6),
     1                      icode,
     1                      work,nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
CC         in_binary_file(TRANS_HOLE_MOB_CODE) = .TRUE.
      endif
c
c     12. and 13. get minority current density
      if( chtyp .eq. 'N' ) then
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,7),
     1                      icode,
     1                      arrdat(arrind(E_LAT_CUR)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(LAT_ELEC_CUR_CODE)   = .TRUE.
      else
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,7),
     1                      icode,
     1                      arrdat(arrind(H_LAT_CUR)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(LAT_HOLE_CUR_CODE)   = .TRUE.
      endif
      if( chtyp .eq. 'N' ) then
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,8),
     1                      icode,
     1                      arrdat(arrind(E_TRANS_CUR)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(TRANS_ELEC_CUR_CODE) = .TRUE.
         in_binary_file(MAG_ELEC_CUR_CODE)   = .TRUE.
      else
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,8),
     1                      icode,
     1                      arrdat(arrind(H_TRANS_CUR)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(TRANS_HOLE_CUR_CODE) = .TRUE.
         in_binary_file(MAG_HOLE_CUR_CODE)   = .TRUE.
      endif
      if( three_d ) then
c        Z component
         if( chtyp .eq. 'N' ) then
            call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,9),
     1                   icode,
     1                   arrdat(arrind(E_Z_CUR)),nx,nt,nz,nyoxm,
     1                   plane_index,plane_type,ni,nj,
     1                   ARRAYSIZE,CORESIZE,ierr,ioerr)
            if( ierr .ne. 0 ) goto 10010
            in_binary_file(Z_ELEC_CUR_CODE)   = .TRUE.
         else
            call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,9),
     1                   icode,
     1                   arrdat(arrind(H_Z_CUR)),nx,nt,nz,nyoxm,
     1                   plane_index,plane_type,ni,nj,
     1                   ARRAYSIZE,CORESIZE,ierr,ioerr)
            if( ierr .ne. 0 ) goto 10010
            in_binary_file(Z_HOLE_CUR_CODE)   = .TRUE.
         endif
      endif
c
      if ( .NOT. std_binfile .and. model.lt.4) go to 100
c
c     14. get majority carrier density
      if( .NOT. three_d ) then
         if( chtyp .eq. 'N' ) then
            call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,10),
     1                   icode,
     1                   arrdat(arrind(H_CONC)),nx,nt,nz,nyoxm,
     1                   plane_index,plane_type,ni,nj,
     1                   ARRAYSIZE,CORESIZE,ierr,ioerr)
c           Special case for standard binfiles
            if( ierr .eq. -1 .and. std_binfile ) goto 100
            if(ierr.eq.1 .and. std_binfile .and. .NOT. do_incore) then
               backspace(binfil)
               goto 100
            endif
            if( ierr .ne. 0 ) goto 10010
            in_binary_file(HOLE_CC_CODE) = .TRUE.
            in_binary_file(HOLE_QF_CODE) = .TRUE.
         else
            call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,10),
     1                   icode,
     1                   arrdat(arrind(E_CONC)),nx,nt,nz,nyoxm,
     1                   plane_index,plane_type,ni,nj,
     1                   ARRAYSIZE,CORESIZE,ierr,ioerr)
c           Special case for standard binfiles
            if( ierr .eq. -1 .and. std_binfile ) goto 100
            if( ierr .ne. 0 ) goto 10010
            if(ierr.eq.1 .and. std_binfile .and. .NOT. do_incore) then
               backspace(binfil)
               goto 100
            endif
            in_binary_file(ELEC_CC_CODE) = .TRUE.
            in_binary_file(ELEC_QF_CODE) = .TRUE.
         endif
      endif
c
c     15. get majority mobility (lateral)
      if( chtyp .eq. 'N' ) then
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,11),
     1                icode,
     1                arrdat(arrind(H_MOB)),nx,nt,nz,nyoxm,
     1                plane_index,plane_type,ni,nj,
     1                ARRAYSIZE,CORESIZE,ierr,ioerr)
c        Special case for standard binfiles
         if( three_d .and. ierr .eq. -1 .and. std_binfile )
     1        goto 100
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(HOLE_MOB_CODE) = .TRUE.
      else
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,11),
     1                icode,
     1                arrdat(arrind(E_MOB)),nx,nt,nz,nyoxm,
     1                plane_index,plane_type,ni,nj,
     1                ARRAYSIZE,CORESIZE,ierr,ioerr)
c        Special case for standard binfiles
         if( three_d .and. ierr .eq. -1 .and. std_binfile )
     1        goto 100
         if( ierr .ne. 0 ) goto 10010
             in_binary_file(ELEC_MOB_CODE) = .TRUE.
      endif
c     15a. get majority mobility (transverse)
c     Note: we discard transverse mobility now. 17-May-91 jvf
      if( chtyp .eq. 'N' ) then
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,12),
     1                icode,
     1                work,nx,nt,nz,nyoxm,
     1                plane_index,plane_type,ni,nj,
     1                ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
CC         in_binary_file(TRANS_HOLE_MOB_CODE) = .TRUE.
      else
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,12),
     1                icode,
     1                work,nx,nt,nz,nyoxm,
     1                plane_index,plane_type,ni,nj,
     1                ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
CC         in_binary_file(TRANS_ELEC_MOB_CODE) = .TRUE.
      endif
c
c     16. and 17. get majority current density
      if( chtyp .eq. 'N' ) then
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,13),
     1                icode,
     1                arrdat(arrind(H_LAT_CUR)),nx,nt,nz,nyoxm,
     1                plane_index,plane_type,ni,nj,
     1                ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(LAT_HOLE_CUR_CODE)  = .TRUE.
      else
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,13),
     1                icode,
     1                arrdat(arrind(E_LAT_CUR)),nx,nt,nz,nyoxm,
     1                plane_index,plane_type,ni,nj,
     1                ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(LAT_ELEC_CUR_CODE)  = .TRUE.
      endif
      if( chtyp .eq. 'N' ) then
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,14),
     1        icode,
     1        arrdat(arrind(H_TRANS_CUR)),nx,nt,nz,nyoxm,
     1        plane_index,plane_type,ni,nj,
     1        ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(TRANS_HOLE_CUR_CODE) = .TRUE.
         in_binary_file(MAG_HOLE_CUR_CODE)  = .TRUE.
      else
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,14),
     1        icode,
     1        arrdat(arrind(E_TRANS_CUR)),nx,nt,nz,nyoxm,
     1        plane_index,plane_type,ni,nj,
     1        ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
         in_binary_file(TRANS_ELEC_CUR_CODE) = .TRUE.
         in_binary_file(MAG_ELEC_CUR_CODE)  = .TRUE.
      endif
      if( three_d ) then
c        Z component
         if( chtyp .eq. 'N' ) then
            call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,15),
     1                      icode,
     1                      arrdat(arrind(H_Z_CUR)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
            if( ierr .ne. 0 ) goto 10010
            in_binary_file(Z_HOLE_CUR_CODE)  = .TRUE.
         else
            call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,15),
     1                      icode,
     1                      arrdat(arrind(E_Z_CUR)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
            if( ierr .ne. 0 ) goto 10010
            in_binary_file(Z_ELEC_CUR_CODE)  = .TRUE.
         endif
      endif
c
c     18. get avalanche generation rate
      call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,16),
     1                   icode,
     1                   arrdat(arrind(AVAL)),nx,nt,nz,nyoxm,
     1                   plane_index,plane_type,ni,nj,
     1                   ARRAYSIZE,CORESIZE,ierr,ioerr)
      if( ierr .ne. 0 ) goto 10010
      in_binary_file(AVAL_CODE) = .TRUE.
      if( std_binfile ) model = 4
c
      if( .NOT. std_binfile .and. model .lt. 5 ) goto 100
c
c     20. Electron temperature
c
c     Note: we read this in and store it, but we don't let user see
c     it in the various menus. See comment in load_mini_specific
c     for details on how to let user have access to this data.
      if( chtyp .eq. 'N' ) then
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,17),
     1                      icode,
     1                      arrdat(arrind(E_TEMP)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
c        Special case for standard binfiles
         if( ierr .eq. -1 .and. std_binfile ) goto 100
         if( ierr .eq. 1 .and. std_binfile .and. .NOT. do_incore) then
            backspace(binfil)
            goto 100
         endif
         if( ierr .ne. 0 ) goto 10010
      else
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,17),
     1                      icode,
     1                      arrdat(arrind(H_TEMP)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
c        Special case for standard binfiles
         if( ierr .eq. -1 .and. std_binfile ) goto 100
         if( ierr .eq. 1 .and. std_binfile .and. .NOT. do_incore) then
            backspace(binfil)
            goto 100
         endif
         if( ierr .ne. 0 ) goto 10010
      endif
      if( chtyp .eq. 'N' ) then
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,18),
     1                      icode,
     1                      arrdat(arrind(H_TEMP)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
      else
         call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,18),
     1                      icode,
     1                      arrdat(arrind(E_TEMP)),nx,nt,nz,nyoxm,
     1                      plane_index,plane_type,ni,nj,
     1                      ARRAYSIZE,CORESIZE,ierr,ioerr)
         if( ierr .ne. 0 ) goto 10010
      endif
      in_binary_file(ELEC_TEMP_CODE) = .TRUE.
      in_binary_file(HOLE_TEMP_CODE) = .TRUE.
      if( std_binfile ) model = 5
c
100   continue
c
c     Skip appended data (only for 2d binary file anyway)
      if( do_incore ) goto 140
c
c     Attempt to read appended data. If we get an end-of-file,
c     then there was no attached data.
c
      do while(.TRUE.)
c
c        We exit do while by the err=... on the next read statement.
c
         read(binfil,err=105,end=105,iostat=ioerr) code
c        Use code to determine what data is next in binary file...
c
c        Check for valid codes. We may have read the first record
c        of the next dataset...
         if( code .lt. 30 .or. code .gt. 100 ) then
c           Invalid code, check for next record
c           On some operating systems (e.g. Ultrix, SUN), the FORTRAN ENDFILE
c           statement does not create an endfile record in the binary file.
c           (DEC FORTRAN can force this with the -vms compile switch).
c           Thus, the next dataset may appear directly after the end of the
c           first dataset.
c           Check to see if this is the start of another binary data set.
c           If the read is sucessful, then assume a new dataset is appended.
            backspace(binfil)
            read(binfil,err=10010,end=10010,iostat=ioerr) title
            backspace(binfil)
            goto 105
         endif
c
c        Gaussian fixed surface states
         if( code .eq. 30 ) then
            read(binfil,err=10010,iostat=ioerr) appended_data_name,
     1          xbound_low, xbound_hi, ybound_low, ybound_hi
            read(binfil,err=10010,iostat=ioerr) 
     1           (work_dbl(i),i=xbound_low,xbound_hi)
            call copy_dbl_to_single(work_dbl,interface_charge,
     1              ARRAYSIZE,1)
            in_binary_file(INTERFACE_CHARGE_CODE) = .TRUE.

c
c        Chargeable surface state distribution
         else if( code .eq. 31 ) then
            read(binfil,err=10010,iostat=ioerr) appended_data_name,
     1           xbound_low, xbound_hi, ybound_low, ybound_hi
            read(binfil,err=10010,iostat=ioerr) 
     1           (work_dbl(i),i=xbound_low,xbound_hi)
            call copy_dbl_to_single(work_dbl,fss_charge_dist,
     1              ARRAYSIZE,1)
            in_binary_file(FSS_CHARGE_DIST_CODE) = .TRUE.
c
c        Charged surface state distribution
         else if( code .eq. 32 ) then
            read(binfil,err=10010,iostat=ioerr) appended_data_name,
     1           xbound_low, xbound_hi, ybound_low, ybound_hi
            read(binfil,err=10010,iostat=ioerr) 
     1           (work_dbl(i),i=xbound_low,xbound_hi)
            call copy_dbl_to_single(work_dbl,fss_charge,
     1              ARRAYSIZE,1)
            in_binary_file(FSS_CHARGE_CODE) = .TRUE.
c
c        Majority carrrier density (model <= 3)
         else if( code .eq. 33 ) then
            read(binfil,err=10010,iostat=ioerr) appended_data_name,
     1           xbound_low, xbound_hi, ybound_low, ybound_hi
            if( chtyp .eq. 'N' ) then
c              This index on incore (18) is just a placeholder,
c              as this data is only produced in 2D binary files...
               call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,18),
     1                            icode,
     1                            arrdat(arrind(H_CONC)),nx,nt,nz,nyoxm,
     1                            plane_index,plane_type,ni,nj,
     1                            ARRAYSIZE,CORESIZE,ierr,ioerr)
              if( ierr .ne. 0 ) goto 10010
              in_binary_file(HOLE_CC_CODE)  = .TRUE.
              in_binary_file(HOLE_QF_CODE)  = .TRUE.
           else
              call read_3d_plane_core(binfil,work_dbl,incore(1,1,1,18),
     1                           icode,
     1                           arrdat(arrind(H_CONC)),nx,nt,nz,nyoxm,
     1                           plane_index,plane_type,ni,nj,
     1                           ARRAYSIZE,CORESIZE,ierr,ioerr)
               if( ierr .ne. 0 ) goto 10010
               in_binary_file(HOLE_CC_CODE)  = .TRUE.
               in_binary_file(HOLE_QF_CODE)  = .TRUE.
            endif
c
c        Smiling poly information
         else if( code .eq. 34 ) then
            read(binfil,err=10010,iostat=ioerr) appended_data_name,
     1           xbound_low, xbound_hi, ybound_low, ybound_hi
            read(binfil,err=10010,iostat=ioerr) 
     1           (work_dbl(i),i=xbound_low,xbound_hi)
            call copy_dbl_to_single(work_dbl,foxu,nx,1)
            mini_smile = .TRUE.
         else
c           Read any other extensions, but don't do anything with the data
            read(binfil,err=10010,iostat=ioerr) appended_data_name,
     1           xbound_low, xbound_hi, ybound_low, ybound_hi
            j=(xbound_hi - xbound_low + 1)*(ybound_hi - ybound_low + 1)
            read(binfil,err=10010,iostat=ioerr) (work_dbl(i),i=1,j)
         endif
      enddo
c
105   continue
c
      if( batchmode ) then
         if( local_record .ne. datafile_record ) then
            local_record = local_record + 1
            goto 20000
         else
            write(luttyo,121) vs,vg,vd,vb
121         format(' ','Bias point information:'/
     1             ' ','Source = ',f8.3,'  Gate = ',f8.3,
     1               '  Drain = ',f8.3,'  Bulk = ',f8.3)
         endif
      else
c        Test for next dataset, if EOF then branch to a special handler
         read(binfil,err=10010,end=130,iostat=ioerr) title
         backspace(binfil)
         if( local_record .eq. 1 ) then
            write(luttyo,122)
122         format(/' ','Info: binary file has multiple bias points')
         endif
         write(luttyo,123) vs,vg,vd,vb
123      format(/' ','Loaded MINIMOS data set with bias:'/
     1           ' ','Source = ',f8.3,'  Gate = ',f8.3,
     1             '  Drain = ',f8.3,'  Bulk = ',f8.3)
         call get_char(ch,
     1      'Do you wish to read the next bias point? (y/n) [N] ',0)
         call upcase(ch)
         if( ch .eq. 'Y' ) then
            local_record = local_record + 1
            goto 20000
         endif
         goto 140
c
c        EOF reached
130      continue
         if( local_record .gt. 1 ) then
            write(luttyo,131) vs,vg,vd,vb
131         format(/' ','Info: ***final bias point in file reached***'/
     1              ' ','Loaded MINIMOS data set with bias:'/
     1              ' ','Source = ',f8.3,'  Gate = ',f8.3,
     1                '  Drain = ',f8.3,'  Bulk = ',f8.3)
           call get_char(ch,
     1      'Accept this bias point, or Rewind file and start over?' //
     2      ' (A/R) [A] ',0)
            call upcase(ch)
            if( ch .eq. 'R' ) then
               rewind(binfil)
               local_record = 1
               goto 20000
            endif
         endif
      endif
c
140   continue
      write(luttyo,141)
141   format(' ','...done')
      datafile_record = local_record
      read_error = .FALSE.
      if( .NOT. do_incore ) close(unit=binfil)
      if( three_d ) then
         threed_loaded = .TRUE.
      endif
      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. PM_INSUFF_DATA_IN_REC ) then
c        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...
      if( .NOT. do_incore ) close(unit=binfil)
      goto 10100
c
10100 continue
      return
      end
c
      subroutine load_mini_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
c     NOTE WELL. If you want to let user access carrier temperatures
c     from MODEL=HOT, increase max_menu_num to 36. It is kept at 34
c     in order to make the MINIMOS data menu print out on a 24x80 terminal
c     screen without overflowing. 17-May-91 jvf
      max_menu_num = 34
c     Array index of net doping
      net_dop_array_index = 2
c
      call load_desc_arr(1, 'Potential', 'POTENTIAL',
     1                   'V','V cm','V cm^{2}','.psi',
     2                   LIN,OX,NO_JUMP,TWOD,1)
c
      call load_desc_arr(2, 'Doping Concentration', 'NET_DOPING',
     1                   'cm^{-3}','cm^{-2}','cm^{-1}','.dconc',
     2                   LOG,NO_OX,NO_JUMP,TWOD,2)
c
      call load_desc_arr(3, 'Electron Concentration', 'ELECTRONS',
     1                   'cm^{-3}','cm^{-2}','cm^{-1}','.econc',
     2                   LOG,NO_OX,NO_JUMP,TWOD,3)
c
      call load_desc_arr(4, 'Hole Concentration', 'HOLES',
     1                   'cm^{-3}','cm^{-2}','cm^{-1}','.hconc',
     2                   LOG,NO_OX,NO_JUMP,TWOD,4)
c
      call load_desc_arr(5, 'Electric field (x-comp)', 'EX',
     1                   'V/cm','V','V cm','.ex',
     2                   LIN,OX,NO_JUMP,TWOD,5)
c
      call load_desc_arr(6, 'Electric field (y-comp)', 'EY',
     1                   'V/cm','V','V cm','.ey',
     2                   LIN,OX,JUMP,TWOD,6)
c
      call load_desc_arr(7, 'E field in direction of current', 'EJ',
     1                   'V/cm','V','V cm','.ej',
     2                   LIN,NO_OX,NO_JUMP,TWOD,7)
c
      call load_desc_arr(8, 'Mag. electric field', 'EMAG',
     1                   'V/cm','V','V cm','.emag',
     2                   LIN,OX,NO_JUMP,TWOD,8)
c
      call load_desc_arr(9, 'Electron current (x-comp)', 'JX_N',
     1                   'A/cm^{2}','A/cm','A','.jx_e',
     2                   LOG,NO_OX,NO_JUMP,TWOD,9)
c
      call load_desc_arr(10, 'Electron current (y-comp)', 'JY_N',
     1                   'A/cm^{2}','A/cm','A','.jy_e',
     2                   LOG,NO_OX,NO_JUMP,TWOD,10)
c
      call load_desc_arr(11, 'Mag. electron current', 'JMAG_N',
     1                   'A/cm^{2}','A/cm','A','.jmag_e',
     2                   LOG,NO_OX,NO_JUMP,TWOD,11)
c
      call load_desc_arr(12, 'Hole current (x-comp)', 'JX_P',
     1                   'A/cm^{2}','A/cm','A','.jx_h',
     2                   LOG,NO_OX,NO_JUMP,TWOD,12)
c
      call load_desc_arr(13, 'Hole current (y-comp)', 'JY_P',
     1                   'A/cm^{2}','A/cm','A','.jy_h',
     2                   LOG,NO_OX,NO_JUMP,TWOD,13)
c
      call load_desc_arr(14, 'Mag. hole current', 'JMAG_H',
     1                   'A/cm^{2}','A/cm','A','.jmag_h',
     2                   LOG,NO_OX,NO_JUMP,TWOD,14)
c
      call load_desc_arr(15, 'Avalanche generation', 'AVL',
     1                   'cm^{-3}','cm^{-2}','cm^{-1}','.avl',
     2                   LOG,NO_OX,NO_JUMP,TWOD,15)
c
      call load_desc_arr(16, 'Electron qFermi level', 'QFN',
     1                   'V','V cm','V cm^{2}','.qf_e',
     2                   LIN,NO_OX,NO_JUMP,TWOD,16)
c
      call load_desc_arr(17, 'Hole qFermi level', 'QFP',
     1                   'V','V cm','V cm^{2}','.qf_h',
     2                   LIN,NO_OX,NO_JUMP,TWOD,17)
c
      call load_desc_arr(18, 'Electron mobility', 'MU_N',
     1                   'cm^{2}/V s','cm^{3}/V s','cm^{4}/V s',
     2                   '.mu_e',
     3                   LIN,NO_OX,NO_JUMP,TWOD,18)
c
      call load_desc_arr(19, 'Hole mobility', 'MU_P',
     1                   'cm^{2}/V s','cm^{3}/V s','cm^{4}/V s',
     2                   '.mu_h',
     3                   LIN,NO_OX,NO_JUMP,TWOD,19)
c
      call load_desc_arr(20, 'N_{d}^{+} - n', 'EXCESS_N',
     1                   'cm^{-3}','cm^{-2}','cm^{-1}','.ch_e',
     2                   LOG,NO_OX,NO_JUMP,TWOD,20)
c
      call load_desc_arr(21, 'p - N_{a}^{-}', 'EXCESS_P',
     1                   'cm^{-3}','cm^{-2}','cm^{-1}','.ch_h',
     2                   LOG,NO_OX,NO_JUMP,TWOD,21)
c
      call load_desc_arr(22, 'Net charge density', 'NET_CHARGE',
     1                   'cm^{-3}','cm^{-2}','cm^{-1}','.ch_net',
     2                   LOG,NO_OX,NO_JUMP,TWOD,22)
c
      call load_desc_arr(23, 'Fixed interface charge', 'NSS',
     1                   'cm^{-2}','cm{-1}','cm','.nss',
     2                   LIN,NO_OX,NO_JUMP,ONED,1)
c
      call load_desc_arr(24, 'Fast interface charge', 'DIT',
     1                   'cm^{-2}','cm{-1}','cm','.fss',
     2                   LIN,NO_OX,NO_JUMP,ONED,2)
c
      call load_desc_arr(25, 'Charged fast interface charge',
     1                   'DIT_CHARGED',
     2                   'cm^{-2}','cm{-1}','cm','.ch_fss',
     3                   LIN,NO_OX,NO_JUMP,ONED,3)
c
      call load_desc_arr(26, 'Electron current (z-comp)', 'JZ_N',
     1                   'A/cm','A','A cm','.jz_e',
     2                   LOG,NO_OX,NO_JUMP,TWOD,23)
c
      call load_desc_arr(27, 'Hole current (z-comp)', 'JZ_P',
     1                   'A/cm','A','A cm','.jz_h',
     2                   LOG,NO_OX,NO_JUMP,TWOD,24)
c
      call load_desc_arr(28, 'Electric field (z-comp)', 'EZ',
     1                   'V/cm','V','V cm','.ez',
     2                   LIN,OX,NO_JUMP,TWOD,25)
c
      call load_desc_arr(29, 'Electron velocity (x-comp)', 'VX_N',
     1                   'cm/s','cm^{2}/s','cm^{3}/s','.evx',
     2                   LIN,OX,NO_JUMP,TWOD,26)
c
      call load_desc_arr(30, 'Electron velocity (y-comp)', 'VY_N',
     1                   'cm/s','cm^{2}/s','cm^{3}/s','.evy',
     2                   LIN,OX,NO_JUMP,TWOD,27)
c
      call load_desc_arr(31, 'Electron velocity (mag)', 'VMAG_N',
     1                   'cm/s','cm^{2}/s','cm^{3}/s','.ev_mag',
     2                   LIN,OX,NO_JUMP,TWOD,28)
c
      call load_desc_arr(32, 'Hole velocity (x-comp)', 'VX_P',
     1                   'cm/s','cm^{2}/s','cm^{3}/s','.hvx',
     2                   LIN,OX,NO_JUMP,TWOD,29)
c
      call load_desc_arr(33, 'Hole velocity (y-comp)', 'VY_P',
     1                   'cm/s','cm^{2}/s','cm^{3}/s','.hvy',
     2                   LIN,OX,NO_JUMP,TWOD,30)
c
      call load_desc_arr(34, 'Hole velocity (mag)', 'VMAG_P',
     1                   'cm/s','cm^{2}/s','cm^{3}/s','.hv_mag',
     2                   LIN,OX,NO_JUMP,TWOD,31)
c
      call load_desc_arr(35, 'Electron temperature', 'TEMP_E',
     1                   'K','K cm','K cm^{2}','.etemp',
     2                   LIN,NO_OX,NO_JUMP,TWOD,32)
c
      call load_desc_arr(36, 'Hole temperature', 'TEMP_P',
     1                   'K','K cm','K cm^{2}','.htemp',
     2                   LIN,NO_OX,NO_JUMP,TWOD,33)
c
      return
      end
c
      subroutine load_desc_arr(menu_id, name, nickname,
     1                   units, units1, units2, extension,
     2                   do_log, value_in_oxide, jump_at_ox, data_1d,
     3                   arr_index)
      implicit none
c
      include 'const.h'
      include 'sysdep.cmn'
      include 'io.cmn'
      include 'data.cmn'
c
      integer menu_id, arr_index
      character*(*) name, units, units1, units2, extension,
     1              nickname
      logical do_log, value_in_oxide, jump_at_ox, data_1d
c
      if( menu_id .le. 0 .or. menu_id .gt. MENUSIZE ) then
         write(luttyo,100) menu_id
100      format(' ','Internal error (load_desc_arr): menu_id (',i5,
     1              ') out of bounds')
         goto 1000
      endif
c
      if( data_1d .and.
     1    (arr_index .le. 0 .or. arr_index .gt. MENUSIZE) ) then
         write(luttyo,200) arr_index
200      format(' ','Internal error (load_desc_arr): arr_index (',i5,
     1              ') out of bounds for 1d data')
         goto 1000
      endif
c
      if( .NOT. data_1d .and.
     1    (arr_index .le. 0 .or. arr_index .gt. NUM_DATA_ARRAYS) ) then
         write(luttyo,300) arr_index
300      format(' ','Internal error (load_desc_arr): arr_index (',i5,
     1              ') out of bounds for 2d data')
         goto 1000
      endif
c
      data_name(menu_id)         = name
      data_nickname(menu_id)     = nickname
      data_name_int_1d(menu_id)  = 'Int of ' // name
      data_units(menu_id)        = units
      data_units_int_1d(menu_id) = units1
      data_units_int_2d(menu_id) = units2
      data_file_ext(menu_id)     = extension
      is_data_log(menu_id)       = do_log
      is_data_in_oxide(menu_id)  = value_in_oxide
      does_data_jump_at_oxide(menu_id) = jump_at_ox
      is_data_1d(menu_id)        = data_1d
      menu_to_arr(menu_id)       = arr_index
c
1000  return
      end
c
      subroutine lookup_menuid_from_nickname(nickname, menu_id)
      implicit none
c
      include 'const.h'
      include 'sysdep.cmn'
      include 'data.cmn'
c
c     Given quantity nickname, returns menu id number.
c     Returns -1 in menu_id if nickname does not match.
c
      integer menu_id
      character*(*) nickname
c
      integer i
c
      menu_id = -1
c
      do 1000 i=1,max_menu_num
         if( nickname .eq. data_nickname(i) ) then
            menu_id = i
            goto 1001
         endif
1000  continue
1001  continue
c
      return
      end
c
      subroutine read_3d_plane_core(binfil,work,core,
     1                      icode,
     2                      dest,nx,ny,nz,y_offset,
     3                      plane_index,plane_type,
     3                      ni,nj,isize,icore,
     4                      ierr,ioerr)
      implicit none
c
      include 'const.h'
c
      integer binfil, icode, nx, ny, nz, y_offset,
     1        plane_type, plane_index, ni, nj,
     2        isize, icore, ierr, ioerr
      double precision  work(isize*isize)
      real    dest(ni,nj), core(icore*icore,icore)
c
c     ICODE == 1 -> Read from file,        do not load in core
c     ICODE == 2 -> Read from file,        load to core
c     ICODE == 3 -> Do not read from file, load from core
c
      integer i, iz, k, zero_offset
c
      ierr = 0
      zero_offset = y_offset*nx
c
      if(plane_type .eq. XY_PLANE) then
         do iz=1,plane_index
            if( icode .lt. 3 ) then
               read(binfil,err=1000,end=2000,iostat=ioerr)
     1             (work(i),i=1,nx*ny)
               if( icode .eq. 2 ) then
                  do i=1,nx*ny
                     core(i,iz) = SNGL(work(i))
                  end do
               endif
            endif
         end do
         do k=1,ny
            do i=1,nx
               if( icode .eq. 3 ) then
                  dest(i,k+y_offset) = core(i + nx*(k-1),plane_index)
               else
                  dest(i,k+y_offset) = SNGL(work(i + nx*(k-1)))
               endif
            end do
         end do
c        Skip over rest of planes
         do iz=plane_index+1,nz
            if( icode .lt. 3 ) then
               read(binfil,err=1000,end=2000,iostat=ioerr)
     1             (work(i),i=1,nx*ny)
               if( icode .eq. 2 ) then
                  do i=1,nx*ny
                     core(i,iz) = SNGL(work(i))
                  end do
               endif
            endif
         end do
c
      else if (plane_type .eq. YZ_PLANE) then
         do iz=1,nz
            if( icode .lt. 3 ) then
               read(binfil,err=1000,end=2000,iostat=ioerr)
     1             (work(i),i=1,nx*ny)
               if( icode .eq. 2 ) then
                  do i=1,nx*ny
                     core(i,iz) = SNGL(work(i))
                  end do
               endif
            endif
            do k=1,ny
               if( icode .eq. 3 ) then
                  dest(iz,k+y_offset) = 
     1               core(plane_index + nx*(k-1),iz)
               else
                  dest(iz,k+y_offset) = 
     1               SNGL(work(plane_index + nx*(k-1)))
               endif
            end do
         end do
c
      else if (plane_type .eq. XZ_PLANE) then
         do iz=1,nz
            if( icode .lt. 3 ) then
               read(binfil,err=1000,end=2000,iostat=ioerr)
     1             (work(i + zero_offset),i=1,nx*ny)
               if( icode .eq. 2 ) then
                  do i=1,nx*ny
                     core(i + zero_offset,iz) =
     1                  SNGL(work(i + zero_offset))
                  end do
               endif
            endif
            do k=1,nx
               if( icode .eq. 3 ) then
                  dest(k,iz) = 
     1               core(nx*(plane_index-1) + k,iz)
               else
                  dest(k,iz) = 
     1               SNGL(work(nx*(plane_index-1) + k))
               endif
            end do
         end do
      else
         ierr = 1
      endif
c
      return
c
1000  ierr = 1
      return
c
2000  ierr = -1
      end

