kmesh_supercell_sort Subroutine

private subroutine kmesh_supercell_sort()

Uses

  • proc~~kmesh_supercell_sort~~UsesGraph proc~kmesh_supercell_sort kmesh_supercell_sort module~w90_io w90_io proc~kmesh_supercell_sort->module~w90_io module~w90_constants w90_constants module~w90_io->module~w90_constants

We look for kpoint neighbours in a large supercell of reciprocal unit cells. Done sequentially this is very slow. Here we order the cells by the distance from the origin. Doing the search in this order gives a dramatic speed up

Arguments

None

Calls

proc~~kmesh_supercell_sort~~CallsGraph proc~kmesh_supercell_sort kmesh_supercell_sort proc~internal_maxloc internal_maxloc proc~kmesh_supercell_sort->proc~internal_maxloc

Called by

proc~~kmesh_supercell_sort~~CalledByGraph proc~kmesh_supercell_sort kmesh_supercell_sort proc~kmesh_get kmesh_get proc~kmesh_get->proc~kmesh_supercell_sort proc~wannier_run wannier_run proc~wannier_run->proc~kmesh_get program~postw90 postw90 program~postw90->proc~kmesh_get

Contents

Source Code


Source Code

  subroutine kmesh_supercell_sort
    !==================================================================
    !
    !! We look for kpoint neighbours in a large supercell of reciprocal
    !! unit cells. Done sequentially this is very slow.
    !! Here we order the cells by the distance from the origin.
    !! Doing the search in this order gives a dramatic speed up
    !
    !==================================================================
    use w90_io, only: io_stopwatch
    implicit none
    integer :: counter, l, m, n, loop

    integer :: lmn_cp(3, (2*nsupcell + 1)**3), indx(1)
    real(kind=dp) :: pos(3)
    real(kind=dp) :: dist((2*nsupcell + 1)**3)
    real(kind=dp) :: dist_cp((2*nsupcell + 1)**3)

    if (timing_level > 1) call io_stopwatch('kmesh: supercell_sort', 1)

    counter = 1
    lmn(:, counter) = 0
    dist(counter) = 0.0_dp
    do l = -nsupcell, nsupcell
      do m = -nsupcell, nsupcell
        do n = -nsupcell, nsupcell
          if (l == 0 .and. m == 0 .and. n == 0) cycle
          counter = counter + 1
          lmn(1, counter) = l; lmn(2, counter) = m; lmn(3, counter) = n
          pos = matmul(lmn(:, counter), recip_lattice)
          dist(counter) = sqrt(dot_product(pos, pos))
        end do
      end do
    end do

    do loop = (2*nsupcell + 1)**3, 1, -1
      indx = internal_maxloc(dist)
      dist_cp(loop) = dist(indx(1))
      lmn_cp(:, loop) = lmn(:, indx(1))
      dist(indx(1)) = -1.0_dp
    end do

    lmn = lmn_cp
    dist = dist_cp

    if (timing_level > 1) call io_stopwatch('kmesh: supercell_sort', 2)

  end subroutine kmesh_supercell_sort