kmesh_supercell_sort Subroutine

private subroutine kmesh_supercell_sort(print_output, recip_lattice, lmn, timer)

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_types w90_types proc~kmesh_supercell_sort->module~w90_types module~w90_constants w90_constants module~w90_io->module~w90_constants module~w90_types->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

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

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 proc~io_stopwatch_start io_stopwatch_start proc~kmesh_supercell_sort->proc~io_stopwatch_start proc~io_stopwatch_stop io_stopwatch_stop proc~kmesh_supercell_sort->proc~io_stopwatch_stop

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~w90_create_kmesh w90_create_kmesh proc~w90_create_kmesh->proc~kmesh_get program~postw90 postw90 program~postw90->proc~kmesh_get proc~w90_get_gkpb~2 w90_get_gkpb proc~w90_get_gkpb~2->proc~w90_create_kmesh proc~w90_get_nnkp~2 w90_get_nnkp proc~w90_get_nnkp~2->proc~w90_create_kmesh proc~w90_get_nn~2 w90_get_nn proc~w90_get_nn~2->proc~w90_create_kmesh proc~write_kmesh write_kmesh proc~write_kmesh->proc~w90_create_kmesh proc~w90_get_gkpb w90_get_gkpb proc~w90_get_gkpb->proc~w90_get_gkpb~2 proc~w90_get_nn w90_get_nn proc~w90_get_nn->proc~w90_get_nn~2 proc~w90_get_nnkp w90_get_nnkp proc~w90_get_nnkp->proc~w90_get_nnkp~2 program~wannier wannier program~wannier->proc~w90_get_nn~2 program~wannier->proc~write_kmesh

Source Code

  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