LCOV - code coverage report
Current view: top level - cdn - pwden.F90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 188 254 74.0 %
Date: 2024-04-25 04:21:55 Functions: 1 1 100.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_pwden
       8             : CONTAINS
       9        7322 :    SUBROUTINE pwden(stars, kpts, banddos,   input, fmpi, noco, nococonv, cell, atoms, sym, &
      10        7322 :                     ikpt, jspin, lapw, ne, ev_list, we, eig, den, results, f_b8, zMat, dos, q_dfpt, lapwq, we1, zMat1, iDir, &
      11             :                     lapwmq,zMat1m)
      12             :       !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      13             :       !     In this subroutine the star function expansion coefficients of
      14             :       !     the plane wave charge density is determined.
      15             :       !
      16             :       !     This subroutine is called for each k-point and each spin.
      17             :       !
      18             :       !
      19             :       !     INPUT:    eigen vectors
      20             :       !               reciprocal lattice information
      21             :       !               Brillouine zone sampling
      22             :       !               FFT information
      23             :       !
      24             :       !     OUTPUT:   den%pw(s)
      25             :       !
      26             :       !                                      Stefan Bl"ugel, JRCAT, Feb. 1997
      27             :       !                                      Gustav Bihlmayer, UniWien
      28             :       !
      29             :       !     In non-collinear calculations the density becomes a hermitian 2x2
      30             :       !     matrix. This subroutine generates this density matrix in the
      31             :       !     interstitial region. The diagonal elements of this matrix
      32             :       !     (n_11 & n_22) are stored in den%pw, while the real and imaginary part
      33             :       !     of the off-diagonal element are store in den%pw(:,3).
      34             :       !
      35             :       !     Philipp Kurz 99/07
      36             :       !
      37             :       !     Subtroutine was refactored in 2020. GM.
      38             :       !
      39             :       !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      40             : 
      41             : !DEC$ NOOPTIMIZE
      42             :       USE m_types
      43             :       USE m_types_dos
      44             :       USE m_constants
      45             :       USE m_forceb8
      46             :       USE m_pwint
      47             :       USE m_juDFT
      48             :       USE m_types_fftGrid
      49             :       USE m_fft_interface
      50             : 
      51             :       IMPLICIT NONE
      52             : 
      53             :       TYPE(t_lapw), INTENT(IN)       :: lapw
      54             :       TYPE(t_mpi), INTENT(IN)        :: fmpi
      55             : 
      56             :       TYPE(t_banddos), INTENT(IN)    :: banddos
      57             :       TYPE(t_input), INTENT(IN)      :: input
      58             :       TYPE(t_noco), INTENT(IN)       :: noco
      59             :       TYPE(t_nococonv),INTENT(IN)    :: nococonv
      60             :       TYPE(t_sym), INTENT(IN)        :: sym
      61             :       TYPE(t_stars), INTENT(IN)      :: stars
      62             :       TYPE(t_cell), INTENT(IN)       :: cell
      63             :       TYPE(t_kpts), INTENT(IN)       :: kpts
      64             :       TYPE(t_atoms), INTENT(IN)      :: atoms
      65             :       TYPE(t_mat), INTENT(IN)        :: zMat
      66             :       TYPE(t_potden), INTENT(INOUT)  :: den
      67             :       TYPE(t_results), INTENT(INOUT) :: results
      68             :       TYPE(t_dos), INTENT(INOUT)     :: dos
      69             : 
      70             :       REAL, INTENT(IN)       :: we(:)  !(nobd)
      71             :       REAL, INTENT(IN)       :: eig(:) !(input%neig)
      72             :       INTEGER, INTENT(IN)    :: ne
      73             :       INTEGER, INTENT(IN)    :: ev_list(ne)
      74             :       INTEGER, INTENT(IN)    :: ikpt
      75             :       INTEGER, INTENT(IN)    :: jspin
      76             :       COMPLEX, INTENT(INOUT) ::  f_b8(3, atoms%ntype)
      77             : 
      78             :       REAL,         OPTIONAL, INTENT(IN) :: q_dfpt(3), we1(:)
      79             :       TYPE(t_mat),  OPTIONAL, INTENT(IN) :: zMat1
      80             :       TYPE(t_lapw), OPTIONAL, INTENT(IN) :: lapwq
      81             :       INTEGER,      OPTIONAL, INTENT(IN) :: iDir
      82             : 
      83             :       TYPE(t_lapw), OPTIONAL, INTENT(IN) :: lapwmq
      84             :       TYPE(t_mat),  OPTIONAL, INTENT(IN) :: zMat1m
      85             : 
      86             :       ! local variables
      87      527184 :       TYPE(t_fftGrid) :: state, stateB, stateq, stateBq, StateDeriv, ekinGrid, chargeDen, rhomatGrid(4), statemq, stateBmq
      88       51254 :       TYPE(t_fftGrid) :: stepFct
      89             :       INTEGER nu, iv, ir, istr, i, j
      90             :       INTEGER idens, ndens, ispin, iGp, iG, gVec(3), gInd
      91             :       REAL q0, q0_11, q0_22, norm, xk(3)
      92             :       REAL s, stateRadius, stateFFTRadius, stateFFTExtendedRadius
      93             :       COMPLEX x
      94             :       REAL, PARAMETER:: tol_3 = 1.0e-3
      95             :       LOGICAL forw, l_dfpt, l_minusq
      96             : 
      97             :       ! local arrays
      98        7322 :       INTEGER, ALLOCATABLE :: stateIndices(:)
      99        7322 :       INTEGER, ALLOCATABLE :: stateBIndices(:)
     100        7322 :       INTEGER, ALLOCATABLE :: stateqIndices(:)
     101        7322 :       INTEGER, ALLOCATABLE :: stateBqIndices(:)
     102        7322 :       INTEGER, ALLOCATABLE :: statemqIndices(:)
     103             :       INTEGER, ALLOCATABLE :: stateBmqIndices(:)
     104        7322 :       INTEGER, ALLOCATABLE :: fieldSphereIndices(:)
     105        7322 :       REAL wtf(ne), wtf1(ne)
     106        7322 :       COMPLEX tempState(lapw%nv(jspin)), starCharges(stars%ng3), z0(lapw%nv(jspin))
     107        7322 :       COMPLEX, ALLOCATABLE :: cwk(:), ecwk(:)
     108             : 
     109             :       ! subroutines
     110             :       REAL dznrm2, dnrm2
     111             : 
     112             :       !------->          ABBREVIATIONS
     113             :       !
     114             :       !     ne    : number of occupied states
     115             :       !     nv    : number of g-components in eigenstate
     116             :       !     cwk   : complex work array: charge density in g-space (as stars)
     117             :       !     den%pw : charge density stored as stars
     118             :       !     we    : weights for the BZ-integration for a particular k-point
     119             :       !     omtil : volume (slab) unit cell, between -.5*D_tilde and +.5*D_tilde
     120             :       !     nstr  : number of members (arms) of reciprocal lattice (g) vector
     121             :       !             of each star.
     122             :       !     ng3_fft: number of stars in the  charge density  FFT-box
     123             :       !     ng3   : number of 3 dim. stars in the charge density sphere defined
     124             :       !             by gmax
     125             : 
     126        7322 :       CALL timestart("pwden")
     127             : 
     128        7322 :       l_dfpt = PRESENT(q_dfpt)
     129             : 
     130        7322 :       l_minusq = PRESENT(lapwmq)
     131             : 
     132     1622775 :       stateRadius = MAXVAL(ABS(lapw%rk(:,:)))
     133       29288 :       stateRadius = stateRadius + SQRT(DOT_PRODUCT(kpts%bk(:,ikpt),kpts%bk(:,ikpt)))
     134        9410 :       IF (noco%l_noco) stateRadius = stateRadius + SQRT(DOT_PRODUCT(nococonv%qss(:),nococonv%qss(:)))
     135        7322 :       IF (l_dfpt) stateRadius = stateRadius + SQRT(DOT_PRODUCT(q_dfpt,q_dfpt))
     136             : 
     137        7322 :       stateFFTRadius = 2.0*stateRadius
     138        7322 :       stateFFTExtendedRadius = 2.0*stateRadius
     139             : 
     140        7322 :       IF (noco%l_noco.OR.noco%l_soc) THEN
     141        1758 :          IF (banddos%dos .OR. banddos%vacdos .OR. input%cdinf.OR.banddos%band) THEN
     142           2 :             stateFFTExtendedRadius = 3.0*stateRadius+0.1
     143           2 :             CALL stepFct%init(cell,sym,stateFFTExtendedRadius+0.001)
     144           2 :             CALL stepFct%putFieldOnGrid(stars, stars%ustep, cell,stateFFTRadius+0.0005)
     145           2 :             CALL stepFct%fillFieldSphereIndexArray(stars, stateFFTRadius+0.0008, fieldSphereIndices)
     146           2 :             CALL fft_interface(3, stepFct%dimensions(:), stepFct%grid, .FALSE., fieldSphereIndices)
     147             :          END IF
     148             :       END IF
     149             : 
     150       29288 :       ALLOCATE (cwk(stars%ng3), ecwk(stars%ng3))
     151             : 
     152        7322 :       IF (noco%l_noco) THEN
     153         696 :          CALL state%init(cell,sym,stateFFTExtendedRadius+0.001)
     154         696 :          CALL stateB%init(cell,sym,stateFFTExtendedRadius+0.001)
     155         696 :          IF (l_dfpt) THEN
     156           0 :             CALL stateq%init(cell,sym,stateFFTExtendedRadius+0.001)
     157           0 :             CALL stateBq%init(cell,sym,stateFFTExtendedRadius+0.001)
     158           0 :             IF (l_minusq) THEN
     159           0 :                CALL statemq%init(cell,sym,stateFFTExtendedRadius+0.001)
     160           0 :                CALL stateBmq%init(cell,sym,stateFFTExtendedRadius+0.001)
     161             :             END IF
     162             :          END IF
     163        3480 :          DO i = 1, 4
     164        2784 :             CALL rhomatGrid(i)%init(cell,sym,stateFFTExtendedRadius+0.001)
     165    13288776 :             rhomatGrid(i)%grid(:) = CMPLX(0.0,0.0)
     166             :          END DO
     167         696 :          CALL rhomatGrid(1)%fillFieldSphereIndexArray(stars, stateFFTRadius+0.0008, fieldSphereIndices)
     168         696 :          IF (noco%l_ss) THEN
     169         102 :             ALLOCATE(stateIndices(lapw%nv(1)))
     170         102 :             ALLOCATE(stateBIndices(lapw%nv(2)))
     171          34 :             CALL state%fillStateIndexArray(lapw,1,stateIndices)
     172          34 :             CALL stateB%fillStateIndexArray(lapw,2,stateBIndices)
     173          34 :             IF (l_dfpt) THEN
     174           0 :                ALLOCATE(stateqIndices(lapwq%nv(1)))
     175           0 :                ALLOCATE(stateBqIndices(lapwq%nv(2)))
     176           0 :                CALL stateq%fillStateIndexArray(lapwq,1,stateqIndices)
     177           0 :                CALL stateBq%fillStateIndexArray(lapwq,2,stateBqIndices)
     178             :             END IF
     179             :          ELSE
     180        1986 :             ALLOCATE(stateIndices(lapw%nv(jspin)))
     181        1324 :             ALLOCATE(stateBIndices(lapw%nv(jspin)))
     182         662 :             CALL state%fillStateIndexArray(lapw,jspin,stateIndices)
     183         662 :             CALL stateB%fillStateIndexArray(lapw,jspin,stateBIndices)
     184         662 :             IF (l_dfpt) THEN
     185           0 :                ALLOCATE(stateqIndices(lapwq%nv(jspin)))
     186           0 :                ALLOCATE(stateBqIndices(lapwq%nv(jspin)))
     187           0 :                CALL stateq%fillStateIndexArray(lapwq,jspin,stateqIndices)
     188           0 :                CALL stateBq%fillStateIndexArray(lapwq,jspin,stateBqIndices)
     189             :             END IF
     190             :          ENDIF
     191             :       ELSE
     192        6626 :          CALL state%init(cell,sym,stateFFTExtendedRadius+0.001)
     193        6626 :          IF (l_dfpt) THEN
     194           0 :             CALL stateq%init(cell,sym,stateFFTExtendedRadius+0.001)
     195           0 :             IF (l_minusq) THEN
     196           0 :                CALL statemq%init(cell,sym,stateFFTExtendedRadius+0.001)
     197             :             END IF
     198             :          END IF
     199        6626 :          CALL chargeDen%init(cell,sym,stateFFTExtendedRadius+0.001)
     200    22130592 :          chargeDen%grid(:) = CMPLX(0.0,0.0)
     201             :          ! TODO: Shouldn't there be a starsq here for DFPT?
     202        6626 :          CALL chargeDen%fillFieldSphereIndexArray(stars, stateFFTRadius+0.0008, fieldSphereIndices)
     203        6626 :          IF (input%l_f) THEN
     204          62 :             CALL stateDeriv%init(cell,sym,stateFFTExtendedRadius+0.001)
     205          62 :             CALL ekinGrid%init(cell,sym,stateFFTExtendedRadius+0.001)
     206      507187 :             ekinGrid%grid(:) = CMPLX(0.0,0.0)
     207             :          END IF
     208       19878 :          ALLOCATE(stateIndices(lapw%nv(jspin)))
     209        6626 :          CALL state%fillStateIndexArray(lapw,jspin,stateIndices)
     210        6626 :          IF (l_dfpt) THEN
     211           0 :             ALLOCATE(stateqIndices(lapwq%nv(jspin)))
     212           0 :             CALL stateq%fillStateIndexArray(lapwq,jspin,stateqIndices)
     213           0 :             IF (l_minusq) THEN
     214           0 :                ALLOCATE(statemqIndices(lapwmq%nv(jspin)))
     215           0 :                CALL statemq%fillStateIndexArray(lapwmq,jspin,statemqIndices)
     216             :             END IF
     217             :          END IF
     218             :       ENDIF
     219             : 
     220           0 :       IF (.NOT.l_dfpt) THEN
     221             :          ! g=0 star: calculate the charge for this k-point and spin
     222             :          !           analytically to test the quality of FFT
     223        7322 :          q0 = 0.0
     224        7322 :          q0_11 = 0.0
     225        7322 :          q0_22 = 0.0
     226        7322 :          IF (noco%l_noco) THEN
     227         696 :             IF (.NOT. zmat%l_real) THEN
     228        9505 :                DO nu = 1, ne
     229        8809 :                   norm = dznrm2(lapw%nv(1),zMat%data_c(1:, nu),1) ! dznrm2 returns the 2-norm of the vector.
     230        8809 :                   q0_11 = q0_11 + we(nu)*norm*norm
     231        8809 :                   norm = dznrm2(lapw%nv(2),zMat%data_c(lapw%nv(1) + atoms%nlotot + 1:, nu),1) ! dznrm2 returns the 2-norm of the vector.
     232        9505 :                   q0_22 = q0_22 + we(nu)*norm*norm
     233             :                ENDDO
     234             :             ENDIF
     235         696 :             q0_11 = q0_11/cell%omtil
     236         696 :             q0_22 = q0_22/cell%omtil
     237             :          ELSE
     238        6626 :             IF (zmat%l_real) THEN
     239       43162 :                DO nu = 1, ne
     240       40172 :                   norm = dnrm2(lapw%nv(jspin),zMat%data_r(:, nu),1) ! dnrm2 returns the 2-norm of the vector.
     241       43162 :                   q0 = q0 + we(nu)*norm*norm
     242             :                ENDDO
     243             :             ELSE
     244       51456 :                DO nu = 1, ne
     245       47820 :                   norm = dznrm2(lapw%nv(jspin),zMat%data_c(:, nu),1) ! dznrm2 returns the 2-norm of the vector.
     246       51456 :                   q0 = q0 + we(nu)*norm*norm
     247             :                ENDDO
     248             :             ENDIF
     249        6626 :             q0 = q0/cell%omtil
     250             :          ENDIF
     251             : 
     252        7322 :          IF ((noco%l_noco).AND.(ikpt.LE.fmpi%isize)) THEN
     253       85894 :             dos%qis = 0.0
     254             :          END IF
     255             :       END IF
     256             : 
     257      104123 :       wtf(:ne) = we(:ne)/cell%omtil
     258        7322 :       IF (l_dfpt) wtf1(:ne) = we1(:ne)/cell%omtil
     259             : 
     260             :       ! LOOP OVER OCCUPIED STATES
     261      104123 :       DO nu = 1, ne
     262             :          
     263             :          ! Do inverse FFT of state and add related charge density to overall charge density on real-space mesh.
     264      104123 :          IF (noco%l_noco) THEN
     265        8809 :             forw = .FALSE.
     266        8809 :             IF (noco%l_ss) THEN
     267         136 :                CALL state%putComplexStateOnGrid(lapw, 1, zMat%data_c(1:lapw%nv(1),nu))
     268         136 :                CALL stateB%putComplexStateOnGrid(lapw, 2, zMat%data_c(lapw%nv(1) + atoms%nlotot+1:lapw%nv(1) + atoms%nlotot+lapw%nv(2),nu))
     269         136 :                IF (l_dfpt) THEN
     270           0 :                   CALL stateq%putComplexStateOnGrid(lapwq, 1, zMat1%data_c(1:lapwq%nv(1),nu))
     271           0 :                   CALL stateBq%putComplexStateOnGrid(lapwq, 2, zMat1%data_c(lapwq%nv(1) + atoms%nlotot+1:lapwq%nv(1) + atoms%nlotot+lapwq%nv(2),nu))
     272             :                END IF
     273             :             ELSE
     274        8673 :                CALL state%putComplexStateOnGrid(lapw, jspin, zMat%data_c(1:lapw%nv(jspin),nu))
     275        8673 :                CALL stateB%putComplexStateOnGrid(lapw, jspin, zMat%data_c(lapw%nv(1) + atoms%nlotot+1:lapw%nv(1) + atoms%nlotot+lapw%nv(jspin),nu))
     276        8673 :                IF (l_dfpt) THEN
     277           0 :                   CALL stateq%putComplexStateOnGrid(lapwq, jspin, zMat1%data_c(1:lapwq%nv(1),nu))
     278           0 :                   CALL stateBq%putComplexStateOnGrid(lapwq, jspin, zMat1%data_c(lapwq%nv(1) + atoms%nlotot+1:lapwq%nv(1) + atoms%nlotot+lapwq%nv(jspin),nu))
     279             :                END IF
     280             :             END IF
     281             : 
     282        8809 :             CALL fft_interface(3, state%dimensions(:), state%grid, forw, stateIndices)
     283        8809 :             CALL fft_interface(3, stateB%dimensions(:), stateB%grid, forw, stateBIndices)
     284        8809 :             IF (l_dfpt) THEN
     285           0 :                CALL fft_interface(3, stateq%dimensions(:), stateq%grid, forw, stateqIndices)
     286           0 :                CALL fft_interface(3, stateBq%dimensions(:), stateBq%grid, forw, stateBqIndices)
     287             :             END IF
     288             : 
     289             :             ! In the non-collinear case rho becomes a hermitian 2x2
     290             :             ! matrix (rhomatGrid).
     291             :             IF (.NOT.l_dfpt) THEN
     292    37617465 :             DO ir = 0, rhomatGrid(1)%gridLength - 1
     293             :                !In this order: rho_11, rho_22, m_x/2, m_y/2
     294    37608656 :                rhomatGrid(1)%grid(ir) = rhomatGrid(1)%grid(ir) + wtf(nu) * ABS(state%grid(ir))**2
     295    37608656 :                rhomatGrid(2)%grid(ir) = rhomatGrid(2)%grid(ir) + wtf(nu) * ABS(stateB%grid(ir))**2
     296    37608656 :                rhomatGrid(3)%grid(ir) = rhomatGrid(3)%grid(ir) + wtf(nu) * (REAL(state%grid(ir))*REAL(stateB%grid(ir)) + AIMAG(state%grid(ir))*AIMAG(stateB%grid(ir)))
     297    37617465 :                rhomatGrid(4)%grid(ir) = rhomatGrid(4)%grid(ir) + wtf(nu) * (REAL(state%grid(ir))*AIMAG(stateB%grid(ir)) - AIMAG(state%grid(ir))*REAL(stateB%grid(ir)))
     298             :             END DO
     299             :             ELSE
     300             :                !TODO: This looks ultra different for DFPT.
     301             :                !TODO: Only touch this once the magic minus is fully consistent.
     302             :             END IF
     303             : 
     304             :             ! In a non-collinear calculation the interstitial charge
     305             :             ! cannot be calculated by a simple substraction if the
     306             :             ! muffin-tin (and vacuum) charge is know, because the
     307             :             ! total charge does not need to be one in each spin-
     308             :             ! channel. Thus it has to be calculated explicitly, if
     309             :             ! it is needed.
     310        8809 :             IF (banddos%dos .OR. banddos%vacdos .OR. input%cdinf.OR.banddos%band) THEN
     311     1029024 :                DO ir = 0, state%gridLength - 1
     312     1029000 :                   state%grid(ir) = ABS(state%grid(ir))**2
     313     1029024 :                   stateB%grid(ir) = ABS(stateB%grid(ir))**2
     314             :                END DO
     315             : 
     316          24 :                forw = .TRUE.
     317          24 :                CALL fft_interface(3, state%dimensions(:), state%grid, forw, fieldSphereIndices)
     318          24 :                CALL fft_interface(3, stateB%dimensions(:), stateB%grid, forw, fieldSphereIndices)
     319             : 
     320          24 :                CALL state%takeFieldFromGrid(stars, cwk, stateFFTRadius+0.0005)
     321      236208 :                DO istr = 1, stars%ng3
     322      236208 :                   cwk(istr) = REAL(stars%nstr(istr))*cwk(istr)
     323             :                END DO
     324       96384 :                DO istr = 1, stars%ng3_fft
     325       96360 :                   CALL pwint(stars, atoms, sym,   cell, istr, x)
     326       96360 :                   dos%qis(ev_list(nu), ikpt, 1) = dos%qis(ev_list(nu), ikpt, 1) + REAL(cwk(istr)*x)/cell%omtil
     327       96384 :                   dos%qTot(ev_list(nu), ikpt, 1) = dos%qTot(ev_list(nu), ikpt, 1) + REAL(cwk(istr)*x)/cell%omtil
     328             :                ENDDO
     329             : 
     330          24 :                CALL stateB%takeFieldFromGrid(stars, cwk, stateFFTRadius+0.0005)
     331      236208 :                DO istr = 1, stars%ng3
     332      236208 :                   cwk(istr) = REAL(stars%nstr(istr))*cwk(istr)
     333             :                END DO
     334       96384 :                DO istr = 1, stars%ng3_fft
     335       96360 :                   CALL pwint(stars, atoms, sym,   cell, istr, x)
     336       96360 :                   dos%qis(ev_list(nu), ikpt, input%jspins) = dos%qis(ev_list(nu), ikpt, input%jspins) + REAL(cwk(istr)*x)/cell%omtil
     337      105169 :                   dos%qTot(ev_list(nu), ikpt, input%jspins) = dos%qTot(ev_list(nu), ikpt, input%jspins) + REAL(cwk(istr)*x)/cell%omtil
     338             :                ENDDO
     339             :             ENDIF
     340             : 
     341             :          ELSE
     342       87992 :             CALL state%putStateOnGrid(lapw, jSpin, zMat, nu)
     343       87992 :             IF (l_dfpt) THEN
     344           0 :                CALL stateq%putStateOnGrid(lapwq, jspin, zMat1, nu)
     345           0 :                IF (l_minusq) THEN
     346           0 :                   CALL statemq%putStateOnGrid(lapwmq, jspin, zMat1m, nu)
     347             :                END IF
     348             :             END IF
     349             : 
     350       87992 :             forw = .FALSE.
     351             :             ! The following FFT is a general complex to complex FFT
     352             :             ! For zmat%l_real this should be turned into a real to real FFT at some point
     353             :             ! Note: For the moment also no zero-indices for SpFFT provided
     354             :             !$acc data copy(state%grid)
     355       87992 :             CALL fft_interface(3, state%dimensions(:), state%grid, forw, stateIndices)
     356             :             !$acc end data
     357       87992 :             IF (l_dfpt) THEN
     358           0 :                CALL fft_interface(3, stateq%dimensions(:), stateq%grid, forw, stateqIndices)
     359           0 :                IF (l_minusq) THEN
     360           0 :                   CALL fft_interface(3, statemq%dimensions(:), statemq%grid, forw, statemqIndices)
     361             :                END IF
     362             :             END IF
     363             :             IF (.NOT.l_dfpt) THEN
     364   302641942 :                DO ir = 0, chargeDen%gridLength - 1
     365   302641942 :                   chargeDen%grid(ir) = chargeDen%grid(ir) + wtf(nu) * ABS(state%grid(ir))**2
     366             :                END DO
     367             :             ELSE
     368           0 :                IF (.NOT.l_minusq) THEN
     369           0 :                   DO ir = 0, chargeDen%gridLength - 1
     370           0 :                      chargeDen%grid(ir) = chargeDen%grid(ir) + wtf(nu) * 2 * CONJG(state%grid(ir)) * stateq%grid(ir)
     371             :                      !chargeDen%grid(ir) = chargeDen%grid(ir) + wtf(nu) * 2 * CONJG(CONJG(state%grid(ir)) * stateq%grid(ir))
     372           0 :                      IF (norm2(q_dfpt)<1e-8) chargeDen%grid(ir) = chargeDen%grid(ir) + wtf1(nu) * ABS(state%grid(ir))**2
     373             :                   END DO
     374             :                ELSE
     375           0 :                   DO ir = 0, chargeDen%gridLength - 1
     376             :                      chargeDen%grid(ir) = chargeDen%grid(ir) + wtf(nu) * (CONJG(statemq%grid(ir)) * state%grid(ir) &
     377           0 :                                                                         + CONJG(state%grid(ir)) * stateq%grid(ir))
     378             :                      !chargeDen%grid(ir) = chargeDen%grid(ir) + wtf(nu) * 2 * CONJG(CONJG(state%grid(ir)) * stateq%grid(ir))
     379           0 :                      IF (norm2(q_dfpt)<1e-8) chargeDen%grid(ir) = chargeDen%grid(ir) + wtf1(nu) * ABS(state%grid(ir))**2
     380             :                   END DO
     381             :                END IF
     382             :             END IF
     383             : 
     384       87992 :             IF (input%l_f) THEN
     385     6998766 :                DO ir = 0, ekinGrid%gridLength - 1
     386     6998766 :                   ekinGrid%grid(ir) = ekinGrid%grid(ir) - wtf(nu) * eig(nu) * ABS(state%grid(ir))**2
     387             :                END DO
     388             : 
     389        1568 :                DO j = 1, 3
     390      917808 :                   DO iv = 1, lapw%nv(jspin)
     391     3666528 :                      xk = lapw%gvec(:, iv, jspin) + lapw%bkpt
     392             :                      s = 0.0
     393     3666528 :                      DO i = 1, 3
     394     3666528 :                         s = s + xk(i)*cell%bmat(i, j)
     395             :                      ENDDO
     396      917808 :                      IF (zmat%l_real) THEN
     397      747558 :                         tempState(iv) = s*zMat%data_r(iv, nu)
     398             :                      ELSE
     399      169074 :                         tempState(iv) = s*zMat%data_c(iv, nu)
     400             :                      END IF
     401             :                   END DO
     402        1176 :                   CALL stateDeriv%putComplexStateOnGrid(lapw, jSpin, tempState)
     403        1176 :                   CALL fft_interface(3, stateDeriv%dimensions(:), stateDeriv%grid, forw, stateIndices)
     404    20996690 :                   DO ir = 0, ekinGrid%gridLength - 1
     405    20996298 :                      ekinGrid%grid(ir) = ekinGrid%grid(ir) + wtf(nu) * 0.5 * ABS(stateDeriv%grid(ir))**2
     406             :                   END DO
     407             :                END DO
     408             :             END IF
     409             : 
     410       87992 :             IF (noco%l_soc.AND.input%jspins.EQ.2) THEN
     411       17556 :                IF (banddos%dos .OR. banddos%vacdos .OR. input%cdinf.OR.banddos%band) THEN
     412           0 :                   DO ir = 0, state%gridLength - 1
     413           0 :                      state%grid(ir) = conjg(state%grid(ir)) * stepFct%grid(ir) * state%grid(ir)
     414             :                   END DO
     415             : 
     416           0 :                   forw = .TRUE.
     417           0 :                   CALL fft_interface(3, state%dimensions(:), state%grid, forw, fieldSphereIndices)
     418             : 
     419           0 :                   cwk = CMPLX(0.0,0.0)
     420           0 :                   CALL state%takeFieldFromGrid(stars, cwk, stateFFTRadius+0.0005)
     421           0 :                   starCharges = CMPLX(0.0,0.0)
     422           0 :                   CALL pwint_all(stars,atoms,sym ,cell,1,stars%ng3,starCharges)
     423           0 :                   starCharges(:) = starCharges(:) * cwk(:) * stars%nstr(:) / cell%omtil
     424           0 :                   dos%qis(ev_list(nu), ikpt, jSpin) = dos%qis(ev_list(nu), ikpt, jSpin) + REAL(SUM(starCharges(:)))
     425           0 :                   dos%qTot(ev_list(nu), ikpt, jSpin) = dos%qTot(ev_list(nu), ikpt, jSpin) + REAL(SUM(starCharges(:)))
     426             :                END IF
     427             :             END IF
     428             :          END IF
     429             :       END DO
     430             :       
     431             :       ! END OUTER LOOP OVER STATES NU
     432             : 
     433             :       ! Perform FFT transform of charge density to reciprocal space.
     434             : 
     435             :       ! In a collinear calculation pwden is called once per spin.
     436             :       ! However in a non-collinear calculation pwden is only called once
     437             :       ! and all four components of the density matrix (n_11 n_22 n_12
     438             :       ! n_21) have to be calculated at once.
     439        7322 :       ndens = 1
     440        7322 :       IF (noco%l_noco) ndens = 4
     441       16732 :       DO idens = 1, ndens
     442        9410 :          forw = .TRUE.
     443        9410 :          IF (noco%l_noco) THEN
     444        2784 :             CALL fft_interface(3, rhomatGrid(idens)%dimensions(:), rhomatGrid(idens)%grid, forw, fieldSphereIndices)
     445             :          ELSE
     446             :             ! The following FFT is a general complex to complex FFT
     447             :             ! For zmat%l_real this should be turned into a real to real FFT at some point
     448             :             ! Note: For the moment also no zero-indices for SpFFT provided
     449        6626 :             CALL fft_interface(3, chargeDen%dimensions(:), chargeDen%grid, forw, fieldSphereIndices)
     450        6626 :             IF (input%l_f) THEN
     451          62 :                CALL fft_interface(3, ekinGrid%dimensions(:), ekinGrid%grid, forw, fieldSphereIndices)
     452             :             END IF
     453             :          ENDIF
     454             : 
     455             :          ! collect stars from the fft-grid
     456    20584172 :          cwk = 0.0
     457    20584172 :          ecwk = 0.0
     458        9410 :          IF (noco%l_noco) THEN
     459        2784 :             CALL rhomatGrid(idens)%takeFieldFromGrid(stars, cwk, stateFFTRadius+0.0005)
     460             :          ELSE
     461             :             ! TODO: Shouldn't there be a starsq here for DFPT?
     462        6626 :             CALL chargeDen%takeFieldFromGrid(stars, cwk, stateFFTRadius+0.0005)
     463        6626 :             IF (input%l_f) THEN
     464          62 :                CALL ekinGrid%takeFieldFromGrid(stars, ecwk, stateFFTRadius+0.0005)
     465             :             END IF
     466             :          ENDIF
     467             : 
     468        9410 :          IF (input%l_useapw) THEN
     469           0 :             IF (input%l_f) THEN
     470           0 :                CALL force_b8(atoms, ecwk, stars, sym, cell, jspin, results%force, f_b8)
     471             :             ENDIF
     472             :          ENDIF
     473             : 
     474        9410 :          IF (.NOT.l_dfpt) THEN
     475             :          ! check charge neutralilty
     476        9410 :          IF ((idens .EQ. 1) .OR. (idens .EQ. 2)) THEN
     477        8018 :             IF (noco%l_noco) THEN
     478        1392 :                IF (idens .EQ. 1) THEN
     479         696 :                   q0 = q0_11
     480             :                ELSE
     481         696 :                   q0 = q0_22
     482             :                ENDIF
     483             :             ENDIF
     484        8018 :             IF (ABS(q0) .GT. 1.0e-9) THEN
     485        7936 :                IF (ABS(q0 - REAL(cwk(1)))/q0 .GT. tol_3) THEN
     486           0 :                   WRITE (99, *) "XX:", ne, lapw%nv
     487           0 :                   IF (zmat%l_real) THEN
     488           0 :                      DO istr = 1, SIZE(zMat%data_r, 2)
     489           0 :                         WRITE (99, *) "X:", istr, zMat%data_r(:, istr)
     490             :                      ENDDO
     491             :                   ELSE
     492           0 :                      DO istr = 1, SIZE(zMat%data_c, 2)
     493           0 :                         WRITE (99, *) "X:", istr, zMat%data_c(:, istr)
     494             :                      ENDDO
     495             :                   ENDIF
     496           0 :                   WRITE (oUnit, '(''bad quality of charge density'',2f13.8)') q0, REAL(cwk(1))
     497           0 :                   CALL juDFT_warn('pwden: bad quality of charge')
     498             :                ENDIF
     499             :             ENDIF
     500             :          ENDIF
     501             :          END IF
     502             : 
     503             :          ! add charge density to existing one
     504       16732 :          IF (idens .LE. 2) THEN
     505             :             ! add to spin-up or -down density (collinear & non-collinear)
     506        8018 :             ispin = jspin
     507        8018 :             IF (noco%l_noco) ispin = idens
     508             :             ! TODO: Shouldn't there be a starsq here for DFPT?
     509     3791476 :             DO istr = 1, stars%ng3_fft
     510     3791476 :                den%pw(istr, ispin) = den%pw(istr, ispin) + cwk(istr)
     511             :             ENDDO
     512        1392 :          ELSE IF (idens .EQ. 3) THEN
     513             :             ! add to off-diag. part of density matrix (only non-collinear)
     514     1040324 :             DO istr = 1, stars%ng3_fft
     515     1040324 :                den%pw(istr, 3) = den%pw(istr, 3) + cwk(istr)
     516             :             ENDDO
     517         696 :             IF (l_dfpt) THEN
     518             :                ! add to other off-diag. part of density matrix (only non-collinear)
     519           0 :                DO istr = 1, stars%ng3_fft
     520           0 :                   den%pw(istr, 4) = den%pw(istr, 4) + cwk(istr)
     521             :                ENDDO
     522             :             END IF
     523             :          ELSE
     524             :             ! add to off-diag. part of density matrix (only non-collinear)
     525     1040324 :             DO istr = 1, stars%ng3_fft
     526     1040324 :                den%pw(istr, 3) = den%pw(istr, 3) - ImagUnit*cwk(istr)
     527             :                ! TODO: This is a magic minus. It should be + ImagUnit*cwk(istr)
     528             :             ENDDO
     529         696 :             IF (l_dfpt) THEN
     530             :                ! TODO: Only touch this once the magic minus is fully consistent.
     531           0 :                DO istr = 1, stars%ng3_fft
     532           0 :                   den%pw(istr, 4) = den%pw(istr, 4) + ImagUnit*cwk(istr)
     533             :                ENDDO
     534             :             END IF
     535             :          ENDIF
     536             :       ENDDO
     537             : 
     538        7322 :       DEALLOCATE (cwk, ecwk)
     539             : 
     540        7322 :       CALL timestop("pwden")
     541             : 
     542        7322 :    END SUBROUTINE pwden
     543             : END MODULE m_pwden

Generated by: LCOV version 1.14