overlap_read Subroutine

public subroutine overlap_read(kmesh_info, select_projection, au_matrix, m_matrix_local, num_bands, num_kpts, num_proj, num_wann, print_output, timing_level, cp_pp, use_bloch_phases, seedname, stdout, timer, dist_k, error, comm)

Uses

  • proc~~overlap_read~~UsesGraph proc~overlap_read overlap_read module~w90_error w90_error proc~overlap_read->module~w90_error module~w90_io w90_io proc~overlap_read->module~w90_io module~w90_types w90_types proc~overlap_read->module~w90_types module~w90_wannier90_types w90_wannier90_types proc~overlap_read->module~w90_wannier90_types module~w90_comms w90_comms module~w90_error->module~w90_comms module~w90_error_base w90_error_base module~w90_error->module~w90_error_base module~w90_constants w90_constants module~w90_io->module~w90_constants module~w90_types->module~w90_constants module~w90_wannier90_types->module~w90_constants module~w90_comms->module~w90_constants module~w90_comms->module~w90_error_base

Read the Mmn and Amn from files Note: one needs to call overlap_allocate first!

Arguments

Type IntentOptional Attributes Name
type(kmesh_info_type), intent(in) :: kmesh_info
type(select_projection_type), intent(in) :: select_projection
complex(kind=dp), intent(inout) :: au_matrix(:,:,:)
complex(kind=dp), intent(inout) :: m_matrix_local(:,:,:,:)
integer, intent(in) :: num_bands
integer, intent(in) :: num_kpts
integer, intent(in) :: num_proj
integer, intent(in) :: num_wann
type(print_output_type), intent(in) :: print_output
integer, intent(in) :: timing_level
logical, intent(in) :: cp_pp
logical, intent(in) :: use_bloch_phases
character(len=50), intent(in) :: seedname
integer, intent(in) :: stdout
type(timer_list_type), intent(inout) :: timer
integer, intent(in) :: dist_k(:)
type(w90_error_type), intent(out), allocatable :: error
type(w90_comm_type), intent(in) :: comm

Calls

proc~~overlap_read~~CallsGraph proc~overlap_read overlap_read proc~io_stopwatch_start io_stopwatch_start proc~overlap_read->proc~io_stopwatch_start proc~io_stopwatch_stop io_stopwatch_stop proc~overlap_read->proc~io_stopwatch_stop proc~mpirank mpirank proc~overlap_read->proc~mpirank proc~overlap_rotate overlap_rotate proc~overlap_read->proc~overlap_rotate proc~set_error_alloc set_error_alloc proc~overlap_read->proc~set_error_alloc proc~set_error_dealloc set_error_dealloc proc~overlap_read->proc~set_error_dealloc proc~set_error_fatal set_error_fatal proc~overlap_read->proc~set_error_fatal proc~set_error_file set_error_file proc~overlap_read->proc~set_error_file proc~overlap_rotate->proc~io_stopwatch_start proc~overlap_rotate->proc~io_stopwatch_stop proc~overlap_rotate->proc~set_error_fatal dspev dspev proc~overlap_rotate->dspev proc~comms_sync_error comms_sync_error proc~set_error_alloc->proc~comms_sync_error proc~set_base_error set_base_error proc~set_error_alloc->proc~set_base_error proc~set_error_dealloc->proc~comms_sync_error proc~set_error_dealloc->proc~set_base_error proc~set_error_fatal->proc~comms_sync_error proc~set_error_fatal->proc~set_base_error proc~set_error_file->proc~comms_sync_error proc~set_error_file->proc~set_base_error

Called by

proc~~overlap_read~~CalledByGraph proc~overlap_read overlap_read proc~overlaps overlaps proc~overlaps->proc~overlap_read program~wannier wannier program~wannier->proc~overlaps

Source Code

  subroutine overlap_read(kmesh_info, select_projection, au_matrix, m_matrix_local, num_bands, &
                          num_kpts, num_proj, num_wann, print_output, timing_level, cp_pp, &
                          use_bloch_phases, seedname, stdout, timer, dist_k, error, comm)
    !================================================!
    !! Read the Mmn and Amn from files
    !! Note: one needs to call overlap_allocate first!
    !
    !================================================!

    use w90_io, only: io_stopwatch_start, io_stopwatch_stop
    use w90_types, only: kmesh_info_type, print_output_type, timer_list_type
    use w90_wannier90_types, only: select_projection_type
    use w90_error

    implicit none

    ! arguments
    type(kmesh_info_type), intent(in) :: kmesh_info
    type(print_output_type), intent(in) :: print_output
    type(select_projection_type), intent(in) :: select_projection
    type(timer_list_type), intent(inout) :: timer
    type(w90_comm_type), intent(in) :: comm
    type(w90_error_type), allocatable, intent(out) :: error

    integer, intent(in) :: dist_k(:)
    integer, intent(in) :: num_bands
    integer, intent(in) :: num_kpts
    integer, intent(in) :: num_proj
    integer, intent(in) :: num_wann
    integer, intent(in) :: stdout
    integer, intent(in) :: timing_level

    complex(kind=dp), intent(inout) :: au_matrix(:, :, :)
    complex(kind=dp), intent(inout) :: m_matrix_local(:, :, :, :)

    logical, intent(in) :: cp_pp, use_bloch_phases

    character(len=50), intent(in) :: seedname

    ! local variables
    complex(kind=dp), allocatable :: mmn_tmp(:, :)
    real(kind=dp) :: m_real, m_imag, a_real, a_imag

    integer, allocatable :: map_kpts(:)
    integer :: mmn_in, amn_in, num_mmn, num_amn
    integer :: my_node_id
    integer :: nb_tmp, nkp_tmp, nntot_tmp, np_tmp, ierr
    integer :: nkp, nkp2, nkp_loc, inn, nn, n, m
    integer :: nnl, nnm, nnn, ncount

    logical :: disentanglement
    logical :: nn_found
    logical :: on_root = .false.

    character(len=50) :: dummy

    disentanglement = (num_bands > num_wann)

    my_node_id = mpirank(comm)
    if (my_node_id == 0) then
      on_root = .true.
    end if
    allocate (map_kpts(num_kpts), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating map_kpts in overlap_read', comm)
      return
    end if
    nkp_loc = 1
    do nkp = 1, num_kpts
      if (dist_k(nkp) == my_node_id) then
        map_kpts(nkp) = nkp_loc
        nkp_loc = nkp_loc + 1
      end if
    end do

    if (timing_level > 0) call io_stopwatch_start('overlap: read', timer)

    !if (on_root) then - read on local bits on all nodes

    ! Read M_matrix_orig from file
    open (newunit=mmn_in, file=trim(seedname)//'.mmn', &
          form='formatted', status='old', action='read', err=101)

    if (print_output%iprint > 0) write (stdout, '(/a)', advance='no') ' Reading overlaps from '//trim(seedname)//'.mmn    : '

    ! Read the comment line
    read (mmn_in, '(a)', err=103, end=103) dummy
    if (print_output%iprint > 0) write (stdout, '(a)') trim(dummy)

    ! Read the number of bands, k-points and nearest neighbours
    read (mmn_in, *, err=103, end=103) nb_tmp, nkp_tmp, nntot_tmp

    ! Checks
    if (nb_tmp .ne. num_bands) then
      call set_error_file(error, trim(seedname)//'.mmn has not the right number of bands', comm)
      return
    end if
    if (nkp_tmp .ne. num_kpts) then
      call set_error_file(error, trim(seedname)//'.mmn has not the right number of k-points', comm)
      return
    end if
    if (nntot_tmp .ne. kmesh_info%nntot) then
      write (*, *) my_node_id, nntot_tmp, kmesh_info%nntot
      call set_error_file(error, trim(seedname)//'.mmn has not the right number of nearest neighbours', comm)
      return
    end if

    ! Read the overlaps
    num_mmn = num_kpts*kmesh_info%nntot
    allocate (mmn_tmp(num_bands, num_bands), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating mmn_tmp in overlap_read', comm)
      return
    end if
    do ncount = 1, num_mmn
      read (mmn_in, *, err=103, end=103) nkp, nkp2, nnl, nnm, nnn
      do n = 1, num_bands
        do m = 1, num_bands
          read (mmn_in, *, err=103, end=103) m_real, m_imag
          mmn_tmp(m, n) = cmplx(m_real, m_imag, kind=dp)
        end do
      end do
      if (dist_k(nkp) == my_node_id) then
        nn = 0
        nn_found = .false.
        do inn = 1, kmesh_info%nntot
          if ((nkp2 .eq. kmesh_info%nnlist(nkp, inn)) .and. &
              (nnl .eq. kmesh_info%nncell(1, nkp, inn)) .and. &
              (nnm .eq. kmesh_info%nncell(2, nkp, inn)) .and. &
              (nnn .eq. kmesh_info%nncell(3, nkp, inn))) then
            if (.not. nn_found) then
              nn_found = .true.
              nn = inn
            else
              call set_error_file(error, 'Error reading '//trim(seedname)// &
                                  '.mmn. More than one matching nearest neighbour found', comm)
              return
            end if
          end if
        end do
        if (nn .eq. 0) then
          if (on_root) write (stdout, '(/a,i8,2i5,i4,2x,3i3)') &
            ' Error reading '//trim(seedname)//'.mmn:', ncount, nkp, nkp2, nn, nnl, nnm, nnn
          call set_error_file(error, 'Neighbour not found', comm)
          return
        end if
        m_matrix_local(:, :, nn, map_kpts(nkp)) = mmn_tmp(:, :)
      end if
    end do
    deallocate (mmn_tmp, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating mmn_tmp in overlap_read', comm)
      return
    end if
    close (mmn_in)

    !if (disentanglement) then
    !  w = num_bands*num_bands*kmesh_info%nntot
    !  call comms_scatterv(m_matrix_orig_local, w*counts(my_node_id), m_matrix_orig, w*counts, w*displs, error, comm)
    !  if (allocated(error)) return
    !else
    !  w = num_wann*num_wann*kmesh_info%nntot
    !  call comms_scatterv(m_matrix_local, w*counts(my_node_id), m_matrix, w*counts, w*displs, error, comm)
    !  if (allocated(error)) return
    !endif

    if (.not. use_bloch_phases) then
      !if (on_root) then read on all nodes

      ! Read A_matrix from file wannier.amn
      open (newunit=amn_in, file=trim(seedname)//'.amn', form='formatted', status='old', err=102)

      if (print_output%iprint > 0) write (stdout, '(/a)', advance='no') ' Reading projections from '//trim(seedname)//'.amn : '

      ! Read the comment line
      read (amn_in, '(a)', err=104, end=104) dummy
      if (print_output%iprint > 0) write (stdout, '(a)') trim(dummy)

      ! Read the number of bands, k-points and projections
      read (amn_in, *, err=104, end=104) nb_tmp, nkp_tmp, np_tmp

      ! Checks
      if (nb_tmp .ne. num_bands) then
        call set_error_file(error, trim(seedname)//'.amn has not the right number of bands', comm)
        return
      end if
      if (nkp_tmp .ne. num_kpts) then
        call set_error_file(error, trim(seedname)//'.amn has not the right number of k-points', comm)
        return
      end if
      if (np_tmp .ne. num_proj) then
        call set_error_file(error, trim(seedname)//'.amn has not the right number of projections', comm)
        return
      end if

      if (num_proj > num_wann .and. .not. select_projection%lselproj) then
        call set_error_file(error, trim(seedname)//'.amn has too many projections to be used without selecting a subset', comm)
        return
      end if

      if (.not. allocated(select_projection%proj2wann_map)) then
        call set_error_fatal(error, 'select_projection%proj2wann_map not allocated in overlap_read call', comm)
        return
      end if

      ! Read the projections
      num_amn = num_bands*num_proj*num_kpts
      do ncount = 1, num_amn
        read (amn_in, *, err=104, end=104) m, n, nkp, a_real, a_imag
        if (select_projection%proj2wann_map(n) < 0) cycle
        au_matrix(m, select_projection%proj2wann_map(n), nkp) = cmplx(a_real, a_imag, kind=dp)
      end do
      close (amn_in)
      !endif

      !call comms_bcast(au_matrix(1, 1, 1), num_bands*num_wann*num_kpts, error, comm)
      !if (allocated(error)) return

    else
      au_matrix = cmplx_0
      do n = 1, num_kpts
        do m = 1, num_wann
          au_matrix(m, m, n) = cmplx_1
        end do
      end do

    end if

    ! If post-processing a Car-Parinello calculation (gamma only)
    ! then rotate M and A to the basis of Kohn-Sham eigenstates
    if (cp_pp) call overlap_rotate(au_matrix, m_matrix_local, kmesh_info%nntot, num_bands, &
                                   timing_level, timer, error, comm)
    if (allocated(error)) return

    deallocate (map_kpts, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating map_kpts in overlap_read', comm)
      return
    end if
    if (timing_level > 0) call io_stopwatch_stop('overlap: read', timer)

    return

101 call set_error_file(error, 'Error: Problem opening input file '//trim(seedname)//'.mmn', comm)
    return
102 call set_error_file(error, 'Error: Problem opening input file '//trim(seedname)//'.amn', comm)
    return
103 call set_error_file(error, 'Error: Problem reading input file '//trim(seedname)//'.mmn', comm)
    return
104 call set_error_file(error, 'Error: Problem reading input file '//trim(seedname)//'.amn', comm)
    return
  end subroutine overlap_read