LCOV - code coverage report
Current view: top level - hybrid - trafo.F90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 363 551 65.9 %
Date: 2024-04-23 04:28:20 Functions: 12 15 80.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------
       2             : ! Copyright (c) 2016 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
       3             : ! This file is part of FLEUR and available as free software under the conditions
       4             : ! of the MIT license as expressed in the LICENSE file in more detail.
       5             : !--------------------------------------------------------------------------------
       6             : 
       7             : MODULE m_trafo
       8             :    use m_judft
       9             :    use m_glob_tofrom_loc
      10             :    use m_constants
      11             : CONTAINS
      12             : 
      13           0 :    SUBROUTINE waveftrafo_symm(cmt_out, z_out, cmt, l_real, z_r, z_c, bandi, ndb, &
      14             :                               nk, iop, atoms, mpdata, hybinp, hybdat, kpts, &
      15             :                               sym, jsp, lapw)
      16             : 
      17             :       USE m_constants
      18             :       USE m_wrapper
      19             :       USE m_types_mpdata
      20             :       USE m_types_hybinp
      21             :       USE m_types_hybdat
      22             :       USE m_types_sym
      23             :       USE m_types_kpts
      24             :       USE m_types_atoms
      25             :       USE m_types_lapw
      26             :       USE m_juDFT
      27             :       IMPLICIT NONE
      28             : 
      29             :       TYPE(t_mpdata), INTENT(IN)      :: mpdata
      30             :       TYPE(t_hybinp), INTENT(IN)      :: hybinp
      31             :       TYPE(t_hybdat), INTENT(IN)      :: hybdat
      32             :       TYPE(t_sym), INTENT(IN)         :: sym
      33             :       TYPE(t_kpts), INTENT(IN)        :: kpts
      34             :       TYPE(t_atoms), INTENT(IN)       :: atoms
      35             :       TYPE(t_lapw), INTENT(IN)        :: lapw
      36             : 
      37             : !     - scalars -
      38             :       INTEGER, INTENT(IN)      :: nk, jsp, ndb
      39             :       INTEGER, INTENT(IN)      ::  bandi, iop
      40             : 
      41             : !     - arrays -
      42             :       COMPLEX, INTENT(IN)      ::  cmt(:, :, :)
      43             :       LOGICAL, INTENT(IN)      ::  l_real
      44             :       REAL, INTENT(IN)         ::  z_r(:, :)
      45             :       COMPLEX, INTENT(IN)      ::  z_c(:, :)
      46             :       COMPLEX, INTENT(INOUT)   ::  cmt_out(hybdat%maxlmindx, atoms%nat, ndb)
      47             :       COMPLEX, INTENT(INOUT)   ::  z_out(lapw%nv(jsp), ndb)
      48             : 
      49             : !     - local -
      50             : 
      51             : !     - scalars -
      52             :       INTEGER                 ::  iatom, iatom1, iiatom, itype, igpt, igpt1, ieq, iiop
      53             :       INTEGER                 ::  i, l, n, nn, lm0, lm1, lm2
      54             :       COMPLEX                 ::  cdum
      55             : 
      56             : !     - arrays -
      57             :       REAL                    ::  rrot(3, 3), invrrot(3, 3)
      58             :       INTEGER                 ::  g(3), g1(3)
      59             :       REAL                    ::  tau1(3), rkpt(3), rkpthlp(3), trans(3)
      60           0 :       COMPLEX                 ::  cmthlp(2*atoms%lmaxd + 1)
      61             :       LOGICAL                 ::  trs
      62             : 
      63           0 :       if (l_real) THEN
      64           0 :          rrot = transpose(1.0*sym%mrot(:, :, sym%invtab(iop)))
      65           0 :          invrrot = transpose(1.0*sym%mrot(:, :, iop))
      66           0 :          trans = sym%tau(:, iop)
      67             :       else
      68           0 :          IF (iop <= sym%nop) THEN
      69           0 :             trs = .false.
      70           0 :             rrot = transpose(1.0*sym%mrot(:, :, sym%invtab(iop)))
      71           0 :             invrrot = transpose(1.0*sym%mrot(:, :, iop))
      72           0 :             trans = sym%tau(:, iop)
      73             :          ELSE
      74           0 :             trs = .true.
      75           0 :             iiop = iop - sym%nop
      76           0 :             rrot = -transpose(1.0*sym%mrot(:, :, sym%invtab(iiop)))
      77           0 :             invrrot = -transpose(1.0*sym%mrot(:, :, iiop))
      78           0 :             trans = sym%tau(:, iiop)
      79             :          END IF
      80             :       end if
      81             : 
      82           0 :       rkpt = matmul(rrot, kpts%bkf(:, nk))
      83           0 :       rkpthlp = rkpt
      84           0 :       rkpt = kpts%to_first_bz(rkpt)
      85           0 :       g1 = nint(rkpt - rkpthlp)
      86             : 
      87             : ! MT coefficients
      88           0 :       cmt_out = 0
      89           0 :       iatom = 0
      90             : 
      91           0 :       DO itype = 1, atoms%ntype
      92           0 :          iiatom = atoms%firstAtom(itype) - 1
      93           0 :          DO ieq = 1, atoms%neq(itype)
      94           0 :             iatom = iatom + 1
      95             : 
      96           0 :             iatom1 = hybinp%map(iatom, iop)
      97           0 :             tau1 = hybinp%tvec(:, iatom, iop)
      98             : 
      99           0 :             cdum = exp(-ImagUnit*tpi_const*dot_product(rkpt, tau1))
     100             : 
     101           0 :             lm0 = 0
     102           0 :             DO l = 0, atoms%lmax(itype)
     103           0 :                nn = mpdata%num_radfun_per_l(l, itype)
     104           0 :                DO n = 1, nn
     105           0 :                   lm1 = lm0 + n
     106           0 :                   lm2 = lm0 + n + 2*l*nn
     107           0 :                   DO i = 1, ndb
     108           0 :                      if (l_real) THEN
     109             :                         cmt_out(lm1:lm2:nn, iatom1, i) = cdum* &
     110           0 :                                                          matmul(cmt(bandi + i - 1, lm1:lm2:nn, iatom), &
     111           0 :                                                                 sym%d_wgn(-l:l, -l:l, l, iop))
     112             :                      else
     113           0 :                         IF (trs) THEN
     114           0 :                            cmthlp(:2*l + 1) = CONJG(cmt(bandi + i - 1, lm1:lm2:nn, iatom))
     115             :                         ELSE
     116           0 :                            cmthlp(:2*l + 1) = cmt(bandi + i - 1, lm1:lm2:nn, iatom)
     117             :                         END IF
     118           0 :                         cmt_out(lm1:lm2:nn, iatom1, i) = cdum*matmul(cmthlp(:2*l + 1), sym%d_wgn(-l:l, -l:l, l, iop))
     119             :                      end if
     120             :                   END DO
     121             :                END DO
     122           0 :                lm0 = lm2
     123             :             END DO
     124             :          END DO
     125             :       END DO
     126             : 
     127             : ! PW coefficients
     128           0 :       z_out = 0
     129             : 
     130           0 :       DO igpt = 1, lapw%nv(jsp)
     131           0 :          g = INT(matmul(invrrot, lapw%gvec(:, igpt, jsp) + g1))
     132             : !determine number of g
     133           0 :          igpt1 = 0
     134           0 :          DO i = 1, lapw%nv(jsp)
     135           0 :             IF (maxval(abs(g - lapw%gvec(:, i, jsp))) <= 1E-06) THEN
     136             :                igpt1 = i
     137             :                EXIT
     138             :             END IF
     139             :          END DO
     140           0 :          IF (igpt1 == 0) THEN
     141           0 :             call judft_error('wavetrafo_symm: rotated G vector not found')
     142             :          END IF
     143           0 :          cdum = exp(-ImagUnit*tpi_const*dot_product(rkpt + lapw%gvec(:, igpt, jsp), trans(:)))
     144           0 :          if (l_real) THEN
     145           0 :             z_out(igpt, 1:ndb) = cdum*z_r(igpt1, bandi:bandi + ndb - 1)
     146             :          else
     147           0 :             IF (trs) THEN
     148           0 :                z_out(igpt, 1:ndb) = cdum*CONJG(z_c(igpt1, bandi:bandi + ndb - 1))
     149             :             ELSE
     150           0 :                z_out(igpt, 1:ndb) = cdum*z_c(igpt1, bandi:bandi + ndb - 1)
     151             :             END IF
     152             :          end if
     153             :       END DO
     154             : 
     155           0 :    END SUBROUTINE waveftrafo_symm
     156             : 
     157          84 :    SUBROUTINE waveftrafo_gen_cmt(cmt, c_phase, l_real, nk, iop, atoms, &
     158          28 :                                  mpdata, hybinp, kpts, sym, nbands, cmt_out)
     159             : 
     160             :       use m_juDFT
     161             :       USE m_constants
     162             :       USE m_wrapper
     163             :       USE m_types_mpdata
     164             :       USE m_types_hybinp
     165             :       USE m_types_sym
     166             :       USE m_types_kpts
     167             :       USE m_types_atoms
     168             :       IMPLICIT NONE
     169             : 
     170             :       TYPE(t_mpdata), INTENT(IN) :: mpdata
     171             :       TYPE(t_hybinp), INTENT(IN) :: hybinp
     172             :       TYPE(t_sym), INTENT(IN)    :: sym
     173             :       TYPE(t_kpts), INTENT(IN)   :: kpts
     174             :       TYPE(t_atoms), INTENT(IN)  :: atoms
     175             : !     - scalars -
     176             :       INTEGER, INTENT(IN)      :: nk, nbands
     177             :       INTEGER, INTENT(IN)      ::  iop
     178             :       LOGICAL, INTENT(in)      :: l_real
     179             : !     - arrays -
     180             :       COMPLEX, INTENT(IN)      ::  cmt(:, :, :), c_phase(nbands)
     181             : 
     182             :       COMPLEX, INTENT(INOUT)  ::  cmt_out(:, :, :)
     183             : !        - local -
     184             : 
     185             : !     - scalars -
     186             :       INTEGER                 ::  itype, iatom, iatom1, iiatom, ieq, iiop
     187             :       INTEGER                 ::  i, l, n, nn, lm0, lm1, lm2
     188             :       COMPLEX                 ::  cdum
     189             :       LOGICAL                 ::  trs
     190             : 
     191             : !     - arrays -
     192             :       INTEGER                 ::  rrot(3, 3), invrrot(3, 3)
     193             :       INTEGER                 ::  g1(3)
     194             :       REAL                    ::  tau1(3), rkpt(3), rkpthlp(3), trans(3)
     195          28 :       COMPLEX                 ::  cmthlp(2*atoms%lmaxd + 1)
     196             : 
     197          28 :       call timestart("gen_cmt")
     198          28 :       if (l_real) THEN
     199         260 :          rrot = transpose(sym%mrot(:, :, sym%invtab(iop)))
     200             :          invrrot = transpose(sym%mrot(:, :, iop))
     201          20 :          trans = sym%tau(:, iop)
     202             :       else
     203           8 :          IF (iop <= sym%nop) THEN
     204           8 :             trs = .false.
     205         104 :             rrot = transpose(sym%mrot(:, :, sym%invtab(iop)))
     206             :             invrrot = transpose(sym%mrot(:, :, iop))
     207           8 :             trans = sym%tau(:, iop)
     208             :          ELSE
     209             : ! in the case of SOC (l_soc=.true.)
     210             : ! time reversal symmetry is not valid anymore;
     211             : ! nsym should thus equal nop
     212           0 :             trs = .true.
     213           0 :             iiop = iop - sym%nop
     214           0 :             rrot = -transpose(sym%mrot(:, :, sym%invtab(iiop)))
     215             :             invrrot = -transpose(sym%mrot(:, :, iiop))
     216           0 :             trans = sym%tau(:, iiop)
     217             :          END IF
     218             :       end if
     219             : 
     220         700 :       rkpt = matmul(rrot, kpts%bkf(:, nk))
     221             :       rkpthlp = rkpt
     222         112 :       rkpt = kpts%to_first_bz(rkpt)
     223          28 :       g1 = nint(rkpt - rkpthlp)
     224             : 
     225             :       ! MT coefficients
     226       93504 :       cmt_out = 0
     227          28 :       iatom = 0
     228             : 
     229          72 :       DO itype = 1, atoms%ntype
     230          44 :          iiatom = atoms%firstAtom(itype) - 1
     231         116 :          DO ieq = 1, atoms%neq(itype)
     232          44 :             iatom = iatom + 1
     233             : 
     234          44 :             iatom1 = hybinp%map(iatom, iop)
     235         176 :             tau1 = hybinp%tvec(:, iatom, iop)
     236             : 
     237         176 :             cdum = exp(-ImagUnit*tpi_const*dot_product(rkpt, tau1))
     238             : 
     239          44 :             lm0 = 0
     240         516 :             DO l = 0, atoms%lmax(itype)
     241         428 :                nn = mpdata%num_radfun_per_l(l, itype)
     242        1340 :                DO n = 1, nn
     243         912 :                   lm1 = lm0 + n
     244         912 :                   lm2 = lm0 + n + 2*l*nn
     245             : 
     246       10460 :                   DO i = 1, nbands
     247       10032 :                      if (l_real) THEN
     248        4864 :                         cmt_out(i, lm1:lm2:nn, iatom1) = cdum*matmul(cmt(i, lm1:lm2:nn, iatom), &
     249      787392 :                                                                      hybinp%d_wgn2(-l:l, -l:l, l, iop))
     250             :                      else
     251        4256 :                         IF (trs) THEN
     252           0 :                            cmthlp(:2*l + 1) = conjg(cmt(i, lm1:lm2:nn, iatom))
     253             :                         ELSE
     254       41664 :                            cmthlp(:2*l + 1) = cmt(i, lm1:lm2:nn, iatom)
     255             :                         END IF
     256      556192 :                         cmt_out(i, lm1:lm2:nn, iatom1) = cdum*matmul(cmthlp(:2*l + 1), hybinp%d_wgn2(-l:l, -l:l, l, iop))
     257             :                      end if
     258             : 
     259             :                   END DO
     260             :                END DO
     261         472 :                lm0 = lm2
     262             :             END DO
     263             :          END DO
     264             :       END DO
     265             : 
     266             :       ! If phase and inversion-sym. is true,
     267             :       ! define the phase such that z_out is real.
     268          28 :       if (l_real) then
     269         180 :          DO i = 1, nbands
     270       47828 :             cmt_out(i, :, :) = cmt_out(i, :, :)/c_phase(i)
     271             :          END DO
     272             :       end if
     273          28 :       call timestop("gen_cmt")
     274          28 :    END SUBROUTINE waveftrafo_gen_cmt
     275             : 
     276           0 :    SUBROUTINE waveftrafo_genwavf( &
     277           0 :       cmt, z_in, nk, iop, atoms, &
     278             :       mpdata, hybinp, kpts, sym, jsp, input, nbands, &
     279           0 :       lapw_nk, lapw_rkpt, cmt_out, z_out)
     280             : 
     281             :       use m_juDFT
     282             :       USE m_constants
     283             :       USE m_wrapper
     284             :       USE m_types_mat
     285             :       USE m_types_input
     286             :       USE m_types_mpdata
     287             :       USE m_types_hybinp
     288             :       USE m_types_sym
     289             :       USE m_types_kpts
     290             :       USE m_types_atoms
     291             :       USE m_types_lapw
     292             :       IMPLICIT NONE
     293             : 
     294             :       type(t_mat), intent(in)     :: z_in
     295             :       TYPE(t_input), INTENT(IN)   :: input
     296             :       TYPE(t_mpdata), INTENT(IN)    :: mpdata
     297             :       TYPE(t_hybinp), INTENT(IN)   :: hybinp
     298             :       TYPE(t_sym), INTENT(IN)   :: sym
     299             :       TYPE(t_kpts), INTENT(IN)   :: kpts
     300             :       TYPE(t_atoms), INTENT(IN)   :: atoms
     301             :       TYPE(t_lapw), INTENT(IN)    :: lapw_nk, lapw_rkpt
     302             :       type(t_mat), intent(inout)  :: z_out
     303             : !     - scalars -
     304             :       INTEGER, INTENT(IN)      :: nk, jsp, nbands
     305             :       INTEGER, INTENT(IN)      ::  iop
     306             : !     - arrays -
     307             :       COMPLEX, INTENT(IN)      ::  cmt(:, :, :)
     308             : 
     309             :       COMPLEX, INTENT(INOUT)  ::  cmt_out(:, :, :)
     310             : !        - local -
     311             : 
     312             : !     - scalars -
     313             :       INTEGER                 ::  itype, iatom, iatom1, iiatom, igpt, igpt1, ieq, iiop
     314             :       INTEGER                 ::  i, l, n, nn, lm0, lm1, lm2
     315             :       COMPLEX                 ::  cdum
     316             :       LOGICAL                 ::  trs
     317             : 
     318             : !     - arrays -
     319             :       INTEGER                 ::  rrot(3, 3), invrrot(3, 3)
     320             :       INTEGER                 ::  g(3), g1(3)
     321             :       REAL                    ::  tau1(3), rkpt(3), rkpthlp(3), trans(3)
     322           0 :       COMPLEX                 ::  zhlp(z_in%matsize1, input%neig)
     323           0 :       COMPLEX                 ::  cmthlp(2*atoms%lmaxd + 1)
     324             : 
     325           0 :       call timestart("genwavf")
     326           0 :       if (z_in%l_real) THEN
     327           0 :          rrot = transpose(sym%mrot(:, :, sym%invtab(iop)))
     328           0 :          invrrot = transpose(sym%mrot(:, :, iop))
     329           0 :          trans = sym%tau(:, iop)
     330             :       else
     331           0 :          IF (iop <= sym%nop) THEN
     332           0 :             trs = .false.
     333           0 :             rrot = transpose(sym%mrot(:, :, sym%invtab(iop)))
     334           0 :             invrrot = transpose(sym%mrot(:, :, iop))
     335           0 :             trans = sym%tau(:, iop)
     336             :          ELSE
     337             : ! in the case of SOC (l_soc=.true.)
     338             : ! time reversal symmetry is not valid anymore;
     339             : ! nsym should thus equal nop
     340           0 :             trs = .true.
     341           0 :             iiop = iop - sym%nop
     342           0 :             rrot = -transpose(sym%mrot(:, :, sym%invtab(iiop)))
     343           0 :             invrrot = -transpose(sym%mrot(:, :, iiop))
     344           0 :             trans = sym%tau(:, iiop)
     345             :          END IF
     346             :       end if
     347             : 
     348           0 :       rkpt = matmul(rrot, kpts%bkf(:, nk))
     349           0 :       rkpthlp = rkpt
     350           0 :       rkpt = kpts%to_first_bz(rkpt)
     351           0 :       g1 = nint(rkpt - rkpthlp)
     352             : 
     353             :       ! MT coefficients
     354           0 :       cmt_out = 0
     355           0 :       iatom = 0
     356             : 
     357           0 :       DO itype = 1, atoms%ntype
     358           0 :          iiatom = atoms%firstAtom(itype) - 1
     359           0 :          DO ieq = 1, atoms%neq(itype)
     360           0 :             iatom = iatom + 1
     361             : 
     362           0 :             iatom1 = hybinp%map(iatom, iop)
     363           0 :             tau1 = hybinp%tvec(:, iatom, iop)
     364             : 
     365           0 :             cdum = exp(-ImagUnit*tpi_const*dot_product(rkpt, tau1))
     366             : 
     367           0 :             lm0 = 0
     368           0 :             DO l = 0, atoms%lmax(itype)
     369           0 :                nn = mpdata%num_radfun_per_l(l, itype)
     370           0 :                DO n = 1, nn
     371           0 :                   lm1 = lm0 + n
     372           0 :                   lm2 = lm0 + n + 2*l*nn
     373             : 
     374           0 :                   DO i = 1, nbands
     375           0 :                      if (z_in%l_real) THEN
     376           0 :                         cmt_out(i, lm1:lm2:nn, iatom1) = cdum*matmul(cmt(i, lm1:lm2:nn, iatom), &
     377           0 :                                                                      hybinp%d_wgn2(-l:l, -l:l, l, iop))
     378             :                      else
     379           0 :                         IF (trs) THEN
     380           0 :                            cmthlp(:2*l + 1) = conjg(cmt(i, lm1:lm2:nn, iatom))
     381             :                         ELSE
     382           0 :                            cmthlp(:2*l + 1) = cmt(i, lm1:lm2:nn, iatom)
     383             :                         END IF
     384           0 :                         cmt_out(i, lm1:lm2:nn, iatom1) = cdum*matmul(cmthlp(:2*l + 1), hybinp%d_wgn2(-l:l, -l:l, l, iop))
     385             :                      end if
     386             : 
     387             :                   END DO
     388             :                END DO
     389           0 :                lm0 = lm2
     390             :             END DO
     391             :          END DO
     392             :       END DO
     393             : 
     394             :       ! PW coefficients
     395             : 
     396           0 :       zhlp = 0
     397           0 :       DO igpt = 1, lapw_rkpt%nv(jsp)
     398           0 :          g = matmul(invrrot, lapw_rkpt%gvec(:, igpt, jsp) + g1)
     399             :          !determine number of g
     400           0 :          igpt1 = 0
     401           0 :          DO i = 1, lapw_nk%nv(jsp)
     402           0 :             IF (all(abs(g - lapw_nk%gvec(:, i, jsp)) <= 1E-06)) THEN
     403             :                igpt1 = i
     404             :                EXIT
     405             :             END IF
     406             :          END DO
     407           0 :          IF (igpt1 == 0) CYCLE
     408           0 :          cdum = exp(-ImagUnit*tpi_const*dot_product(rkpt + lapw_rkpt%gvec(:, igpt, jsp), trans))
     409           0 :          if (z_in%l_real) THEN
     410           0 :             zhlp(igpt, :nbands) = cdum*z_in%data_r(igpt1, :nbands)
     411             :          else
     412           0 :             IF (trs) THEN
     413           0 :                zhlp(igpt, :nbands) = cdum*conjg(z_in%data_c(igpt1, :nbands))
     414             :             ELSE
     415           0 :                zhlp(igpt, :nbands) = cdum*z_in%data_c(igpt1, :nbands)
     416             :             END IF
     417             :          end if
     418             :       END DO
     419             : 
     420             :       ! If phase and inversion-sym. is true,
     421             :       ! define the phase such that z_out is real.
     422             : 
     423           0 :       DO i = 1, nbands
     424           0 :          if (z_in%l_real) THEN
     425           0 :             cdum = commonphase(zhlp(:, i), z_in%matsize1)
     426             : 
     427           0 :             IF (any(abs(aimag(zhlp(:, i)/cdum)) > 1e-8)) THEN
     428           0 :                WRITE (*, *) maxval(abs(aimag(zhlp(:, i)/cdum)))
     429           0 :                WRITE (*, *) zhlp
     430           0 :                call judft_error('waveftrafo1: Residual imaginary part.')
     431             :             END IF
     432           0 :             z_out%data_r(:, i) = real(zhlp(:, i)/cdum)
     433           0 :             cmt_out(i, :, :) = cmt_out(i, :, :)/cdum
     434             :          else
     435           0 :             z_out%data_c(:, i) = zhlp(:, i)
     436             :          end if
     437             :       END DO
     438           0 :       call timestop("genwavf")
     439           0 :    END SUBROUTINE waveftrafo_genwavf
     440             : 
     441          28 :    SUBROUTINE waveftrafo_gen_zmat(z_in, nk, iop, &
     442             :                                   kpts, sym, jsp, nbands, &
     443          28 :                                   lapw_nk, lapw_rkpt, z_out, c_phase)
     444             : 
     445             :       use m_juDFT
     446             :       USE m_constants
     447             :       USE m_wrapper
     448             :       USE m_types_mat
     449             :       USE m_types_sym
     450             :       USE m_types_kpts
     451             :       USE m_types_lapw
     452             :       IMPLICIT NONE
     453             : 
     454             :       type(t_mat), intent(in)     :: z_in
     455             :       TYPE(t_sym), INTENT(IN)     :: sym
     456             :       TYPE(t_kpts), INTENT(IN)    :: kpts
     457             :       TYPE(t_lapw), INTENT(IN)    :: lapw_nk, lapw_rkpt
     458             :       type(t_mat), intent(inout)  :: z_out
     459             :       complex, intent(inout), optional :: c_phase(:)
     460             : !     - scalars -
     461             :       INTEGER, INTENT(IN)      :: nk, jsp, nbands
     462             :       INTEGER, INTENT(IN)      :: iop
     463             : 
     464             : !     - scalars -
     465             :       INTEGER                 ::  igpt, igpt1, iiop, i
     466             :       COMPLEX                 ::  cdum
     467             :       LOGICAL                 ::  trs
     468             : 
     469             : !     - arrays -
     470             :       INTEGER                 ::  rrot(3, 3), invrrot(3, 3)
     471             :       INTEGER                 ::  g(3), g1(3)
     472             :       REAL                    ::  rkpt(3), rkpthlp(3), trans(3)
     473          28 :       COMPLEX                 ::  zhlp(z_in%matsize1, nbands)
     474             : 
     475          28 :       call timestart("gen_zmat")
     476        1440 :       if (present(c_phase)) c_phase = 0
     477             : 
     478          28 :       if (z_in%l_real) THEN
     479         260 :          rrot = transpose(sym%mrot(:, :, sym%invtab(iop)))
     480         260 :          invrrot = transpose(sym%mrot(:, :, iop))
     481          80 :          trans = sym%tau(:, iop)
     482             :       else
     483           8 :          IF (iop <= sym%nop) THEN
     484           8 :             trs = .false.
     485         104 :             rrot = transpose(sym%mrot(:, :, sym%invtab(iop)))
     486         104 :             invrrot = transpose(sym%mrot(:, :, iop))
     487          32 :             trans = sym%tau(:, iop)
     488             :          ELSE
     489             : ! in the case of SOC (l_soc=.true.)
     490             : ! time reversal symmetry is not valid anymore;
     491             : ! nsym should thus equal nop
     492           0 :             trs = .true.
     493           0 :             iiop = iop - sym%nop
     494           0 :             rrot = -transpose(sym%mrot(:, :, sym%invtab(iiop)))
     495           0 :             invrrot = -transpose(sym%mrot(:, :, iiop))
     496           0 :             trans = sym%tau(:, iiop)
     497             :          END IF
     498             :       end if
     499             : 
     500         700 :       rkpt = matmul(rrot, kpts%bkf(:, nk))
     501          28 :       rkpthlp = rkpt
     502         112 :       rkpt = kpts%to_first_bz(rkpt)
     503         112 :       g1 = nint(rkpt - rkpthlp)
     504             : 
     505             :       ! PW coefficients
     506             : 
     507       43612 :       zhlp = 0
     508        4196 :       DO igpt = 1, lapw_rkpt%nv(jsp)
     509       66688 :          g = matmul(invrrot, lapw_rkpt%gvec(:, igpt, jsp) + g1)
     510             :          !determine number of g
     511        4168 :          igpt1 = 0
     512      376668 :          DO i = 1, lapw_nk%nv(jsp)
     513      452200 :             IF (all(abs(g - lapw_nk%gvec(:, i, jsp)) <= 1E-06)) THEN
     514             :                igpt1 = i
     515             :                EXIT
     516             :             END IF
     517             :          END DO
     518        4168 :          IF (igpt1 == 0) CYCLE
     519       16672 :          cdum = exp(-ImagUnit*tpi_const*dot_product(rkpt + lapw_rkpt%gvec(:, igpt, jsp), trans))
     520        4196 :          if (z_in%l_real) THEN
     521       25200 :             zhlp(igpt, :nbands) = cdum*z_in%data_r(igpt1, :nbands)
     522             :          else
     523        1368 :             IF (trs) THEN
     524           0 :                zhlp(igpt, :nbands) = cdum*conjg(z_in%data_c(igpt1, :nbands))
     525             :             ELSE
     526       20520 :                zhlp(igpt, :nbands) = cdum*z_in%data_c(igpt1, :nbands)
     527             :             END IF
     528             :          end if
     529             :       END DO
     530             : 
     531             :       ! If phase and inversion-sym. is true,
     532             :       ! define the phase such that z_out is real.
     533             : 
     534         300 :       DO i = 1, nbands
     535         300 :          if (z_in%l_real) THEN
     536         160 :             cdum = commonphase(zhlp(:, i), z_in%matsize1)
     537         160 :             if (present(c_phase)) c_phase(i) = cdum
     538         160 :             if (abs(cdum) < 1e-30) THEN
     539           0 :                call juDFT_error("commonphase can't be 0.")
     540             :             end if
     541       23200 :             IF (any(abs(aimag(zhlp(:, i)/cdum)) > 1e-8)) THEN
     542           0 :                WRITE (*, *) maxval(abs(aimag(zhlp(:, i)/cdum)))
     543           0 :                call judft_error('waveftrafo1: Residual imaginary part.')
     544             :             END IF
     545       23200 :             z_out%data_r(:, i) = real(zhlp(:, i)/cdum)
     546             :          else
     547       20384 :             z_out%data_c(:, i) = zhlp(:, i)
     548             :          end if
     549             :       END DO
     550          28 :       call timestop("gen_zmat")
     551          28 :    END SUBROUTINE waveftrafo_gen_zmat
     552             : 
     553             : ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     554             :    ! Symmetrizes MT part of input matrix according to inversion symmetry.
     555             :    ! This is achieved by a transformation to
     556             :    !        1/sqrt(2) * ( exp(ikR) Y_lm(r-R) + (-1)**(l+m) exp(-ikR) Y_l,-m(r+R) )
     557             :    ! and                                                                                 if R /=0 or m<0
     558             :    !        i/sqrt(2) * ( exp(ikR) Y_lm(r-R) - (-1)**(l+m) exp(-ikR) Y_l,-m(r+R) ) .
     559             :    !
     560             :    !  or
     561             :    !        i*Y_l,0(r)                                                                   if R=0,m=0 and l odd
     562             :    ! These functions have the property f(-r)=f(r)* which makes the output matrix real symmetric.
     563             :    ! (Array mat is overwritten! )
     564             : 
     565         120 :    SUBROUTINE symmetrize_mpimat(fi, fmpi, mpimat, start_dim, end_dim, imode, lreal, nindxm)
     566             :       USE m_types_fleurinput
     567             :       USE m_types_mpi
     568             :       use m_constants
     569             : 
     570             : #ifdef CPP_MPI
     571             :       USE mpi
     572             : #endif
     573             : 
     574             : 
     575             :       IMPLICIT NONE
     576             :       type(t_fleurinput), intent(in)  :: fi
     577             :       type(t_mpi), intent(in)         :: fmpi
     578             : 
     579             : !     - scalars -
     580             :       INTEGER, INTENT(IN)    :: imode, start_dim(2), end_dim(2)
     581             :       LOGICAL, INTENT(IN)    ::  lreal
     582             : 
     583             : !     - arrays -
     584             :       INTEGER, INTENT(IN)    ::  nindxm(0:maxval(fi%hybinp%lcutm1), fi%atoms%ntype)
     585             :       COMPLEX, INTENT(INOUT) ::  mpimat(:, :)
     586             : 
     587             : !     -local scalars -
     588             :       INTEGER               :: i, j, itype, ieq, ic, ic1, l, m, n, nn, ifac, ishift, start_loc, end_loc
     589             :       integer               :: i_loc, j_loc, i_pe, j_pe, ierr, len_dim(2)
     590             :       REAL                  :: rfac
     591             : 
     592             : !     - local arrays -
     593         144 :       COMPLEX               ::  mpicarr(maxval(end_dim)), cfac
     594             : 
     595          48 :       call timestart("symmetrize_mpimat")
     596         144 :       len_dim = end_dim - start_dim + 1
     597          48 :       rfac = sqrt(0.5)
     598          48 :       cfac = sqrt(0.5)*ImagUnit
     599          48 :       ic = 0
     600          48 :       i = 0
     601             : 
     602         120 :       DO itype = 1, fi%atoms%ntype
     603         864 :          nn = sum([((2*l + 1)*nindxm(l, itype), l=0, fi%hybinp%lcutm1(itype))])
     604         192 :          DO ieq = 1, fi%atoms%neq(itype)
     605          72 :             ic = ic + 1
     606          72 :             IF (fi%sym%invsat(ic) == 0) THEN
     607             : ! if the structure is inversion-symmetric, but the equivalent atom belongs to a different unit cell
     608             : ! invsat(atom) = 0, invsatnr(atom) = 0
     609             : ! but we need invsatnr(atom) = natom
     610             :                ic1 = ic
     611             :             ELSE
     612           0 :                ic1 = fi%sym%invsatnr(ic)
     613             :             END IF
     614             : !ic1 = invsatnr(ic)
     615          72 :             IF (ic1 < ic) THEN
     616           0 :                i = i + nn
     617           0 :                CYCLE
     618             :             END IF
     619             : !     IF( ic1 .lt. ic ) cycle
     620         504 :             DO l = 0, fi%hybinp%lcutm1(itype)
     621         360 :                ifac = -1
     622        2232 :                DO m = -l, l
     623        1800 :                   ifac = -ifac
     624        1800 :                   ishift = (ic1 - ic)*nn - 2*m*nindxm(l, itype)
     625       14448 :                   DO n = 1, nindxm(l, itype)
     626       12288 :                      i = i + 1
     627       12288 :                      j = i + ishift
     628       12288 :                      call glob_to_loc(fmpi, i, i_pe, i_loc)
     629       12288 :                      call glob_to_loc(fmpi, j, j_pe, j_loc)
     630       14088 :                      IF (ic1 /= ic .or. m < 0) THEN
     631        4800 :                         IF (iand(imode, 1) /= 0) THEN
     632        4800 :                            call range_from_glob_to_loc(fmpi, start_dim(2), start_loc)
     633        4800 :                            call range_to_glob_to_loc(fmpi, end_dim(2), end_loc)
     634      513088 :                            mpicarr(start_loc:end_loc)  = mpimat(i,start_loc:end_loc)
     635      513088 :                            mpimat(i,start_loc:end_loc) = (mpicarr(start_loc:end_loc) + ifac*mpimat(j,start_loc:end_loc))*rfac
     636      513088 :                            mpimat(j,start_loc:end_loc) = (mpicarr(start_loc:end_loc) - ifac*mpimat(j,start_loc:end_loc))*(-cfac)
     637             :                         END IF
     638        4800 :                         IF (iand(imode, 2) /= 0) THEN
     639        2400 :                            if(i_pe == j_pe .and. fmpi%n_rank == i_pe) then 
     640      332256 :                               mpicarr(start_dim(1):end_dim(1)) = mpimat(start_dim(1):end_dim(1), i_loc)
     641             :                               mpimat(start_dim(1):end_dim(1),i_loc) &
     642      332256 :                                  = (mpimat(start_dim(1):end_dim(1), i_loc) + ifac*mpimat(start_dim(1):end_dim(1), j_loc))*rfac
     643             :                               mpimat(start_dim(1):end_dim(1),j_loc) &
     644      332256 :                                  = (mpicarr(start_dim(1):end_dim(1)) - ifac*mpimat(start_dim(1):end_dim(1), j_loc))*cfac
     645             : #ifdef CPP_MPI
     646             :                            else
     647        1200 :                               if(fmpi%n_rank == i_pe) then 
     648           0 :                                  call MPI_Send(mpimat(start_dim(1),i_loc), len_dim(1), MPI_DOUBLE_COMPLEX, j_pe, i, fmpi%sub_comm, ierr)
     649           0 :                                  call MPI_Recv(mpicarr(start_dim(1)), len_dim(1), MPI_DOUBLE_COMPLEX, j_pe, j, fmpi%sub_comm, MPI_STATUS_IGNORE, ierr)
     650           0 :                                  mpimat(start_dim(1):end_dim(1),i_loc) = (mpimat(start_dim(1):end_dim(1), i_loc) + ifac*mpicarr(start_dim(1):end_dim(1)))*rfac
     651        1200 :                               elseif(fmpi%n_rank == j_pe) then 
     652           0 :                                  call MPI_Recv(mpicarr(start_dim(1)), len_dim(1), MPI_DOUBLE_COMPLEX, i_pe, i, fmpi%sub_comm, MPI_STATUS_IGNORE, ierr)
     653           0 :                                  call MPI_Send(mpimat(start_dim(1),j_loc), len_dim(1), MPI_DOUBLE_COMPLEX, i_pe, j, fmpi%sub_comm, ierr)
     654           0 :                                  mpimat(start_dim(1):end_dim(1),j_loc) = (mpicarr(start_dim(1):end_dim(1)) - ifac*mpimat(start_dim(1):end_dim(1), j_loc))*cfac
     655             :                               endif
     656             : #endif
     657             :                            endif
     658             :                         END IF
     659        7488 :                      ELSE IF (m == 0 .and. ifac == -1) THEN
     660        1056 :                         IF (iand(imode, 1) /= 0) THEN
     661        1056 :                            call range_from_glob_to_loc(fmpi, start_dim(2), start_loc)
     662        1056 :                            call range_to_glob_to_loc(fmpi, end_dim(2), end_loc)
     663      112592 :                            mpimat(i,start_loc:end_loc) = -ImagUnit*mpimat(i,start_loc:end_loc)
     664             :                         END IF
     665        1056 :                         IF (iand(imode, 2) /= 0 .and. fmpi%n_rank == i_pe) THEN
     666       72960 :                            mpimat(start_dim(1):end_dim(1), i_loc) = ImagUnit*mpimat(start_dim(1):end_dim(1), i_loc)
     667             :                         END IF
     668             :                      END IF
     669             :                   END DO
     670             :                END DO
     671             :             END DO
     672             :          END DO
     673             :       END DO
     674             : 
     675          48 :       IF (lreal) THEN
     676           0 :          call juDFT_error("this isn't impemented for mpimat")
     677             : ! Determine common phase factor and divide by it to make the output matrix real.
     678             :          ! cfac = commonphase_mtx(mat, dims(1), dims(2))
     679             :          ! do i = 1, dims(1)
     680             :          ! do j = 1, dims(2)
     681             :          !    mat(i, j) = mat(i, j)/cfac
     682             :          !    if (abs(aimag(mat(i, j))) > 1e-8) then
     683             :          !       call judft_error('symmetrize: Residual imaginary part. Symmetrization failed.')
     684             :          !    end if
     685             :          ! end do
     686             :          ! end do
     687             :       END IF
     688             : 
     689          48 :       call timestop("symmetrize_mpimat")
     690          48 :    END SUBROUTINE symmetrize_mpimat
     691             : 
     692             : 
     693             : ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     694             :    ! Symmetrizes MT part of input matrix according to inversion symmetry.
     695             :    ! This is achieved by a transformation to
     696             :    !        1/sqrt(2) * ( exp(ikR) Y_lm(r-R) + (-1)**(l+m) exp(-ikR) Y_l,-m(r+R) )
     697             :    ! and                                                                                 if R /=0 or m<0
     698             :    !        i/sqrt(2) * ( exp(ikR) Y_lm(r-R) - (-1)**(l+m) exp(-ikR) Y_l,-m(r+R) ) .
     699             :    !
     700             :    !  or
     701             :    !        i*Y_l,0(r)                                                                   if R=0,m=0 and l odd
     702             :    ! These functions have the property f(-r)=f(r)* which makes the output matrix real symmetric.
     703             :    ! (Array mat is overwritten! )
     704             : 
     705       22152 :    SUBROUTINE symmetrize(mat, dim1, dim2, imode,&
     706        7384 :                          atoms, lcutm, maxlcutm, nindxm, sym)
     707             :       USE m_types_atoms
     708             :       USE m_types_sym
     709             :       use m_constants
     710             :       IMPLICIT NONE
     711             :       TYPE(t_atoms), INTENT(IN)   :: atoms
     712             :       TYPE(t_sym), INTENT(IN)     :: sym
     713             : 
     714             : !     - scalars -
     715             :       INTEGER, INTENT(IN)    ::  imode, dim1, dim2
     716             :       INTEGER, INTENT(IN)    :: maxlcutm
     717             : 
     718             : !     - arrays -
     719             :       INTEGER, INTENT(IN)    :: lcutm(:)
     720             :       INTEGER, INTENT(IN)    ::  nindxm(0:maxlcutm, atoms%ntype)
     721             :       COMPLEX, INTENT(INOUT) ::  mat(:, :)
     722             : 
     723             : !     -local scalars -
     724             :       INTEGER               ::  i, j, itype, ieq, ic, ic1, l, m, n, nn, ifac, ishift
     725             :       REAL, parameter       ::  rfac = sqrt(0.5)
     726             : 
     727             : !     - local arrays -
     728        7384 :       COMPLEX               ::  carr(max(dim1, dim2)), cfac = sqrt(0.5)*ImagUnit
     729             : 
     730             : !      call timestart("symmetrize")
     731        7384 :       ic = 0
     732        7384 :       i = 0
     733             : 
     734       18030 :       DO itype = 1, atoms%ntype
     735      127608 :          nn = sum([((2*l + 1)*nindxm(l, itype), l=0, lcutm(itype))])
     736       28676 :          DO ieq = 1, atoms%neq(itype)
     737       10646 :             ic = ic + 1
     738       10646 :             IF (sym%invsat(ic) == 0) THEN
     739             : ! if the structure is inversion-symmetric, but the equivalent atom belongs to a different unit cell
     740             : ! invsat(atom) = 0, invsatnr(atom) = 0
     741             : ! but we need invsatnr(atom) = natom
     742             :                ic1 = ic
     743             :             ELSE
     744           0 :                ic1 = sym%invsatnr(ic)
     745             :             END IF
     746             : !ic1 = invsatnr(ic)
     747       10646 :             IF (ic1 < ic) THEN
     748           0 :                i = i + nn
     749           0 :                CYCLE
     750             :             END IF
     751             : !     IF( ic1 .lt. ic ) cycle
     752       74450 :             DO l = 0, lcutm(itype)
     753       53158 :                ifac = -1
     754      329450 :                DO m = -l, l
     755      265646 :                   ifac = -ifac
     756      265646 :                   ishift = (ic1 - ic)*nn - 2*m*nindxm(l, itype)
     757     2143986 :                   DO n = 1, nindxm(l, itype)
     758     1825182 :                      i = i + 1
     759     1825182 :                      j = i + ishift
     760     2090828 :                      IF (ic1 /= ic .or. m < 0) THEN
     761      712712 :                         IF (iand(imode, 1) /= 0) THEN
     762     1417580 :                            carr(:dim2) = mat(i, :dim2)
     763     1417580 :                            mat(i, :dim2) = (carr(:dim2) + ifac*mat(j, :dim2))*rfac
     764     1417580 :                            mat(j, :dim2) = (carr(:dim2) - ifac*mat(j, :dim2))*(-cfac)
     765             :                         END IF
     766      712712 :                         IF (iand(imode, 2) /= 0) THEN
     767        8204 :                            carr(:dim1) = mat(:dim1, i)
     768        8204 :                            mat(:dim1, i) = (carr(:dim1) + ifac*mat(:dim1, j))*rfac
     769        8204 :                            mat(:dim1, j) = (carr(:dim1) - ifac*mat(:dim1, j))*cfac
     770             :                         END IF
     771     1112470 :                      ELSE IF (m == 0 .and. ifac == -1) THEN
     772      156952 :                         IF (iand(imode, 1) /= 0) THEN
     773      312300 :                            mat(i, :dim2) = -ImagUnit*mat(i, :dim2)
     774             :                         END IF
     775      156952 :                         IF (iand(imode, 2) /= 0) THEN
     776        1964 :                            mat(:dim1, i) = ImagUnit*mat(:dim1, i)
     777             :                         END IF
     778             :                      END IF
     779             :                   END DO
     780             :                END DO
     781             :             END DO
     782             :          END DO
     783             :       END DO
     784             : !      call timestop("symmetrize")
     785        7384 :    END SUBROUTINE symmetrize
     786             : 
     787             : ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     788             : 
     789             :    ! Undoes symmetrization with routine symmetrize.
     790       14652 :    SUBROUTINE desymmetrize(mat, dim1, dim2, &
     791        7326 :                            atoms, lcutm, maxlcutm, nindxm, sym)
     792             : 
     793             :       USE m_types_sym
     794             :       USE m_types_atoms
     795             :       IMPLICIT NONE
     796             :       TYPE(t_sym), INTENT(IN)   :: sym
     797             :       TYPE(t_atoms), INTENT(IN)   :: atoms
     798             : 
     799             : !     - scalars -
     800             :       INTEGER, INTENT(IN)      :: dim1, dim2
     801             :       INTEGER, INTENT(IN)      :: maxlcutm
     802             : 
     803             : !     - arrays -
     804             :       INTEGER, INTENT(IN)      :: lcutm(:)
     805             :       INTEGER, INTENT(IN)      ::  nindxm(0:maxlcutm, atoms%ntype)
     806             :       COMPLEX, INTENT(INOUT)   ::  mat(dim1, dim2)
     807             : 
     808             : !     - local scalars -
     809             :       INTEGER                 ::  ifac, i, istart, j, itype, ieq, ic, ic1, l, m, n, nn, ishift
     810             :       REAL, parameter         ::  rfac1 = sqrt(0.5)
     811             :       real                    ::  rfac2
     812             : !     - local arrays -
     813        7326 :       COMPLEX                 ::  carr(max(dim1, dim2))
     814             : 
     815             : !      call timestart("desymmetrize")
     816        7326 :       ic = 0
     817        7326 :       istart = 0
     818       17888 :       DO itype = 1, atoms%ntype
     819      126744 :          nn = sum([((2*l + 1)*nindxm(l, itype), l=0, lcutm(itype))])
     820       28450 :          DO ieq = 1, atoms%neq(itype)
     821       10562 :             ic = ic + 1
     822             :             ! if the structure is inversion-symmetric, but the equivalent atom belongs to a different unit cell
     823             :             ! invsat(atom) = 0, invsatnr(atom) =0
     824             :             ! but we need invsatnr(atom) = natom
     825       10562 :             ic1 = merge(ic, sym%invsatnr(ic), sym%invsat(ic) == 0)
     826             :             !ic1 = invsatnr(ic)
     827             :             !IF( ic1 .lt. ic ) cycle
     828       21124 :             IF (ic1 < ic) THEN
     829           0 :                istart = istart + nn
     830             :             else
     831       63372 :                DO l = 0, lcutm(itype)
     832       52810 :                   ifac = -1
     833      327422 :                   DO m = -l, l
     834      264050 :                      ifac = -ifac
     835      264050 :                      rfac2 = rfac1*ifac
     836      264050 :                      ishift = (ic1 - ic)*nn - 2*m*nindxm(l, itype)
     837      264050 :                      IF (ic1 /= ic .or. m < 0) THEN
     838      105620 :                         if (ishift <= nindxm(l, itype)) call juDFT_error("if ishift is zero the parallelization is wrong")
     839      814308 :                         DO n = 1, nindxm(l, itype)
     840      708688 :                            i = istart + n
     841      708688 :                            j = i + ishift
     842     1417376 :                            carr(:dim2) = mat(i, :)
     843     1417376 :                            mat(i, :) = (carr(:dim2) + ImagUnit*mat(j, :))*rfac1
     844     1522996 :                            mat(j, :) = (carr(:dim2) - ImagUnit*mat(j, :))*rfac2
     845             :                         enddo
     846      158430 :                      ELSE IF (m == 0 .and. ifac == -1) THEN
     847      177172 :                         DO n = 1, nindxm(l, itype)
     848      333220 :                            mat(istart + n, :) = ImagUnit*mat(istart + n, :)
     849             :                         enddo
     850             :                      endif
     851      316860 :                      istart = istart +  nindxm(l, itype)
     852             :                   END DO
     853             :                END DO
     854             :             endif
     855             :          END DO
     856             :       END DO
     857             : !      call timestop("desymmetrize")
     858        7326 :    END SUBROUTINE desymmetrize
     859             : 
     860             :    ! bra_trafo1 rotates cprod at kpts%bkp(ikpt)(<=> not irreducible k-point) to cprod at ikpt (bkp(kpts%bkp(ikpt))), which is the
     861             :    ! symmetrie equivalent one
     862             :    ! isym maps kpts%bkp(ikpt) on ikpt
     863             : 
     864          16 :    subroutine bra_trafo(fi, mpdata, hybdat, nbands, ikpt, psize, phase, vecin, vecout)
     865             :       use m_types_fleurinput
     866             :       USE m_types_mpdata
     867             :       USE m_types_hybdat
     868             :       USE m_types_mat
     869             :       use m_constants
     870             :       use m_judft
     871             :       implicit none
     872             :       type(t_fleurinput), intent(in)    :: fi
     873             :       type(t_mpdata), intent(in)        :: mpdata
     874             :       TYPE(t_hybdat), INTENT(IN)        :: hybdat
     875             :       INTEGER, INTENT(IN)               :: ikpt, nbands, psize
     876             :       type(t_mat), INTENT(IN)           :: vecin
     877             :       type(t_mat), INTENT(INOUT)        :: vecout
     878             :       COMPLEX, INTENT(INOUT)            :: phase(:, :)
     879             : 
     880          16 :       if (vecin%l_real) then
     881          12 :          call bra_trafo_real(fi, mpdata, hybdat, nbands, ikpt, psize, phase, vecin%data_r, vecout%data_r)
     882             :       else
     883           4 :          phase = cmplx_1
     884           4 :          call bra_trafo_cmplx(fi, mpdata, hybdat, nbands, ikpt, psize, vecin%data_c, vecout%data_c)
     885             :       end if
     886             : 
     887          16 :    end subroutine bra_trafo
     888             : 
     889          12 :    subroutine bra_trafo_real(fi, mpdata, hybdat, nbands, ikpt, psize, phase, matin_r, matout_r)
     890             :       use m_types_fleurinput
     891             :       USE m_types_mpdata
     892             :       USE m_types_hybdat
     893             :       use m_constants
     894             :       use m_judft
     895             :       implicit none
     896             :       type(t_fleurinput), intent(in)    :: fi
     897             :       type(t_mpdata), intent(in)        :: mpdata
     898             :       TYPE(t_hybdat), INTENT(IN)        :: hybdat
     899             :       INTEGER, INTENT(IN)               :: ikpt, nbands, psize
     900             :       REAL, INTENT(IN)                  ::  matin_r(:, :)
     901             :       REAL, INTENT(INOUT)               ::  matout_r(:, :)
     902             :       COMPLEX, INTENT(INOUT)            ::  phase(:, :)
     903             : 
     904          12 :       COMPLEX, ALLOCATABLE    ::  vecin(:, :), vecout(:, :)
     905             :       integer :: ok, i, j, cnt
     906          12 :       integer :: igptm2_list(mpdata%n_g(ikpt))
     907             : 
     908        6136 :       phase = cmplx_0
     909          12 :       call timestart("bra trafo real")
     910             : 
     911          28 :       IF (maxval(fi%hybinp%lcutm1) > fi%atoms%lmaxd) call judft_error('bra_trafo: maxlcutm > atoms%lmaxd')   ! very improbable case
     912          12 :       call find_corresponding_g(fi%sym, fi%kpts, mpdata, ikpt, igptm2_list)
     913             : 
     914             : !     transform back to unsymmetrized product basis in case of inversion symmetry
     915             :       !$OMP parallel default(none) private(i,j, cnt, vecin, vecout, ok) &
     916          12 :       !$OMP shared(nbands, psize, fi, hybdat, mpdata, phase, matin_r, matout_r, ikpt, igptm2_list) 
     917             :       allocate (vecin(size(matin_r, dim=1), 1), vecout(size(matin_r, dim=1), 1),  stat=ok, source=cmplx_0)
     918             :       IF (ok /= 0) call judft_error('bra_trafo: error allocating vecin or vecout')
     919             : 
     920             :       !$OMP do collapse(2)
     921             :       DO i = 1, nbands
     922             :          DO j = 1, psize
     923             :             cnt = (i-1) * psize + j
     924             :             vecin(:,1) = matin_r(:,cnt)
     925             :             CALL desymmetrize(vecin(:hybdat%nbasp, 1), hybdat%nbasp, 1, &
     926             :                               fi%atoms, fi%hybinp%lcutm1, maxval(fi%hybinp%lcutm1), mpdata%num_radbasfn, fi%sym)
     927             : 
     928             :             call bra_trafo_core(1, ikpt, 1, fi%sym, mpdata, &
     929             :                               fi%hybinp, hybdat, fi%kpts, fi%atoms, igptm2_list, vecin(:,1:1), vecout(:,1:1))
     930             : 
     931             :             CALL symmetrize(vecout(:, 1:1), hybdat%nbasm(ikpt), 1, 1, &
     932             :                             fi%atoms, fi%hybinp%lcutm1, maxval(fi%hybinp%lcutm1), mpdata%num_radbasfn, fi%sym)
     933             : 
     934             :             phase(j, i) = commonphase(vecout(:, 1), hybdat%nbasm(ikpt))
     935             :             matout_r(:, cnt) = real(vecout(:, 1)/phase(j, i))
     936             :             IF (any(abs(aimag(vecout(:, 1)/phase(j, i))) > 1e-8)) THEN
     937             :                WRITE (*, *) vecout(:, 1)/phase(j, i)
     938             :                call judft_error('bra_trafo: Residual imaginary part.')
     939             :             END IF
     940             : 
     941             :          END DO
     942             :       END DO
     943             :       !$OMP end do
     944             : 
     945             :       deallocate (vecout, vecin)
     946             :       !$OMP end parallel
     947             : 
     948          12 :       call timestop("bra trafo real")
     949          12 :    end subroutine bra_trafo_real
     950             : 
     951           4 :    subroutine bra_trafo_cmplx(fi, mpdata, hybdat, nbands, ikpt, psize, vecin_c, vecout_c)
     952             :       use m_constants
     953             :       use m_judft
     954             :       use m_types_fleurinput
     955             :       USE m_types_mpdata
     956             :       USE m_types_hybdat
     957             :       implicit none
     958             :       type(t_fleurinput), intent(in)    :: fi
     959             :       type(t_mpdata), intent(in)        :: mpdata
     960             :       TYPE(t_hybdat), INTENT(IN)        :: hybdat
     961             :       INTEGER, INTENT(IN)               :: ikpt, nbands, psize
     962             :       COMPLEX, INTENT(IN)               ::  vecin_c(:, :)
     963             :       COMPLEX, INTENT(INOUT)            ::  vecout_c(:, :)
     964             : 
     965           4 :       integer :: igptm2_list(mpdata%n_g(ikpt))
     966             : 
     967           4 :       call timestart("bra trafo cmplx")
     968             : 
     969          12 :       IF (maxval(fi%hybinp%lcutm1) > fi%atoms%lmaxd) call judft_error('bra_trafo: maxlcutm > fi%atoms%lmaxd')   ! very improbable case
     970           4 :       call find_corresponding_g(fi%sym, fi%kpts, mpdata, ikpt, igptm2_list)
     971             : 
     972           4 :       call bra_trafo_core(nbands, ikpt, psize, fi%sym, mpdata, fi%hybinp, hybdat, fi%kpts, fi%atoms, igptm2_list, vecin_c, vecout_c)
     973             : 
     974           4 :       call timestop("bra trafo cmplx")
     975           4 :    end subroutine bra_trafo_cmplx
     976             : 
     977        4910 :    subroutine bra_trafo_core(nbands, ikpt, psize, sym, &
     978        4910 :                              mpdata, hybinp, hybdat, kpts, atoms, igptm2_list, vecin1, vecout1)
     979             :       use m_constants
     980             :       USE m_types_mpdata
     981             :       USE m_types_hybinp
     982             :       use m_types_hybdat
     983             :       USE m_types_sym
     984             :       USE m_types_kpts
     985             :       USE m_types_atoms
     986             :       implicit none
     987             :       type(t_mpdata), intent(in)  :: mpdata
     988             :       TYPE(t_hybinp), INTENT(IN)  :: hybinp
     989             :       TYPE(t_hybdat), INTENT(IN)  :: hybdat
     990             :       TYPE(t_sym), INTENT(IN)     :: sym
     991             :       TYPE(t_kpts), INTENT(IN)    :: kpts
     992             :       TYPE(t_atoms), INTENT(IN)   :: atoms
     993             :       integer, intent(in)         :: igptm2_list(:)
     994             : 
     995             :       INTEGER, INTENT(IN)      ::  ikpt, nbands, psize
     996             : 
     997             :       COMPLEX, intent(in)     :: vecin1(:, :)
     998             :       complex, intent(inout)  :: vecout1(:, :)
     999             : 
    1000             :       INTEGER                 :: nrkpt, itype, ic, l, n, i, nn, i1, i2, j1, j2
    1001             :       INTEGER                 :: igptm, igptm2, igptp, iiop, inviop
    1002             :       COMPLEX                 :: cexp, cdum
    1003             : 
    1004             :       INTEGER                 :: rrot(3, 3), invrot(3, 3)
    1005       48044 :       INTEGER                 :: pnt(maxval(mpdata%num_radbasfn), 0:maxval(hybinp%lcutm1), atoms%nat)
    1006             :       INTEGER                 :: g(3), g1(3)
    1007             :       REAL                    :: rkpt(3), rkpthlp(3), trans(3)
    1008             :       COMPLEX                 :: dwgn(-maxval(hybinp%lcutm1):maxval(hybinp%lcutm1), &
    1009       35720 :                                       -maxval(hybinp%lcutm1):maxval(hybinp%lcutm1), 0:maxval(hybinp%lcutm1))
    1010             : 
    1011             : !      call timestart("bra_trafo_core")
    1012             : !      call timestart("setup")
    1013        4910 :       IF (kpts%bksym(ikpt) <= sym%nop) THEN
    1014        4910 :          inviop = sym%invtab(kpts%bksym(ikpt))
    1015       63830 :          rrot = transpose(sym%mrot(:, :, sym%invtab(kpts%bksym(ikpt))))
    1016        4910 :          invrot = sym%mrot(:, :, sym%invtab(kpts%bksym(ikpt)))
    1017       19640 :          trans = sym%tau(:, kpts%bksym(ikpt))
    1018             : 
    1019             :          dwgn(-maxval(hybinp%lcutm1):maxval(hybinp%lcutm1), -maxval(hybinp%lcutm1):maxval(hybinp%lcutm1), 0:maxval(hybinp%lcutm1)) &
    1020     2284500 :             = hybinp%d_wgn2(-maxval(hybinp%lcutm1):maxval(hybinp%lcutm1), -maxval(hybinp%lcutm1):maxval(hybinp%lcutm1), 0:maxval(hybinp%lcutm1), inviop)
    1021             : 
    1022             :       ELSE
    1023           0 :          iiop = kpts%bksym(ikpt) - sym%nop
    1024           0 :          inviop = sym%invtab(iiop) + sym%nop
    1025           0 :          rrot = -transpose(sym%mrot(:, :, sym%invtab(iiop)))
    1026             :          invrot = sym%mrot(:, :, sym%invtab(iiop))
    1027           0 :          trans = sym%tau(:, iiop)
    1028             : 
    1029             :          dwgn(-maxval(hybinp%lcutm1):maxval(hybinp%lcutm1), -maxval(hybinp%lcutm1):maxval(hybinp%lcutm1), 0:maxval(hybinp%lcutm1)) &
    1030           0 :             = conjg(hybinp%d_wgn2(-maxval(hybinp%lcutm1):maxval(hybinp%lcutm1), -maxval(hybinp%lcutm1):maxval(hybinp%lcutm1), 0:maxval(hybinp%lcutm1), inviop))
    1031             :       END IF
    1032             : 
    1033      122750 :       rkpt = matmul(rrot, kpts%bkf(:, kpts%bkp(ikpt)))
    1034        4910 :       rkpthlp = rkpt
    1035       19640 :       rkpt = kpts%to_first_bz(rkpt)
    1036       19640 :       g = nint(rkpthlp - rkpt)
    1037             : !      call timestop("setup")
    1038             : 
    1039             :       !test
    1040             : !      call timestart("test")
    1041        4910 :       nrkpt = 0
    1042       27346 :       DO i = 1, kpts%nkptf
    1043      109384 :          IF (maxval(abs(rkpt - kpts%bkf(:, i))) <= 1E-06) THEN
    1044             :             nrkpt = i
    1045             :             EXIT
    1046             :          END IF
    1047             :       END DO
    1048        4910 :       IF (nrkpt /= ikpt) THEN
    1049           0 :          PRINT *, kpts%bkp(ikpt), ikpt
    1050           0 :          PRINT *, kpts%bkf(:, ikpt)
    1051           0 :          PRINT *, kpts%bkf(:, kpts%bkp(ikpt))
    1052           0 :          PRINT *, rkpt
    1053             : 
    1054           0 :          call judft_error('bra_trafo: rotation failed')
    1055             :       END IF
    1056             : !      call timestop("test")
    1057             : 
    1058             : !     Define pointer to first mixed-basis functions (with m = -l)
    1059             : !      call timestart("def pointer to first mpb")
    1060             :       i = 0
    1061       11072 :       do ic = 1, atoms%nat
    1062        6162 :          itype = atoms%itype(ic)
    1063       41882 :          DO l = 0, hybinp%lcutm1(itype)
    1064      269708 :             DO n = 1, mpdata%num_radbasfn(l, itype)
    1065      238898 :                i = i + 1
    1066      269708 :                pnt(n, l, ic) = i
    1067             :             END DO
    1068       36972 :             i = i + mpdata%num_radbasfn(l, itype)*2*l
    1069             :          END DO
    1070             :       END DO
    1071             : !      call timestop("def pointer to first mpb")
    1072             : 
    1073             : !     Multiplication
    1074             :       ! MT
    1075             : !      call timestart("MT part")
    1076       19640 :       cexp = exp(ImagUnit*tpi_const*dot_product(kpts%bkf(:, ikpt) + g, trans(:)))
    1077             :       !$OMP parallel do default(none) private(ic, itype, cdum, l, nn, n, i1, i2, j1, j2, i)&
    1078        4910 :       !$OMP shared(atoms, cexp, hybinp, kpts, mpdata, pnt, dwgn, vecin1, vecout1, ikpt, g, nbands, psize)
    1079             :       do ic = 1, atoms%nat
    1080             :          itype = atoms%itype(ic)
    1081             : 
    1082             :          cdum = cexp*exp(-ImagUnit*tpi_const*dot_product(g, atoms%taual(:, hybinp%map(ic, kpts%bksym(ikpt)))))
    1083             : 
    1084             :          DO l = 0, hybinp%lcutm1(itype)
    1085             :             nn = mpdata%num_radbasfn(l, itype)
    1086             :             DO n = 1, nn
    1087             : 
    1088             :                i1 = pnt(n, l, ic)
    1089             :                i2 = i1 + nn*2*l
    1090             :                j1 = pnt(n, l, hybinp%map(ic, kpts%bksym(ikpt)))
    1091             :                j2 = j1 + nn*2*l
    1092             : 
    1093             :                DO i = 1, nbands*psize
    1094             :                   vecout1(i1:i2:nn, i) = cdum*matmul(vecin1(j1:j2:nn, i), dwgn(-l:l, -l:l, l))
    1095             :                END DO
    1096             :             END DO
    1097             :          END DO
    1098             :       END DO
    1099             :       !$OMP end parallel do
    1100             : !      call timestop("MT part")
    1101             : 
    1102             :       ! PW
    1103             : !      call timestart("PW part")
    1104             :       !$OMP parallel do default(none) private(igptm, igptp, g1, igptm2, i, cdum) &
    1105        4910 :       !$OMP shared(vecout1, vecin1, mpdata, ikpt, igptm2_list, kpts, rrot, g, hybdat, trans, nbands, psize)
    1106             :       DO igptm = 1, mpdata%n_g(kpts%bkp(ikpt))
    1107             :          igptp = mpdata%gptm_ptr(igptm, kpts%bkp(ikpt))
    1108             :          g1 = matmul(rrot, mpdata%g(:, igptp)) + g
    1109             :          igptm2 = igptm2_list(igptm)                 
    1110             : 
    1111             :          cdum = exp(ImagUnit*tpi_const*dot_product(kpts%bkf(:, ikpt) + g1, trans(:)))
    1112             :          vecout1(hybdat%nbasp + igptm, :) = cdum*vecin1(hybdat%nbasp + igptm2, :)
    1113             :       END DO
    1114             :       !$OMP end parallel do
    1115             : !      call timestop("PW part")
    1116             : !      call timestop("bra_trafo_core")
    1117        4910 :    end subroutine bra_trafo_core
    1118             : 
    1119          16 :    subroutine find_corresponding_g(sym, kpts, mpdata, ikpt, igptm2_list)
    1120             :       use m_types_sym
    1121             :       USE m_types_kpts
    1122             :       USE m_types_mpdata
    1123             :       implicit none
    1124             :       type(t_sym), intent(in)    :: sym
    1125             :       type(t_kpts), intent(in)   :: kpts
    1126             :       type(t_mpdata), intent(in) :: mpdata
    1127             :       integer, intent(in)        :: ikpt
    1128             :       integer, intent(inout)     :: igptm2_list(:)
    1129             : 
    1130             :       integer :: igptm, igptp, g1(3), igptm2, i, iiop
    1131             :       integer :: g(3), rrot(3, 3)
    1132             :       REAL    :: rkpt(3), rkpthlp(3)
    1133             : 
    1134          16 :       call timestart("find corresponding g")
    1135          16 :       call timestart("setup")
    1136          16 :       IF (kpts%bksym(ikpt) <= sym%nop) THEN
    1137         208 :          rrot = transpose(sym%mrot(:, :, sym%invtab(kpts%bksym(ikpt))))
    1138             :       ELSE
    1139           0 :          iiop = kpts%bksym(ikpt) - sym%nop
    1140           0 :          rrot = -transpose(sym%mrot(:, :, sym%invtab(iiop)))
    1141             :      END IF
    1142             : 
    1143         400 :       rkpt = matmul(rrot, kpts%bkf(:, kpts%bkp(ikpt)))
    1144          16 :       rkpthlp = rkpt
    1145          64 :       rkpt = kpts%to_first_bz(rkpt)
    1146          64 :       g = nint(rkpthlp - rkpt)
    1147          16 :       call timestop("setup")
    1148             : 
    1149             :       !$OMP parallel do default(none) schedule(dynamic, 10) private(igptm, igptp, g1, igptm2) &
    1150          16 :       !$OMP shared(kpts, mpdata, ikpt, rrot, g, igptm2_list)
    1151             :       do igptm = 1, mpdata%n_g(kpts%bkp(ikpt))
    1152             :          igptp = mpdata%gptm_ptr(igptm, kpts%bkp(ikpt))
    1153             :          g1 = matmul(rrot, mpdata%g(:, igptp)) + g
    1154             : 
    1155             :          igptm2 = 0
    1156             :          DO i = 1, mpdata%n_g(ikpt)
    1157             :             IF (maxval(abs(g1 - mpdata%g(:, mpdata%gptm_ptr(i, ikpt)))) <= 1E-06) THEN
    1158             :                igptm2 = i
    1159             :                EXIT
    1160             :             END IF
    1161             :          END DO
    1162             :          IF (igptm2 == 0) THEN
    1163             :             WRITE (*, *) kpts%bkp(ikpt), ikpt, g1
    1164             :             WRITE (*, *) mpdata%n_g(kpts%bkp(ikpt)), mpdata%n_g(ikpt)
    1165             :             WRITE (*, *)
    1166             :             WRITE (*, *) igptp, mpdata%g(:, igptp)
    1167             :             WRITE (*, *) g
    1168             :             WRITE (*, *) rrot
    1169             :             WRITE (*, *) "Failed tests:", g1
    1170             :             DO i = 1, mpdata%n_g(ikpt)
    1171             :                WRITE (*, *) mpdata%g(:, mpdata%gptm_ptr(i, ikpt))
    1172             :             END DO
    1173             :             call judft_error('bra_trafo: G-point not found in G-point set.')
    1174             :          END IF
    1175             : 
    1176             :          igptm2_list(igptm) = igptm2
    1177             :       enddo
    1178             :       !$OMP end parallel do
    1179          16 :       call timestop("find corresponding g")
    1180          16 :    end subroutine find_corresponding_g
    1181             : 
    1182             :    ! Determines common phase factor (with unit norm)
    1183        5066 :    function commonphase(carr, n) result(cfac)
    1184             :       USE m_juDFT
    1185             :       IMPLICIT NONE
    1186             :       INTEGER, INTENT(IN)      :: n
    1187             :       COMPLEX, INTENT(IN)      :: carr(n)
    1188             :       COMPLEX                  :: cfac
    1189             :       REAL                     :: rdum, rmax
    1190             :       INTEGER                  :: i
    1191             : 
    1192        5066 :       cfac = 0
    1193        5066 :       rmax = 0
    1194       49083 :       DO i = 1, n
    1195       49083 :          rdum = abs(carr(i))
    1196       49083 :          IF (rdum > 1e-6) THEN
    1197        5066 :             cfac = carr(i)/rdum
    1198        5066 :             EXIT
    1199       44017 :          ELSE IF (rdum > rmax) THEN
    1200       17390 :             cfac = carr(i)/rdum
    1201       17390 :             rmax = rdum
    1202             :          END IF
    1203             :       END DO
    1204       33658 :       IF (abs(cfac) < 1e-10 .and. all(abs(carr) > 1e-10)) THEN
    1205           0 :          WRITE (999, *) carr
    1206           0 :          call judft_error('commonphase: Could not determine common phase factor. (Wrote carr to fort.999)')
    1207             :       END IF
    1208        5066 :    END function commonphase
    1209             : 
    1210           0 :    function commonphase_mtx(mtx, dim1, dim2) result(cfac)
    1211             :       implicit none
    1212             : 
    1213             :       COMPLEX, INTENT(IN)      :: mtx(:, :)
    1214             :       integer, intent(in)      :: dim1, dim2
    1215             :       COMPLEX                  :: cfac
    1216             :       REAL                     :: rdum, rmax
    1217             :       INTEGER                  :: i, j
    1218             : 
    1219           0 :       do j = 1, dim2
    1220           0 :          do i = 1, dim1
    1221           0 :             rdum = abs(mtx(i, j))
    1222           0 :             IF (rdum > 1e-6) THEN
    1223           0 :                cfac = mtx(i, j)/rdum
    1224           0 :                EXIT
    1225           0 :             ELSE IF (rdum > rmax) THEN
    1226           0 :                cfac = mtx(i, j)/rdum
    1227           0 :                rmax = rdum
    1228             :             END IF
    1229             :          end do
    1230             :       end do
    1231             : 
    1232           0 :       IF (abs(cfac) < 1e-10 .and. all(abs(mtx(:dim1, :dim2)) > 1e-10)) THEN
    1233           0 :          WRITE (999, *) mtx(:dim1, :dim2)
    1234           0 :          call judft_error('commonphase: Could not determine common phase factor. (Wrote carr to fort.999)')
    1235             :       END IF
    1236           0 :    END function commonphase_mtx
    1237             : 
    1238    14036916 :    SUBROUTINE bramat_trafo(vecin, igptm_in, ikpt0, iop, writevec, pointer, sym, &
    1239       11556 :                            rrot, invrrot, mpdata, hybinp, kpts, maxlcutm, atoms, lcutm, nindxm, maxindxm, &
    1240      104004 :                            dwgn, nbasp, nbasm, vecout, igptm_out)
    1241             : 
    1242             :       USE m_constants
    1243             :       USE m_util
    1244             :       USE m_types_mpdata
    1245             :       USE m_types_hybinp
    1246             :       USE m_types_sym
    1247             :       USE m_types_kpts
    1248             :       USE m_types_atoms
    1249             :       IMPLICIT NONE
    1250             :       type(t_mpdata), intent(in) :: mpdata
    1251             :       TYPE(t_hybinp), INTENT(IN)   :: hybinp
    1252             :       TYPE(t_sym), INTENT(IN)   :: sym
    1253             :       TYPE(t_kpts), INTENT(IN)   :: kpts
    1254             :       TYPE(t_atoms), INTENT(IN)   :: atoms
    1255             : 
    1256             : !     - scalars
    1257             :       INTEGER, INTENT(IN)      ::  ikpt0, igptm_in, iop, maxindxm
    1258             :       INTEGER, INTENT(IN)      ::  maxlcutm
    1259             :       INTEGER, INTENT(IN)      ::  nbasp
    1260             :       LOGICAL, INTENT(IN)      ::  writevec
    1261             :       INTEGER, INTENT(INOUT)   ::  igptm_out
    1262             : !     - arrays -
    1263             :       INTEGER, INTENT(IN)      ::  rrot(:, :), invrrot(:, :)
    1264             :       INTEGER, INTENT(IN)      :: lcutm(atoms%ntype), &
    1265             :                                   nindxm(0:maxlcutm, atoms%ntype)
    1266             :       INTEGER, INTENT(IN)      :: nbasm(:)
    1267             :       INTEGER, INTENT(IN)      ::  pointer( &
    1268             :                                   minval(mpdata%g(1, :)) - 1:maxval(mpdata%g(1, :)) + 1, &
    1269             :                                   minval(mpdata%g(2, :)) - 1:maxval(mpdata%g(2, :)) + 1, &
    1270             :                                   minval(mpdata%g(3, :)) - 1:maxval(mpdata%g(3, :)) + 1)
    1271             : 
    1272             :       COMPLEX, INTENT(IN)      ::  vecin(:)
    1273             :       COMPLEX, INTENT(IN)      ::  dwgn(-maxlcutm:maxlcutm, &
    1274             :                                         -maxlcutm:maxlcutm, &
    1275             :                                         0:maxlcutm)
    1276             :       COMPLEX, INTENT(INOUT)     ::  vecout(maxval(nbasm), 1)
    1277             : 
    1278             : !     - private scalars -
    1279             :       INTEGER                 ::  itype, ieq, ic, l, n, i, nn, i1, i2, j1, j2
    1280             :       INTEGER                 ::  igptm, igptm2, igptp, isym
    1281             :       INTEGER                 ::  ikpt1
    1282             :       LOGICAL                 ::  trs, touch
    1283             :       COMPLEX                 ::  cexp, cdum
    1284             : !     - private arrays -
    1285       11556 :       INTEGER                 ::  pnt(maxindxm, 0:maxlcutm, atoms%nat), g(3), &
    1286      104004 :                                  g1(3), iarr(maxval(mpdata%n_g))
    1287             :       REAL                    ::  rkpt(3), rkpthlp(3), trans(3)
    1288       11556 :       COMPLEX                 ::  vecin1(nbasm(ikpt0))
    1289      104004 :       COMPLEX                 ::  carr(maxval(mpdata%n_g))
    1290             : 
    1291       11556 :       call timestart("bramat_trafo")
    1292     5751064 :       igptm_out = -1; vecout = CMPLX_NOT_INITALIZED; touch = .false.
    1293             : 
    1294       11556 :       IF (iop <= sym%nop) THEN
    1295       10632 :          isym = iop
    1296       10632 :          trs = .false.
    1297       42528 :          trans = sym%tau(:, isym)
    1298             :       ELSE
    1299         924 :          isym = iop - sym%nop
    1300         924 :          trs = .true.
    1301        3696 :          trans = sym%tau(:, isym)
    1302             :       END IF
    1303             : 
    1304      288900 :       rkpthlp = matmul(rrot, kpts%bkf(:, ikpt0))
    1305       11556 :       rkpt = kpts%to_first_bz(rkpthlp)
    1306       46224 :       g = nint(rkpthlp - rkpt)
    1307             :       !
    1308             :       ! determine number of rotated k-point bk(:,ikpt) -> ikpt1
    1309             :       !
    1310       11556 :       call timestart("det. kpoint")
    1311       20108 :       DO i = 1, kpts%nkpt
    1312       80432 :          IF (maxval(abs(rkpt - kpts%bkf(:, i))) <= 1E-06) THEN
    1313             :             ikpt1 = i
    1314             :             EXIT
    1315             :          END IF
    1316             :       END DO
    1317       11556 :       call timestop("det. kpoint")
    1318             : 
    1319       11556 :       call timestart("calc igptm_out")
    1320      896060 :       DO igptm = 1, mpdata%n_g(ikpt1)
    1321      896060 :          igptp = mpdata%gptm_ptr(igptm, ikpt1)
    1322    14336960 :          g1 = matmul(invrrot, mpdata%g(:, igptp) - g)
    1323      896060 :          igptm2 = pointer(g1(1), g1(2), g1(3))
    1324      896060 :          IF (igptm2 == igptm_in) THEN
    1325       11556 :             igptm_out = igptm
    1326       11556 :             touch = .true.
    1327       11556 :             IF (writevec) THEN
    1328       13936 :                cdum = exp(ImagUnit*tpi_const*dot_product(kpts%bkf(:, ikpt1) + mpdata%g(:, igptp), trans))
    1329             :                EXIT
    1330             :             ELSE
    1331        8072 :                call timestop("calc igptm_out")
    1332        8072 :                call timestop("bramat_trafo")
    1333             :                RETURN
    1334             :             END IF
    1335             :          END IF
    1336             :       END DO
    1337        3484 :       call timestop("calc igptm_out")
    1338             : 
    1339        3484 :       if (.not. touch) call judft_error("g-point could not be found.")
    1340             : !     Transform back to unsymmetrized product basis in case of inversion symmetry.
    1341             : 
    1342        3484 :       call timestart("desymm")
    1343     1713832 :       vecout(:nbasm(ikpt0), 1) = vecin(:nbasm(ikpt0))
    1344        3484 :       if (sym%invs) CALL desymmetrize(vecout, nbasp, 1, &
    1345        2420 :                                       atoms, lcutm, maxlcutm, nindxm, sym)
    1346        3484 :       call timestop("desymm")
    1347             : 
    1348             : !     Right-multiplication
    1349             :       ! PW
    1350        3484 :       call timestart("right-multiply")
    1351      174232 :       IF (trs) THEN; vecin1(:nbasm(ikpt0)) = cdum*conjg(vecout(:nbasm(ikpt0), 1))
    1352     1542760 :       ELSE; vecin1(:nbasm(ikpt0)) = cdum*vecout(:nbasm(ikpt0), 1)
    1353             :       END IF
    1354        3484 :       call timestop("right-multiply")
    1355             : 
    1356             : !     Define pointer to first mixed-basis functions (with m = -l)
    1357        3484 :       call timestart("def pointer")
    1358        3484 :       i = 0
    1359        3484 :       ic = 0
    1360       10020 :       DO itype = 1, atoms%ntype
    1361       16556 :          DO ieq = 1, atoms%neq(itype)
    1362        6536 :             ic = ic + 1
    1363       45752 :             DO l = 0, lcutm(itype)
    1364      274532 :                DO n = 1, nindxm(l, itype)
    1365      241852 :                   i = i + 1
    1366      274532 :                   pnt(n, l, ic) = i
    1367             :                END DO
    1368       39216 :                i = i + nindxm(l, itype)*2*l
    1369             :             END DO
    1370             :          END DO
    1371             :       END DO
    1372        3484 :       call timestop("def pointer")
    1373             : 
    1374             : !     Left-multiplication
    1375             :       ! MT
    1376        3484 :       call timestart("left multi MT")
    1377       13936 :       cexp = exp(-ImagUnit*tpi_const*dot_product(kpts%bkf(:, ikpt1) + g, trans))
    1378        3484 :       ic = 0
    1379       10020 :       DO itype = 1, atoms%ntype
    1380       16556 :          DO ieq = 1, atoms%neq(itype)
    1381        6536 :             ic = ic + 1
    1382       26144 :             cdum = cexp*exp(ImagUnit*tpi_const*dot_product(g, atoms%taual(:, ic)))
    1383        6536 :             cdum = conjg(cdum)
    1384       45752 :             DO l = 0, lcutm(itype)
    1385       32680 :                nn = nindxm(l, itype)
    1386      281068 :                DO n = 1, nn
    1387             : 
    1388      241852 :                   i1 = pnt(n, l, ic)
    1389      241852 :                   i2 = i1 + nn*2*l
    1390      241852 :                   j1 = pnt(n, l, hybinp%map(ic, sym%invtab(isym)))
    1391      241852 :                   j2 = j1 + nn*2*l
    1392             : 
    1393    10568468 :                   vecout(i1:i2:nn, 1) = cdum*matmul(dwgn(-l:l, -l:l, l), vecin1(j1:j2:nn))
    1394             : 
    1395             :                END DO
    1396             :             END DO
    1397             :          END DO
    1398             :       END DO
    1399        3484 :       call timestop("left multi MT")
    1400             : 
    1401             :       ! PW
    1402        3484 :       call timestart("left multi pw")
    1403      602924 :       DO igptm = 1, mpdata%n_g(ikpt1)
    1404      599440 :          igptp = mpdata%gptm_ptr(igptm, ikpt1)
    1405     9591040 :          g1 = matmul(invrrot, mpdata%g(:, igptp) - g)
    1406      599440 :          iarr(igptm) = pointer(g1(1), g1(2), g1(3))
    1407     2401244 :          carr(igptm) = exp(-ImagUnit*tpi_const*dot_product(kpts%bkf(:, ikpt1) + mpdata%g(:, igptp), trans))
    1408             :       END DO
    1409      602924 :       DO i1 = 1, mpdata%n_g(ikpt1)
    1410      602924 :          vecout(nbasp + i1, 1) = carr(i1)*vecin1(nbasp + iarr(i1))
    1411             :       END DO
    1412        3484 :       call timestop("left multi pw")
    1413             : 
    1414             :       ! If inversion symmetry is applicable, symmetrize to make the values real.
    1415        3484 :       call timestart("symmetrize")
    1416        3484 :       if (sym%invs) CALL symmetrize(vecout, nbasp, 1, 1, &
    1417        2420 :                                     atoms, lcutm, maxlcutm, nindxm, sym)
    1418        3484 :       call timestop("symmetrize")
    1419        3484 :       call timestop("bramat_trafo")
    1420             :    END SUBROUTINE bramat_trafo
    1421             : 
    1422     1511224 : END MODULE m_trafo

Generated by: LCOV version 1.14