w90_wannier90_readwrite_read_projections Subroutine

private subroutine w90_wannier90_readwrite_read_projections(settings, proj, proj_input, use_bloch_phases, lhasproj, guiding_centres, select_proj, num_proj, atom_data, recip_lattice, num_wann, gamma_only, spinors, bohr, stdout, error, comm)

Uses

  • proc~~w90_wannier90_readwrite_read_projections~~UsesGraph proc~w90_wannier90_readwrite_read_projections w90_wannier90_readwrite_read_projections module~w90_error w90_error proc~w90_wannier90_readwrite_read_projections->module~w90_error 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_comms->module~w90_error_base module~w90_constants w90_constants module~w90_comms->module~w90_constants

Arguments

Type IntentOptional Attributes Name
type(settings_type), intent(inout) :: settings
type(proj_type), intent(inout), allocatable :: proj(:)
type(proj_type), intent(inout), allocatable :: proj_input(:)
logical, intent(in) :: use_bloch_phases
logical, intent(out) :: lhasproj
logical, intent(in) :: guiding_centres
type(select_projection_type), intent(inout) :: select_proj
integer, intent(inout) :: num_proj
type(atom_data_type), intent(in) :: atom_data
real(kind=dp), intent(in) :: recip_lattice(3,3)
integer, intent(in) :: num_wann
logical, intent(in) :: gamma_only
logical, intent(in) :: spinors
real(kind=dp), intent(in) :: bohr
integer, intent(in) :: stdout
type(w90_error_type), intent(out), allocatable :: error
type(w90_comm_type), intent(in) :: comm

Calls

proc~~w90_wannier90_readwrite_read_projections~~CallsGraph proc~w90_wannier90_readwrite_read_projections w90_wannier90_readwrite_read_projections proc~set_error_alloc set_error_alloc proc~w90_wannier90_readwrite_read_projections->proc~set_error_alloc proc~set_error_dealloc set_error_dealloc proc~w90_wannier90_readwrite_read_projections->proc~set_error_dealloc proc~set_error_input set_error_input proc~w90_wannier90_readwrite_read_projections->proc~set_error_input proc~w90_readwrite_get_block_length w90_readwrite_get_block_length proc~w90_wannier90_readwrite_read_projections->proc~w90_readwrite_get_block_length proc~w90_readwrite_get_keyword w90_readwrite_get_keyword proc~w90_wannier90_readwrite_read_projections->proc~w90_readwrite_get_keyword proc~w90_readwrite_get_projections w90_readwrite_get_projections proc~w90_wannier90_readwrite_read_projections->proc~w90_readwrite_get_projections proc~w90_readwrite_get_range_vector w90_readwrite_get_range_vector proc~w90_wannier90_readwrite_read_projections->proc~w90_readwrite_get_range_vector 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 proc~set_error_input->proc~comms_sync_error proc~set_error_input->proc~set_base_error proc~w90_readwrite_get_block_length->proc~set_error_input proc~w90_readwrite_get_keyword->proc~set_error_input proc~set_error_fatal set_error_fatal proc~w90_readwrite_get_keyword->proc~set_error_fatal proc~w90_readwrite_get_projections->proc~set_error_alloc proc~w90_readwrite_get_projections->proc~set_error_input proc~utility_cart_to_frac utility_cart_to_frac proc~w90_readwrite_get_projections->proc~utility_cart_to_frac proc~utility_string_to_coord utility_string_to_coord proc~w90_readwrite_get_projections->proc~utility_string_to_coord proc~utility_strip utility_strip proc~w90_readwrite_get_projections->proc~utility_strip proc~w90_readwrite_get_range_vector->proc~set_error_input proc~w90_readwrite_get_keyword_vector w90_readwrite_get_keyword_vector proc~w90_readwrite_get_range_vector->proc~w90_readwrite_get_keyword_vector proc~w90_readwrite_get_vector_length w90_readwrite_get_vector_length proc~w90_readwrite_get_range_vector->proc~w90_readwrite_get_vector_length proc~set_error_fatal->proc~comms_sync_error proc~set_error_fatal->proc~set_base_error proc~utility_string_to_coord->proc~set_error_input proc~w90_readwrite_get_keyword_vector->proc~set_error_input proc~w90_readwrite_get_keyword_vector->proc~set_error_fatal proc~w90_readwrite_get_vector_length->proc~set_error_input proc~w90_readwrite_get_vector_length->proc~set_error_fatal

Called by

proc~~w90_wannier90_readwrite_read_projections~~CalledByGraph proc~w90_wannier90_readwrite_read_projections w90_wannier90_readwrite_read_projections proc~w90_wannier90_readwrite_read_special w90_wannier90_readwrite_read_special proc~w90_wannier90_readwrite_read_special->proc~w90_wannier90_readwrite_read_projections proc~input_reader_special input_reader_special proc~input_reader_special->proc~w90_wannier90_readwrite_read_special proc~w90_input_setopt w90_input_setopt proc~w90_input_setopt->proc~w90_wannier90_readwrite_read_special proc~w90_input_setopt_f w90_input_setopt_f proc~w90_input_setopt_f->proc~w90_input_setopt program~wannier wannier program~wannier->proc~input_reader_special

Source Code

  subroutine w90_wannier90_readwrite_read_projections(settings, proj, proj_input, &
                                                      use_bloch_phases, lhasproj, &
                                                      guiding_centres, select_proj, num_proj, &
                                                      atom_data, recip_lattice, num_wann, &
                                                      gamma_only, spinors, bohr, stdout, error, &
                                                      comm)
    !================================================!
    ! Obtain projector definitions
    use w90_error, only: w90_error_type

    implicit none

    ! arguments
    integer, intent(in) :: num_wann
    integer, intent(inout) :: num_proj
    integer, intent(in) :: stdout
    logical, intent(in) :: gamma_only
    logical, intent(in) :: spinors
    logical, intent(in) :: use_bloch_phases, guiding_centres
    logical, intent(out) :: lhasproj
    real(kind=dp), intent(in) :: bohr
    real(kind=dp), intent(in) :: recip_lattice(3, 3)
    type(atom_data_type), intent(in) :: atom_data
    type(proj_type), allocatable, intent(inout) :: proj(:), proj_input(:)
    type(select_projection_type), intent(inout) :: select_proj
    type(settings_type), intent(inout) :: settings
    type(w90_comm_type), intent(in) :: comm
    type(w90_error_type), allocatable, intent(out) :: error

    ! local variables
    integer :: i, j, i_temp, loop, ierr
    logical :: found
    ! projections selection
    integer :: num_select_projections
    integer, allocatable :: select_projections(:)
    integer :: imap

    lhasproj = .false.

    ! Projections
    call w90_readwrite_get_keyword(settings, 'auto_projections', found, error, comm, &
                                   l_value=select_proj%auto_projections)
    if (allocated(error)) return

    call w90_readwrite_get_block_length(settings, 'projections', found, i_temp, error, comm)
    if (allocated(error)) return

    if (found) then
      if (select_proj%auto_projections) then
        call set_error_input(error, 'Error: Cannot specify both auto_projections and projections block', comm)
        return
      end if
      lhasproj = .true.
      call w90_readwrite_get_projections(settings, num_proj, atom_data, num_wann, proj_input, &
                                         recip_lattice, .true., spinors, bohr, stdout, error, comm)
      if (allocated(error)) return
      ! num_proj is assigned in get_projections() call
    else
      if (guiding_centres .and. .not. (gamma_only .and. use_bloch_phases)) then
        call set_error_input(error, 'w90_wannier90_readwrite_read: Guiding centres requested, but no projection block found', comm)
        return
      end if
      lhasproj = .false.
      num_proj = num_wann
    end if

    ! attempt to read projections from library interface
    if (allocated(settings%entries)) then
      if (found) then
        call set_error_input(error, 'w90_wannier90_readwrite_read: attempting to read .win file with unspent lib options', comm)
        return
      end if

      if (atom_data%num_species > 0) then
        ! only read projections if atom positions are known
        ! Count pass first: num_proj may exceed num_wann when there are more initial
        ! projections than target Wannier functions (valid for disentanglement).
        ! Without this, input_proj is allocated at size num_wann and overflows.
        call w90_readwrite_get_projections(settings, num_proj, atom_data, num_wann, proj_input, &
                                           recip_lattice, .true., spinors, bohr, stdout, error, comm)
        if (allocated(error)) return
        call w90_readwrite_get_projections(settings, num_proj, atom_data, num_wann, proj_input, &
                                           recip_lattice, .false., spinors, bohr, stdout, error, comm)
        if (allocated(error)) return
        lhasproj = .true.
      end if
    end if

    num_select_projections = num_proj !num proj is the size of proj_input
    call w90_readwrite_get_range_vector(settings, 'select_projections', found, num_select_projections, &
                                        .true., error, comm)
    if (allocated(error)) return

    if (found) then
      if (num_select_projections < 1) then
        call set_error_input(error, 'Error: problem reading select_projections', comm)
        return
      end if
      if (allocated(select_projections)) then
        deallocate (select_projections, stat=ierr)
        if (ierr /= 0) then
          call set_error_dealloc(error, 'Error deallocating select_projections &
          & in w90_wannier90_readwrite_read_projections', comm)
          return
        end if
      end if
      allocate (select_projections(num_select_projections), stat=ierr)
      if (ierr /= 0) then
        call set_error_alloc(error, 'Error allocating select_projections in w90_wannier90_readwrite_read_projections', comm)
        return
      end if
      call w90_readwrite_get_range_vector(settings, 'select_projections', found, num_select_projections, &
                                          .false., error, comm, select_projections)
      if (allocated(error)) return

      if (any(select_projections < 1)) then
        call set_error_input(error, 'Error: select_projections must contain positive numbers', comm)
        return
      end if
      if (num_select_projections < num_wann) then
        call set_error_input(error, 'Error: too few projections selected', comm)
        return
      end if
      if (num_select_projections > num_wann) then
        call set_error_input(error, 'Error: too many projections selected', comm)
        return
      end if
      if (.not. lhasproj) then
        call set_error_input(error, 'Error: select_projections cannot be used without defining the projections', comm)
        return
      end if
      if (maxval(select_projections(:)) > num_proj) then
        call set_error_input(error, 'Error: select_projections contains a number greater than num_proj', comm)
        return
      end if
      select_proj%lselproj = .true.
    end if ! found 'select_projections'

    if (allocated(select_proj%proj2wann_map)) then
      deallocate (select_proj%proj2wann_map, stat=ierr)
      if (ierr /= 0) then
        call set_error_dealloc(error, 'Error deallocating proj2wann_map in w90_wannier90_readwrite_read_projections', comm)
        return
      end if
    end if
    allocate (select_proj%proj2wann_map(num_proj), stat=ierr)
    if (ierr /= 0) then
      call set_error_alloc(error, 'Error allocating proj2wann_map in w90_wannier90_readwrite_read_projections', comm)
      return
    end if
    select_proj%proj2wann_map = -1

    if (select_proj%lselproj) then
      do i = 1, num_proj
        do j = 1, num_select_projections
          if (select_projections(j) == i) select_proj%proj2wann_map(i) = j
        end do
      end do
    else
      do i = 1, num_wann
        select_proj%proj2wann_map(i) = i
      end do
    end if

    if (lhasproj) then
      call w90_readwrite_get_projections(settings, num_proj, atom_data, num_wann, proj_input, &
                                         recip_lattice, .false., spinors, bohr, stdout, error, comm)
      if (allocated(error)) return

      allocate (proj(num_proj), stat=ierr)
      if (ierr /= 0) then
        call set_error_alloc(error, 'Error allocating proj in w90_wannier90_readwrite_read_projections', comm)
        return
      end if
      do loop = 1, num_proj
        imap = select_proj%proj2wann_map(loop)
        if (imap < 0) cycle
        if (imap > num_proj) then
          write (*, *) "logic error, imapping"
          stop
        end if
        proj(imap) = proj_input(loop)
      end do
    end if !lhasproj

  end subroutine w90_wannier90_readwrite_read_projections