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
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