master_sort_and_group Subroutine

private subroutine master_sort_and_group(Array, Array_groups, subgroup_info, tran_group_threshold, print_output, wannier_centres_translated, coord, stdout, timer, error, comm)

Uses

  • proc~~master_sort_and_group~~UsesGraph proc~master_sort_and_group master_sort_and_group module~w90_constants w90_constants proc~master_sort_and_group->module~w90_constants module~w90_error w90_error proc~master_sort_and_group->module~w90_error module~w90_io w90_io proc~master_sort_and_group->module~w90_io module~w90_types w90_types proc~master_sort_and_group->module~w90_types module~w90_comms w90_comms module~w90_error->module~w90_comms module~w90_error_base w90_error_base module~w90_error->module~w90_error_base module~w90_io->module~w90_constants module~w90_types->module~w90_constants module~w90_comms->module~w90_constants module~w90_comms->module~w90_error_base

Arguments

Type IntentOptional Attributes Name
real(kind=dp), intent(inout) :: Array(:,:)
integer, intent(in) :: Array_groups(:)
integer, intent(out), allocatable :: subgroup_info(:,:)
real(kind=dp), intent(in) :: tran_group_threshold
type(print_output_type), intent(in) :: print_output
real(kind=dp), intent(in) :: wannier_centres_translated(:,:)
integer, intent(in) :: coord(3)
integer, intent(in) :: stdout
type(timer_list_type), intent(inout) :: timer
type(w90_error_type), intent(out), allocatable :: error
type(w90_comm_type), intent(in) :: comm

Calls

proc~~master_sort_and_group~~CallsGraph proc~master_sort_and_group master_sort_and_group proc~group group proc~master_sort_and_group->proc~group proc~io_stopwatch_start io_stopwatch_start proc~master_sort_and_group->proc~io_stopwatch_start proc~io_stopwatch_stop io_stopwatch_stop proc~master_sort_and_group->proc~io_stopwatch_stop proc~set_error_alloc set_error_alloc proc~master_sort_and_group->proc~set_error_alloc proc~set_error_dealloc set_error_dealloc proc~master_sort_and_group->proc~set_error_dealloc proc~sort sort proc~master_sort_and_group->proc~sort proc~group->proc~set_error_alloc proc~group->proc~set_error_dealloc 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

Called by

proc~~master_sort_and_group~~CalledByGraph proc~master_sort_and_group master_sort_and_group proc~tran_lcr_2c2_sort tran_lcr_2c2_sort proc~tran_lcr_2c2_sort->proc~master_sort_and_group proc~tran_main tran_main proc~tran_main->proc~tran_lcr_2c2_sort proc~w90_transport w90_transport proc~w90_transport->proc~tran_main program~wannier wannier program~wannier->proc~w90_transport

Source Code

  subroutine master_sort_and_group(Array, Array_groups, subgroup_info, tran_group_threshold, &
                                   print_output, wannier_centres_translated, coord, stdout, timer, &
                                   error, comm)
    !================================================!
    ! General sorting and grouping subroutine which takes Array,
    ! an ordered in conduction direction array of wannier function
    ! indexes and positions, and returns the ordered (and grouped)
    ! indexes and positions after considering the other two
    ! directions. Sub group info is also return for later checks.
    !================================================!

    use w90_constants, only: dp
    use w90_io, only: io_stopwatch_start, io_stopwatch_stop
    use w90_types, only: print_output_type, timer_list_type
    use w90_error, only: w90_error_type, set_error_alloc, set_error_dealloc

    implicit none

    ! arguments
    type(print_output_type), intent(in) :: print_output
    type(timer_list_type), intent(inout) :: timer
    type(w90_error_type), allocatable, intent(out) :: error
    type(w90_comm_type), intent(in) :: comm

    integer, intent(in) :: stdout !, Array_size => size(Array_groups) so not needed
    integer, intent(in) :: Array_groups(:), coord(3)
    integer, intent(out), allocatable :: subgroup_info(:, :)

    real(kind=dp), intent(inout) :: Array(:, :) !(2, Array_size)
    real(kind=dp), intent(in) :: tran_group_threshold, wannier_centres_translated(:, :)

    ! local variables
    integer :: i, j, k, Array_num_groups, increment, ierr, subgroup_increment, group_num_subgroups
    integer, allocatable :: group_subgroups(:)
    real(kind=dp), allocatable :: group_array(:, :), sorted_group_array(:, :)
    real(kind=dp), allocatable :: subgroup_array(:, :), sorted_subgroup_array(:, :)
    character(30) :: fmt_2

    if (print_output%timing_level > 2) call io_stopwatch_start('tran: lcr_2c2_sort: master_sort', timer)

    allocate (subgroup_info(size(Array_groups), maxval(Array_groups)), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error in allocating subgroup_info in master_sort_and_group', comm)
      return
    end if
    subgroup_info = 0

    !Number of groups inside the principal layer

    Array_num_groups = size(Array_groups)

    !Convenient variable which will be amended later. Used to appropriately extract the group array from the Array

    increment = 1

    !Loop over groups inside Array

    do j = 1, Array_num_groups
      allocate (group_array(2, Array_groups(j)), stat=ierr)
      if (ierr /= 0) then
        call set_error_alloc(error, 'Error in allocating group_array in master_sort_and_group', comm)
        return
      end if
      allocate (sorted_group_array(2, Array_groups(j)), stat=ierr)
      if (ierr /= 0) then
        call set_error_alloc(error, 'Error in allocating sorted_group_array in master_sort_and_group', comm)
        return
      end if

      !Extract the group from the Array

      group_array = Array(:, increment:increment + Array_groups(j) - 1)

      !Updating group_array to contain coord(2)

      do k = 1, Array_groups(j)
        group_array(2, k) = wannier_centres_translated(coord(2), int(group_array(1, k)))
      end do

      call sort(group_array, sorted_group_array)
      call group(sorted_group_array, group_subgroups, tran_group_threshold, error, comm)
      if (allocated(error)) return

      group_num_subgroups = size(group_subgroups)

      if (print_output%iprint .ge. 4) then

        !Printing subgroup breakdown

        write (fmt_2, '(i5)') group_num_subgroups
        fmt_2 = adjustl(fmt_2)
        fmt_2 = '(a7,i3,a1,i5,a2,'//trim(fmt_2)//'i4,a1)'
        write (stdout, fmt_2) ' Group ', j, ' ', group_num_subgroups, ' (', (group_subgroups(i), i=1, group_num_subgroups), ')'
      end if

      ! filling up subgroup_info

      do k = 1, group_num_subgroups
        subgroup_info(j, k) = group_subgroups(k)
      end do

      !Convenient variable which will be amended later. Used to appropriately extract the subgroup array from the group_array

      subgroup_increment = 1

      !Loop over subgroups inside group

      do k = 1, group_num_subgroups
        allocate (subgroup_array(2, group_subgroups(k)), stat=ierr)
        if (ierr /= 0) then
          call set_error_alloc(error, 'Error in allocating subgroup_array in master_sort_and_group', comm)
          return
        end if
        allocate (sorted_subgroup_array(2, group_subgroups(k)), stat=ierr)
        if (ierr /= 0) then
          call set_error_alloc(error, 'Error in allocating sorted_subgroup_array in master_sort_and_group', comm)
          return
        end if

        !Extract the subgroup from the group

        subgroup_array = sorted_group_array(:, subgroup_increment:subgroup_increment + group_subgroups(k) - 1)

        !Updating subgroup_array to contain coord(3)

        do i = 1, group_subgroups(k)
          subgroup_array(2, i) = wannier_centres_translated(coord(3), int(subgroup_array(1, i)))
        end do

        call sort(subgroup_array, sorted_subgroup_array)

        !Update sorted_group array with the sorted subgroup array

        sorted_group_array(:, subgroup_increment:subgroup_increment + group_subgroups(k) - 1) = sorted_subgroup_array

        !Update the subgroup_increment

        subgroup_increment = subgroup_increment + group_subgroups(k)
        deallocate (sorted_subgroup_array, stat=ierr)
        if (ierr /= 0) then
          call set_error_dealloc(error, 'Error deallocating sorted_subgroup_array in master_sort_and_group', comm)
          return
        end if
        deallocate (subgroup_array, stat=ierr)
        if (ierr /= 0) then
          call set_error_dealloc(error, 'Error deallocating subgroup_array in master_sort_and_group', comm)
          return
        end if
      end do

      !Update Array with the sorted group array

      Array(:, increment:increment + Array_groups(j) - 1) = sorted_group_array

      !Update the group increment

      increment = increment + Array_groups(j)
      deallocate (group_array, stat=ierr)
      if (ierr /= 0) then
        call set_error_dealloc(error, 'Error deallocating group_array in master_sort_and_group', comm)
        return
      end if
      deallocate (sorted_group_array, stat=ierr)
      if (ierr /= 0) then
        call set_error_dealloc(error, 'Error deallocating sorted_group_array in master_sort_and_group', comm)
        return
      end if
      deallocate (group_subgroups, stat=ierr)
      if (ierr /= 0) then
        call set_error_dealloc(error, 'Error deallocating group_subgroups in master_sort_and_group', comm)
        return
      end if
    end do

    if (print_output%timing_level > 2) call io_stopwatch_stop('tran: lcr_2c2_sort: master_sort', timer)

    return

  end subroutine master_sort_and_group