LCOV - code coverage report
Current view: top level - hybrid - wavefproducts_inv.F90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 44 50 88.0 %
Date: 2024-05-02 04:21:52 Functions: 2 2 100.0 %

          Line data    Source code
       1             : module m_wavefproducts_inv
       2             :    USE m_types_hybdat
       3             :    use m_wavefproducts_noinv
       4             :    USE m_constants
       5             :    USE m_judft
       6             :    USE m_types
       7             :    USE m_types_hybinp
       8             :    USE m_util
       9             :    USE m_io_hybrid
      10             :    USE m_wrapper
      11             :    USE m_constants
      12             :    USE m_wavefproducts_aux
      13             : 
      14             : CONTAINS
      15          66 :    SUBROUTINE wavefproducts_inv(fi, ik, z_k, iq, jsp, bandoi, bandof, lapw, hybdat, mpdata, nococonv, stars, ikqpt, cmt_nk, cprod)
      16             :       IMPLICIT NONE
      17             :       type(t_fleurinput), intent(in):: fi
      18             :       TYPE(t_mpdata), intent(in)    :: mpdata
      19             :       type(t_nococonv), intent(in)  :: nococonv
      20             :       type(t_stars), intent(in)     :: stars
      21             :       type(t_mat), intent(in)       :: z_k  ! = z_k_p since ik < nkpt
      22             :       TYPE(t_lapw), INTENT(IN)      :: lapw
      23             :       TYPE(t_hybdat), INTENT(INOUT) :: hybdat
      24             :       type(t_mat), intent(inout)    :: cprod
      25             : 
      26             :       ! - scalars -
      27             :       INTEGER, INTENT(IN)      :: jsp, ik, iq, bandoi, bandof
      28             :       INTEGER, INTENT(INOUT)   :: ikqpt
      29             :       complex, intent(in)  :: cmt_nk(:,:,:)
      30             : 
      31             : 
      32             :       ! - local scalars -
      33             :       INTEGER                 ::    g_t(3), i, j
      34             :       REAL                    ::    kqpt(3), kqpthlp(3)
      35             : 
      36          66 :       type(t_mat) ::  z_kqpt_p
      37          66 :       complex, allocatable :: c_phase_kqpt(:), tmp(:,:)
      38             : 
      39          66 :       CALL timestart("wavefproducts_inv")
      40          66 :       ikqpt = -1
      41         264 :       kqpthlp = fi%kpts%bkf(:, ik) + fi%kpts%bkf(:, iq)
      42             :       ! kqpt can lie outside the first BZ, transfer it back
      43          66 :       kqpt = fi%kpts%to_first_bz(kqpthlp)
      44         264 :       g_t = nint(kqpt - kqpthlp)
      45             : 
      46             :       ! determine number of kqpt
      47          66 :       ikqpt = fi%kpts%get_nk(kqpt)
      48         198 :       allocate (c_phase_kqpt(hybdat%nbands(fi%kpts%bkp(ikqpt),jsp)))
      49          66 :       IF (.not. fi%kpts%is_kpt(kqpt)) call juDFT_error('wavefproducts_inv5: k-point not found')
      50             : 
      51             :       !$acc data copyin(hybdat, hybdat%nbasp)
      52             :          !$acc data copyin(cprod) create(cprod%data_c) copyout(cprod%data_r)
      53             :             !$acc kernels present(cprod, cprod%data_r)
      54     8548200 :             cprod%data_r(:,:) = 0.0
      55             :             !$acc end kernels
      56             :             call wavefproducts_IS_FFT(fi, ik, iq, g_t, jsp, bandoi, bandof, mpdata, hybdat, lapw, stars, nococonv, &
      57          66 :                                        ikqpt, z_k, z_kqpt_p, c_phase_kqpt, cprod)
      58             :          !$acc end data ! cprod
      59             : 
      60             :          
      61         264 :          allocate(tmp(hybdat%nbasp, cprod%matsize2))
      62             :          !$acc data copyout(tmp)
      63             :             !$acc kernels present(tmp)
      64     6143694 :             tmp = cmplx_0
      65             :             !$acc end kernels
      66             :             call wavefproducts_noinv_MT(fi, ik, iq, bandoi, bandof, nococonv, mpdata, hybdat, &
      67          66 :                                        jsp, ikqpt, z_kqpt_p, c_phase_kqpt, cmt_nk, tmp)
      68          66 :             call transform_to_realsph(fi, mpdata, tmp)
      69             :          !$acc end data
      70             :             
      71          66 :          call timestart("cpu cmplx2real copy")
      72          66 :          !$omp parallel do default(none) collapse(2) private(i,j) shared(cprod, hybdat, tmp)
      73             :          do i = 1,cprod%matsize2
      74             :             do j = 1,hybdat%nbasp
      75             :                cprod%data_r(j,i) = real(tmp(j,i))
      76             :             enddo 
      77             :          enddo
      78             :          !$omp end parallel do
      79          66 :          call timestop("cpu cmplx2real copy")
      80          66 :          deallocate(tmp)
      81             :       !$acc end data ! hybdat
      82             : 
      83          66 :       CALL timestop("wavefproducts_inv")
      84          66 :    END SUBROUTINE wavefproducts_inv
      85             : 
      86          66 :    subroutine transform_to_realsph(fi, mpdata, cprod)
      87             :       use m_constants
      88             :       implicit none 
      89             :       type(t_fleurinput), intent(in):: fi
      90             :       TYPE(t_mpdata), intent(in)    :: mpdata
      91             :       complex, intent(inout)        :: cprod(:,:)
      92             : 
      93             :       integer :: lm_0, lm, iatm, iatm2, itype, l, m, partner, ioffset, ishift
      94             : 
      95             :       !$acc data copyin(mpdata, mpdata%num_radbasfn)
      96          66 :          lm_0 = 0
      97         154 :          do iatm = 1,fi%atoms%nat 
      98          88 :             itype = fi%atoms%itype(iatm)
      99             : 
     100          88 :             iatm2 = fi%sym%invsatnr(iatm)
     101          88 :             IF(iatm2.EQ.0) iatm2 = iatm
     102             : 
     103         528 :             ioffset = sum((/((2*l + 1)*mpdata%num_radbasfn(l, itype), l=0, fi%hybinp%lcutm1(itype))/))
     104             :             
     105         154 :             IF(iatm2.LT.iatm) THEN ! iatm is the second of two atoms that are mapped onto each other by inversion symmetry
     106           0 :                DO l = 0, fi%hybinp%lcutm1(itype)
     107           0 :                   lm_0 = lm_0 + mpdata%num_radbasfn(l, itype)*(2*l + 1) ! go to the lm start index of the next l-quantum number
     108             :                END DO
     109             :                CYCLE
     110          88 :             ELSE IF (iatm2.GT.iatm) THEN
     111             :                ! In this case we already make everything correct in wavefproducts_noinv_MT
     112           0 :                DO l = 0, fi%hybinp%lcutm1(itype)
     113           0 :                   lm = lm_0
     114           0 :                   DO m = -l, l
     115             : 
     116             :                      ishift = -2 * m * mpdata%num_radbasfn(l, itype)
     117             : !                     lm1 = lm + (iatm - fi%atoms%firstAtom(itype))*ioffset
     118             : !                     lm2 = lm + (iatm2 - fi%atoms%firstAtom(itype))*ioffset + ishift
     119             : 
     120             : !                     DO i = 1, mpdata%num_radbasfn(l, itype)
     121             : !                        cprod(i + lm1, (j-bandoi+1) + (k-1)*psize) = REAL(cprod(i + lm1, (j-bandoi+1) + (k-1)*psize))
     122             : !                     END DO
     123             : 
     124             :                      lm = lm + mpdata%num_radbasfn(l, itype)
     125             :                   END DO
     126           0 :                   lm_0 = lm_0 + mpdata%num_radbasfn(l, itype)*(2*l + 1) ! go to the lm start index of the next l-quantum number
     127             :                END DO
     128             :             ELSE
     129             :                ! The default(shared) in the OMP part of the following loop is needed to avoid compilation issues on gfortran 7.5.
     130         528 :                DO l = 0, fi%hybinp%lcutm1(itype)
     131        2640 :                   DO m = -l, l
     132        2200 :                      lm = lm_0 + (m + l)*mpdata%num_radbasfn(l, itype)
     133        2640 :                      if(m == 0) then
     134         440 :                         if(mod(l,2) == 1) then
     135             :                            !$acc kernels present(cprod, mpdata, mpdata%num_radbasfn)
     136             :                            cprod(lm+1:lm+mpdata%num_radbasfn(l, itype), :) &
     137      596492 :                               = -ImagUnit * cprod(lm+1:lm+mpdata%num_radbasfn(l, itype), :)
     138             :                            !$acc end kernels
     139             :                         endif
     140             :                      else
     141        1760 :                         if(m < 0) then
     142         880 :                            partner = lm + 2*abs(m)*mpdata%num_radbasfn(l,itype)
     143             :                            !$acc kernels present(cprod, mpdata, mpdata%num_radbasfn)
     144             :                            cprod(lm+1:lm+mpdata%num_radbasfn(l, itype), :) &
     145     5464488 :                               = (-1.0)**l * sqrt_2 * (-1.0)**m  * real(cprod(partner+1:partner+mpdata%num_radbasfn(l, itype), :))
     146             :                            !$acc end kernels
     147             :                         else 
     148             :                            !$acc kernels present(cprod, mpdata, mpdata%num_radbasfn)
     149             :                            cprod(lm+1:lm+mpdata%num_radbasfn(l, itype), :) &
     150     2732684 :                               = -(-1.0)**l * sqrt_2 * (-1.0)**m  * aimag(cprod(lm+1:lm+mpdata%num_radbasfn(l, itype), :))
     151             :                            !$acc end kernels
     152             :                         endif 
     153             :                      endif
     154             :                   enddo 
     155         528 :                   lm_0 = lm_0 + mpdata%num_radbasfn(l, itype)*(2*l + 1) ! go to the lm start index of the next l-quantum number
     156             :                enddo
     157             :             END IF
     158             :          enddo
     159             :       !$acc end data
     160          66 :    end subroutine transform_to_realsph
     161             : end module m_wavefproducts_inv

Generated by: LCOV version 1.14