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
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(print_output_type), | intent(in) | :: | print_output | |||
| real(kind=dp), | intent(in) | :: | recip_lattice(3,3) | |||
| integer, | intent(inout) | :: | lmn(:,:) | |||
| type(timer_list_type), | intent(inout) | :: | timer |
subroutine kmesh_supercell_sort(print_output, recip_lattice, lmn, timer) !================================================ !! 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_start, io_stopwatch_stop use w90_types, only: print_output_type, timer_list_type implicit none type(print_output_type), intent(in) :: print_output integer, intent(inout) :: lmn(:, :) real(kind=dp), intent(in) :: recip_lattice(3, 3) type(timer_list_type), intent(inout) :: timer integer :: counter, l, m, n, loop !! Order in which to search the cells (ordered in dist from origin) 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 (print_output%timing_level > 1) call io_stopwatch_start('kmesh: supercell_sort', timer) 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, nsupcell) 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 (print_output%timing_level > 1) call io_stopwatch_stop('kmesh: supercell_sort', timer) end subroutine kmesh_supercell_sort