sc_pull_rows_to_arr Subroutine

private subroutine sc_pull_rows_to_arr(self, arr)

A routine to collect all the row level data and store in passed array Gather the row blocks up for this cell to fill an array DD>FOR NOW USE ALL_REDUCE AS EASIER, BUT SHOULD BE ABLE

Type Bound

supercell_type

Arguments

Type IntentOptional Attributes Name
class(supercell_type), intent(in) :: self
complex, intent(out), dimension(:,:) :: arr

Contents

Source Code


Source Code

  subroutine sc_pull_rows_to_arr(self,arr)
    use mp, only: sum_allreduce_sub
    use array_utils, only: zero_array
    implicit none
    class(supercell_type), intent(in) :: self
    complex, dimension(:,:), intent(out) :: arr !Note: Dimensions should be self%ncol, self%nrow
    integer :: ic, rl,ru, cl,cu, irb

    ! Zero out arr |--> Not needed if gathering
    ! This may look like it is only needed for the sum_allreduce_sub branch below,
    ! however without this line we would end up not setting arr in cases where we
    ! think of this supercell as empty. This is usually fine, but for the ky=kx=0
    ! mode all processors consider the supercell to be empty, but we still need to
    ! initialise this array in some cases (e.g. when dumping to file). We could
    ! attempt to only do this zeroing in this special case to save some time, but
    ! we don't expect to be calling this routine much so opt for simpler approach.
    call zero_array(arr)

    !Now see if we want to exit
    if (self%is_empty) return
    if (.not.self%is_local) return

    !Place local piece in arr
    !$OMP PARALLEL DO DEFAULT(none) &
    !$OMP PRIVATE(ic, irb, rl, ru, cl, cu) &
    !$OMP SHARED(self, arr) &
    !$OMP SCHEDULE(static)
    do ic = 1, self%ncell
       if (self%cells(ic)%is_empty) cycle
       do irb = 1, self%cells(ic)%nrb
          rl=self%cells(ic)%rb(irb)%row_llim
          ru=self%cells(ic)%rb(irb)%row_ulim
          cl=self%cells(ic)%rb(irb)%col_llim
          cu=self%cells(ic)%rb(irb)%col_ulim
          arr(cl:cu,rl:ru)=self%cells(ic)%rb(irb)%data
       end do
    end do
    !$OMP END PARALLEL DO

    !If we're now all local then also need comms
    if (.not. self%is_all_local) then
       !Now use MPI to get the rest of the data from other procs
       !<DD>FOR NOW USE ALL_REDUCE AS EASIER, BUT SHOULD BE ABLE
       !TO DO THIS WITH ALL_GATHERV WHICH SHOULD BE FASTER
       ! We only actually need the result on the head of the supercell
       ! as this is the only process which operates on the result.
       ! We could therefore replace allreduce with reduce.
       if (self%sc_sub_pd%nproc > 0) call sum_allreduce_sub(arr, self%sc_sub_pd%id)
    end if

  end subroutine sc_pull_rows_to_arr