plot_read_unk Subroutine

private subroutine plot_read_unk(wfnname, formatted, spinors, inc_band, num_inc, num_bands, kpt, ngx, ngy, ngz, wvfn, wvfn_nc, stdout, error, comm)

Uses

  • proc~~plot_read_unk~~UsesGraph proc~plot_read_unk plot_read_unk module~w90_comms w90_comms proc~plot_read_unk->module~w90_comms module~w90_constants w90_constants proc~plot_read_unk->module~w90_constants module~w90_error w90_error proc~plot_read_unk->module~w90_error module~w90_comms->module~w90_constants module~w90_error_base w90_error_base module~w90_comms->module~w90_error_base module~w90_error->module~w90_comms module~w90_error->module~w90_error_base

Read a single UNK file into wvfn (or wvfn_nc for spinors), keeping the first num_inc bands flagged in inc_band (bands not flagged are read and discarded).

Failures set the error and return immediately. This is safe even though the caller distributes k-points over ranks: set_error_file synchronises the failing rank via comms_sync_error, and the other ranks pick the error up in the matching handshake at their next synchronised collective (e.g. the comms_reduce after the caller's k-point loop).

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: wfnname

Name of the UNK file to read

logical, intent(in) :: formatted

Whether the UNK file is formatted

logical, intent(in) :: spinors

Whether the wavefunctions are spinors

logical, intent(in) :: inc_band(:)

Bands to keep

integer, intent(in) :: num_inc

Number of bands to keep

integer, intent(in) :: num_bands

Total number of bands in the file

integer, intent(in) :: kpt

Expected k-point index (checked against the file header)

integer, intent(in) :: ngx

Expected grid dimensions (checked against the file header)

integer, intent(in) :: ngy

Expected grid dimensions (checked against the file header)

integer, intent(in) :: ngz

Expected grid dimensions (checked against the file header)

complex(kind=dp), intent(inout), allocatable :: wvfn(:,:)

Destination, band as second index (caller-allocated; if .not. spinors)

complex(kind=dp), intent(inout), allocatable :: wvfn_nc(:,:,:)

Spinor destination, spin as third index (caller-allocated; if spinors)

integer, intent(in) :: stdout
type(w90_error_type), intent(out), allocatable :: error
type(w90_comm_type), intent(in) :: comm

Calls

proc~~plot_read_unk~~CallsGraph proc~plot_read_unk plot_read_unk proc~set_error_file set_error_file proc~plot_read_unk->proc~set_error_file proc~comms_sync_error comms_sync_error proc~set_error_file->proc~comms_sync_error proc~set_base_error set_base_error proc~set_error_file->proc~set_base_error

Called by

proc~~plot_read_unk~~CalledByGraph proc~plot_read_unk plot_read_unk proc~plot_wannier plot_wannier proc~plot_wannier->proc~plot_read_unk proc~plot_main plot_main proc~plot_main->proc~plot_wannier proc~w90_plot w90_plot proc~w90_plot->proc~plot_main program~wannier wannier program~wannier->proc~w90_plot

Source Code

  subroutine plot_read_unk(wfnname, formatted, spinors, inc_band, num_inc, num_bands, &
                           kpt, ngx, ngy, ngz, wvfn, wvfn_nc, stdout, error, comm)
    !! Read a single UNK file into `wvfn` (or `wvfn_nc` for spinors), keeping
    !! the first `num_inc` bands flagged in `inc_band` (bands not flagged are
    !! read and discarded).
    !!
    !! Failures set the error and return immediately. This is safe even though
    !! the caller distributes k-points over ranks: set_error_file synchronises
    !! the failing rank via comms_sync_error, and the other ranks pick the
    !! error up in the matching handshake at their next synchronised
    !! collective (e.g. the comms_reduce after the caller's k-point loop).

    use w90_constants, only: dp
    use w90_comms, only: w90_comm_type
    use w90_error, only: w90_error_type, set_error_file

    implicit none

    character(len=*), intent(in) :: wfnname
    !! Name of the UNK file to read
    logical, intent(in) :: formatted
    !! Whether the UNK file is formatted
    logical, intent(in) :: spinors
    !! Whether the wavefunctions are spinors
    logical, intent(in) :: inc_band(:)
    !! Bands to keep
    integer, intent(in) :: num_inc
    !! Number of bands to keep
    integer, intent(in) :: num_bands
    !! Total number of bands in the file
    integer, intent(in) :: kpt
    !! Expected k-point index (checked against the file header)
    integer, intent(in) :: ngx, ngy, ngz
    !! Expected grid dimensions (checked against the file header)
    complex(kind=dp), allocatable, intent(inout) :: wvfn(:, :)
    !! Destination, band as second index (caller-allocated; if .not. spinors)
    complex(kind=dp), intent(inout), allocatable :: wvfn_nc(:, :, :)
    !! Spinor destination, spin as third index (caller-allocated; if spinors)
    integer, intent(in) :: stdout
    type(w90_error_type), allocatable, intent(out) :: error
    type(w90_comm_type), intent(in) :: comm

    integer :: file_unit, ierr, ix, iy, iz, ik, nbnd, counter, loop_b, ngpts

    logical :: have_file

    ngpts = ngx*ngy*ngz

    ! A missing UNK file must be detected here rather than silently
    ! (re)created by the open below (status='old' forbids creation).
    inquire (file=wfnname, exist=have_file)
    if (.not. have_file) then
      call set_error_file(error, 'plot_wannier: file '//wfnname//' not found', comm)
      return
    end if

    if (formatted) then
      open (newunit=file_unit, file=wfnname, form='formatted', status='old', iostat=ierr)
    else
      open (newunit=file_unit, file=wfnname, form='unformatted', status='old', iostat=ierr)
    end if
    if (ierr /= 0) then
      call set_error_file(error, 'plot_wannier: could not open file '//wfnname, comm)
      return
    end if

    if (formatted) then
      read (file_unit, *, iostat=ierr) ix, iy, iz, ik, nbnd
    else
      read (file_unit, iostat=ierr) ix, iy, iz, ik, nbnd
    end if
    if (ierr /= 0) then
      call set_error_file(error, 'plot_wannier: error reading file '//wfnname, comm)
      close (file_unit)
      return
    end if

    if ((ix /= ngx) .or. (iy /= ngy) .or. (iz /= ngz) .or. (ik /= kpt)) then
      write (stdout, '(1x,a,a)') 'WARNING: mismatch in file', trim(wfnname)
      write (stdout, '(1x,5(a6,I5))') '   ix=', ix, '   iy=', iy, '   iz=', iz, '   ik=', ik, ' nbnd=', nbnd
      write (stdout, '(1x,5(a6,I5))') '  ngx=', ngx, '  ngy=', ngy, '  ngz=', ngz, '  kpt=', kpt, 'bands=', num_bands
      call set_error_file(error, 'plot_wannier: mismatch in file '//wfnname, comm)
      close (file_unit)
      return
    end if

    counter = 1
    do loop_b = 1, num_bands
      if (counter > num_inc) exit
      if (.not. spinors) then
        call plot_read_unk_band(wvfn(:, counter))
      else
        call plot_read_unk_band(wvfn_nc(:, counter, 1)) ! up-spinor
        if (ierr == 0) call plot_read_unk_band(wvfn_nc(:, counter, 2)) ! down-spinor
      end if
      if (ierr /= 0) then
        call set_error_file(error, 'plot_wannier: error reading file '//wfnname, comm)
        close (file_unit)
        return
      end if
      if (inc_band(loop_b)) counter = counter + 1
    end do

    close (file_unit)

  contains

    subroutine plot_read_unk_band(band)
      !! Read one band's worth of grid values, leaving any failure in `ierr`
      complex(kind=dp), intent(out) :: band(:)

      real(kind=dp) :: w_real, w_imag
      integer :: nx

      if (formatted) then
        do nx = 1, ngpts
          read (file_unit, *, iostat=ierr) w_real, w_imag
          if (ierr /= 0) return
          band(nx) = cmplx(w_real, w_imag, kind=dp)
        end do
      else
        read (file_unit, iostat=ierr) (band(nx), nx=1, ngpts)
      end if
    end subroutine plot_read_unk_band

  end subroutine plot_read_unk