plot_svd_omega_i Subroutine

private subroutine plot_svd_omega_i(num_wann, num_kpts, kmesh_info, m_matrix, print_output, timer, dist_k, error, comm, stdout)

Uses

  • proc~~plot_svd_omega_i~~UsesGraph proc~plot_svd_omega_i plot_svd_omega_i module~w90_comms w90_comms proc~plot_svd_omega_i->module~w90_comms module~w90_constants w90_constants proc~plot_svd_omega_i->module~w90_constants module~w90_error w90_error proc~plot_svd_omega_i->module~w90_error module~w90_io w90_io proc~plot_svd_omega_i->module~w90_io module~w90_types w90_types proc~plot_svd_omega_i->module~w90_types 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 module~w90_io->module~w90_constants module~w90_types->module~w90_constants

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: num_wann
integer, intent(in) :: num_kpts
type(kmesh_info_type), intent(in) :: kmesh_info
complex(kind=dp), intent(in) :: m_matrix(:,:,:,:)
type(print_output_type), intent(in) :: print_output
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
integer, intent(in) :: stdout

Calls

proc~~plot_svd_omega_i~~CallsGraph proc~plot_svd_omega_i plot_svd_omega_i interface~comms_allreduce comms_allreduce proc~plot_svd_omega_i->interface~comms_allreduce proc~io_stopwatch_start io_stopwatch_start proc~plot_svd_omega_i->proc~io_stopwatch_start proc~io_stopwatch_stop io_stopwatch_stop proc~plot_svd_omega_i->proc~io_stopwatch_stop proc~mpirank mpirank proc~plot_svd_omega_i->proc~mpirank proc~set_error_alloc set_error_alloc proc~plot_svd_omega_i->proc~set_error_alloc proc~set_error_dealloc set_error_dealloc proc~plot_svd_omega_i->proc~set_error_dealloc proc~set_error_fatal set_error_fatal proc~plot_svd_omega_i->proc~set_error_fatal zgesvd zgesvd proc~plot_svd_omega_i->zgesvd proc~comms_allreduce_cmplx comms_allreduce_cmplx interface~comms_allreduce->proc~comms_allreduce_cmplx proc~comms_allreduce_real comms_allreduce_real interface~comms_allreduce->proc~comms_allreduce_real 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~comms_allreduce_cmplx->proc~comms_sync_error proc~comms_no_sync_allreduce_cmplx comms_no_sync_allreduce_cmplx proc~comms_allreduce_cmplx->proc~comms_no_sync_allreduce_cmplx proc~comms_allreduce_real->proc~comms_sync_error proc~comms_no_sync_allreduce_real comms_no_sync_allreduce_real proc~comms_allreduce_real->proc~comms_no_sync_allreduce_real

Called by

proc~~plot_svd_omega_i~~CalledByGraph proc~plot_svd_omega_i plot_svd_omega_i proc~plot_main plot_main proc~plot_main->proc~plot_svd_omega_i proc~w90_plot w90_plot proc~w90_plot->proc~plot_main program~wannier wannier program~wannier->proc~w90_plot

Source Code

  subroutine plot_svd_omega_i(num_wann, num_kpts, kmesh_info, m_matrix, print_output, timer, &
                              dist_k, error, comm, stdout)
    !================================================!

    use w90_comms, only: w90_comm_type, mpirank, comms_allreduce
    use w90_constants, only: dp, cmplx_0
    use w90_error, only: w90_error_type, set_error_alloc, set_error_dealloc, set_error_fatal
    use w90_io, only: io_stopwatch_start, io_stopwatch_stop
    use w90_types, only: kmesh_info_type, print_output_type, timer_list_type

    implicit none

    ! arguments
    complex(kind=dp), intent(in) :: m_matrix(:, :, :, :)
    integer, intent(in) :: dist_k(:)
    integer, intent(in) :: num_wann, num_kpts
    integer, intent(in) :: stdout
    type(kmesh_info_type), intent(in) :: kmesh_info
    type(print_output_type), intent(in) :: print_output
    type(timer_list_type), intent(inout) :: timer
    type(w90_comm_type), intent(in) :: comm
    type(w90_error_type), allocatable, intent(out) :: error

    ! local variables
    complex(kind=dp), allocatable :: cv1(:, :), cv2(:, :)
    complex(kind=dp), allocatable :: cw1(:), cw2(:)
    complex(kind=dp), allocatable :: cpad1(:)
    real(kind=dp), allocatable :: singvd(:)

    integer :: ierr, info, nkrank
    integer :: nkp, nn, nb, na, ind
    real(kind=dp) :: omt1, omt2, omt3

    nkrank = count(dist_k == mpirank(comm)) ! number k this rank, for dimensioning

    if (print_output%timing_level > 1 .and. print_output%iprint > 0) then
      call io_stopwatch_start('wann: svd_omega_i', timer)
    end if

    allocate (cw1(10*num_wann), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating cw1 in plot_svd_omega_i', comm)
      return
    end if
    allocate (cw2(10*num_wann), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating cw2 in plot_svd_omega_i', comm)
      return
    end if
    allocate (cv1(num_wann, num_wann), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating cv1 in plot_svd_omega_i', comm)
      return
    end if
    allocate (cv2(num_wann, num_wann), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating cv2 in plot_svd_omega_i', comm)
      return
    end if
    allocate (singvd(num_wann), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating singvd in plot_svd_omega_i', comm)
      return
    end if
    allocate (cpad1(num_wann*num_wann), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating cpad1 in plot_svd_omega_i', comm)
      return
    end if

    cw1 = cmplx_0; cw2 = cmplx_0; cv1 = cmplx_0; cv2 = cmplx_0; cpad1 = cmplx_0
    singvd = 0.0_dp

    ! singular value decomposition
    omt1 = 0.0_dp; omt2 = 0.0_dp; omt3 = 0.0_dp
    do nkp = 1, nkrank
      do nn = 1, kmesh_info%nntot
        ind = 1
        do nb = 1, num_wann
          do na = 1, num_wann
            cpad1(ind) = m_matrix(na, nb, nn, nkp)
            ind = ind + 1
          end do
        end do
        call zgesvd('A', 'A', num_wann, num_wann, cpad1, num_wann, singvd, cv1, &
                    num_wann, cv2, num_wann, cw1, 10*num_wann, cw2, info)
        if (info .ne. 0) then
          call set_error_fatal(error, 'ERROR: Singular value decomp. zgesvd failed', comm)
          return
        end if

        do nb = 1, num_wann
          omt1 = omt1 + kmesh_info%wb(nn)*(1.0_dp - singvd(nb)**2)
          omt2 = omt2 - kmesh_info%wb(nn)*(2.0_dp*log(singvd(nb)))
          omt3 = omt3 + kmesh_info%wb(nn)*(acos(singvd(nb))**2)
        end do
      end do
    end do
    call comms_allreduce(omt1, 1, 'SUM', error, comm)
    call comms_allreduce(omt2, 1, 'SUM', error, comm)
    call comms_allreduce(omt3, 1, 'SUM', error, comm)
    omt1 = omt1/real(num_kpts, dp)
    omt2 = omt2/real(num_kpts, dp)
    omt3 = omt3/real(num_kpts, dp)
    if (print_output%iprint > 0) then
      write (stdout, *) ' '
      write (stdout, '(2x,a,f15.9,1x,a)') 'Omega Invariant:   1-s^2 = ', &
        omt1*print_output%lenconfac**2, '('//trim(print_output%length_unit)//'^2)'
      write (stdout, '(2x,a,f15.9,1x,a)') '                 -2log s = ', &
        omt2*print_output%lenconfac**2, '('//trim(print_output%length_unit)//'^2)'
      write (stdout, '(2x,a,f15.9,1x,a)') '                  acos^2 = ', &
        omt3*print_output%lenconfac**2, '('//trim(print_output%length_unit)//'^2)'
    end if

    deallocate (cpad1, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating cpad1 in plot_svd_omega_i', comm)
      return
    end if
    deallocate (singvd, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating singvd in plot_svd_omega_i', comm)
      return
    end if
    deallocate (cv2, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating cv2 in plot_svd_omega_i', comm)
      return
    end if
    deallocate (cv1, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating cv1 in plot_svd_omega_i', comm)
      return
    end if
    deallocate (cw2, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating cw2 in plot_svd_omega_i', comm)
      return
    end if
    deallocate (cw1, stat=ierr)
    if (ierr /= 0) then
      call set_error_dealloc(error, 'Error in deallocating cw1 in plot_svd_omega_i', comm)
      return
    end if

    if (print_output%timing_level > 1 .and. print_output%iprint > 0) then
      call io_stopwatch_stop('wann: svd_omega_i', timer)
    end if
  end subroutine plot_svd_omega_i