LCOV - code coverage report
Current view: top level - vgen - vgen_xcpot.F90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 65 68 95.6 %
Date: 2024-04-18 04:21:56 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             : MODULE m_vgen_xcpot
       7             : 
       8             :    USE m_juDFT
       9             : #ifdef CPP_MPI
      10             :    use mpi
      11             : #endif
      12             : 
      13             : CONTAINS
      14             : 
      15         688 :    SUBROUTINE vgen_xcpot(hybdat, input, xcpot,  atoms, sphhar, stars, vacuum, sym, &
      16             :                           cell, fmpi, noco, den, denRot, EnergyDen, vTot, vx, vxc, exc, results, &
      17             :                           den1Rot, den1Rotimag, dfptvTotimag, starsq)
      18             :       !! FLAPW potential generator                           
      19             :       !! Calculates the density-potential integrals needed for the total energy
      20             :       !! TE_VCOUL:   charge density-coulomb potential integral
      21             :       !! TE_VEFF :   charge density-effective potential integral
      22             :       !! TE_EXC  :   charge density-ex-corr.energy density integral
      23             :       !!
      24             :       !! DFPT case: Calculate Vxc1 instead of Vxc. For this we need fxc, the xc Kernel.
      25             :       !! The calculation changes dramatically, so we enter different subroutines for it.
      26             :       !! TODO: They only work for LDA right now. GGA requires some mathematical considerations
      27             :       !! and will have to use grad_rho1 as input as well.
      28             : 
      29             :       USE m_types
      30             :       USE m_constants
      31             :       USE m_intnv
      32             :       USE m_vmt_xc
      33             :       USE m_vvac_xc
      34             :       USE m_vis_xc
      35             :       USE m_checkdopall
      36             :       USE m_cdn_io
      37             :       USE m_convol
      38             :       USE m_intgr
      39             :       USE m_metagga
      40             :       USE m_dfpt_vmt_xc
      41             :       USE m_dfpt_vis_xc
      42             :       USE m_dfpt_vvac_xc
      43             : 
      44             :       IMPLICIT NONE
      45             : 
      46             :       CLASS(t_xcpot), INTENT(IN)                 :: xcpot
      47             :       TYPE(t_hybdat), INTENT(IN)                 :: hybdat
      48             :       TYPE(t_mpi),    INTENT(IN)                 :: fmpi
      49             : 
      50             :       TYPE(t_input),     INTENT(IN)              :: input
      51             :       TYPE(t_vacuum),    INTENT(IN)              :: vacuum
      52             :       TYPE(t_noco),      INTENT(IN)              :: noco
      53             :       TYPE(t_sym),       INTENT(IN)              :: sym
      54             :       TYPE(t_stars),     INTENT(IN)              :: stars
      55             :       TYPE(t_cell),      INTENT(IN)              :: cell
      56             :       TYPE(t_sphhar),    INTENT(IN)              :: sphhar
      57             :       TYPE(t_atoms),     INTENT(IN)              :: atoms
      58             :       TYPE(t_potden),    INTENT(IN)              :: den, denRot, EnergyDen
      59             :       TYPE(t_potden),    INTENT(INOUT)           :: vTot, vx, vxc, exc
      60             :       TYPE(t_results),   INTENT(INOUT), OPTIONAL :: results
      61             :       TYPE(t_potden),    INTENT(IN),    OPTIONAL :: den1Rot, den1Rotimag
      62             :       TYPE(t_potden),    INTENT(INOUT), OPTIONAL :: dfptvTotimag
      63             :       TYPE(t_stars),     INTENT(IN),    OPTIONAL :: starsq
      64             : 
      65             :       ! Local type instances
      66         688 :       TYPE(t_potden)    :: workDen, veff
      67         688 :       Type(t_kinED)     :: kinED
      68         688 :       REAL, ALLOCATABLE :: rhoc(:,:,:),rhoc_vx(:)
      69         688 :       REAL, ALLOCATABLE :: tec(:,:), qintc(:,:)
      70             :       ! Local Scalars
      71             :       INTEGER :: ifftd2, ispin, i, iType
      72             :       REAL    :: dpdot
      73             :       LOGICAL :: l_dfptvgen
      74             : #ifdef CPP_MPI
      75             :       integer:: ierr
      76             : #endif
      77             : 
      78         688 :       l_dfptvgen = PRESENT(starsq)
      79             : 
      80             :       call set_kinED(fmpi, sphhar, atoms, sym,  xcpot, &
      81         688 :       input, noco, stars,vacuum , cell, Den, EnergyDen, vTot,kinED)
      82             : 
      83         688 :       IF (PRESENT(results)) THEN
      84         688 :          CALL veff%init(stars, atoms, sphhar, vacuum, noco, input%jspins, 1)
      85             : #ifndef CPP_OLDINTEL
      86        2752 :          ALLOCATE (veff%pw_w, mold=veff%pw)
      87             : #else
      88             :          ALLOCATE (veff%pw_w(size(veff%pw, 1), size(veff%pw, 2)))
      89             : #endif
      90             :       ENDIF
      91             : 
      92             :       ! exchange correlation potential
      93             : 
      94             :       ! vacuum region
      95         688 :       IF (fmpi%irank == 0) THEN
      96         344 :          IF (input%film) THEN
      97          44 :             CALL timestart("Vxc in vacuum")
      98             : 
      99          44 :             ifftd2 = 9*stars%mx1*stars%mx2
     100             : 
     101          44 :             IF (.NOT. l_dfptvgen) THEN
     102          44 :                CALL vvac_xc(ifftd2, stars, vacuum, noco,   cell, xcpot, input,  Den, vTot, exc)
     103             :             ELSE
     104           0 :                CALL dfpt_vvac_xc(ifftd2,  stars,  starsq,  vacuum,  noco,  cell,denRot, den1Rot, xcpot,  input, vTot)
     105             :             END IF  
     106          44 :             CALL timestop("Vxc in vacuum")
     107             :          END IF
     108             : 
     109             :          ! interstitial region
     110         344 :          CALL timestart("Vxc in interstitial")
     111         344 :          IF (.NOT.l_dfptvgen) THEN
     112         344 :              CALL vis_xc(stars, sym, cell, den, xcpot, input, noco, EnergyDen,kinED, vTot, vx, exc, vxc)
     113             :          ELSE
     114             :              ! TODO: This is different enough to warrant a separate subroutine, right?
     115           0 :              CALL dfpt_vis_xc(stars, starsq, sym, cell, denRot, den1Rot, xcpot, input, vTot)
     116             :          END IF
     117         344 :          CALL timestop("Vxc in interstitial")
     118             :       END IF !irank==0
     119             : 
     120             :       !
     121             :       !     ------------------------------------------
     122             :       !     ----> muffin tin spheres region
     123             : 
     124         688 :       IF (fmpi%irank == 0) THEN
     125         344 :          CALL timestart("Vxc in MT")
     126             :       END IF
     127             : 
     128         688 :       IF (.NOT.l_dfptvgen) THEN
     129             :           CALL vmt_xc(fmpi, sphhar, atoms, den, xcpot, input, sym, &
     130         688 :                       EnergyDen,kinED, noco,vTot, vx, exc, vxc)
     131             :       ELSE
     132           0 :           CALL dfpt_vmt_xc(fmpi,sphhar,atoms,denRot,den1Rot,den1Rotimag,xcpot,input,sym,noco,vTot,dfptvTotimag)
     133             :       END IF
     134             : 
     135             :       ! add MT EXX potential to vr
     136         688 :       IF (fmpi%irank == 0) THEN
     137         344 :          CALL timestop("Vxc in MT")
     138             : 
     139             :          ! check continuity of total potential
     140         344 :          IF (input%vchk) CALL checkDOPAll(input,  sphhar, stars, atoms, sym, vacuum,   cell, vTot, 1)
     141             : 
     142             :          ! TOTAL
     143         344 :          IF (PRESENT(results)) THEN
     144             :             ! CALCULATE THE INTEGRAL OF n1*Veff1 + n2*Veff2
     145             :             ! Veff = Vcoulomb + Vxc
     146         344 :             IF (noco%l_noco) THEN
     147          96 :                workDen = denRot
     148             :             ELSE
     149         248 :                workden = den
     150             :             END IF
     151         344 :             veff = vTot
     152         344 :             IF (xcpot%is_hybrid() .AND. hybdat%l_subvxc) THEN
     153         111 :                DO ispin = 1, input%jspins
     154         111 :                   CALL convol(stars, vx%pw_w(:, ispin), vx%pw(:, ispin))
     155             :                END DO
     156       14414 :                veff%pw = vTot%pw - xcpot%get_exchange_weight()*vx%pw
     157       14414 :                veff%pw_w = vTot%pw_w - xcpot%get_exchange_weight()*vx%pw_w
     158      403578 :                veff%mt = vTot%mt - xcpot%get_exchange_weight()*vx%mt
     159             :             END IF
     160             : 
     161         887 :             DO ispin = 1, input%jspins
     162     1223707 :                DO i = 1, stars%ng3
     163     1222820 :                   vx%pw(i, ispin) = vx%pw(i, ispin)/stars%nstr(i)
     164     1223363 :                   vx%pw_w(i, ispin) = vx%pw_w(i, ispin)/stars%nstr(i)
     165             :                END DO
     166             :             END DO
     167             : 
     168         344 :             results%te_veff = 0.0
     169         887 :             DO ispin = 1, input%jspins
     170         543 :                WRITE (oUnit, FMT=8050) ispin
     171             : 8050           FORMAT(/, 10x, 'density-effective potential integrals for spin ', i2,/)
     172         887 :                CALL int_nv(ispin, stars, vacuum, atoms, sphhar, cell, sym, input,   veff, workden, results%te_veff)
     173             :             END DO
     174             : 
     175         344 :             IF (xcpot%is_hybrid() .AND. hybdat%l_subvxc) THEN
     176             : 
     177         343 :                ALLOCATE(rhoc(atoms%jmtd,atoms%ntype,input%jspins), rhoc_vx(atoms%jmtd))
     178         294 :                ALLOCATE(tec(atoms%ntype,input%jspins),qintc(atoms%ntype,input%jspins))
     179          49 :                CALL readCoreDensity(input,atoms,rhoc,tec,qintc)
     180          49 :                DEALLOCATE(tec,qintc)
     181             : 
     182         111 :                DO ispin = 1, input%jspins
     183         209 :                    DO iType = 1,atoms%ntype
     184             :                       rhoc_vx(:atoms%jri(iType)) = rhoc(:atoms%jri(iType),iType,ispin) * &
     185       76848 :                                                    vx%mt(:atoms%jri(iType),0,iType,ispin) / sfp_const
     186          98 :                       CALL intgr3(rhoc_vx,atoms%rmsh(1,iType),atoms%dx(iType),atoms%jri(iType),dpdot)
     187         160 :                       results%te_veff = results%te_veff + xcpot%get_exchange_weight() * dpdot*atoms%neq(iType)
     188             :                    END DO
     189             :                END DO
     190             : 
     191          49 :                DEALLOCATE(rhoc,rhoc_vx)
     192             : 
     193             :             END IF
     194             : 
     195         344 :             WRITE (oUnit, FMT=8060) results%te_veff
     196             : 8060        FORMAT(/, 10x, 'total density-effective potential integral :', t40, ES20.10)
     197             : 
     198             :             ! CALCULATE THE INTEGRAL OF n*exc
     199             : 
     200             :             ! perform spin summation of charge densities for the calculation of Exc
     201         344 :             CALL workden%sum_both_spin()
     202             : 
     203         344 :             WRITE (oUnit, FMT=8070)
     204             : 8070        FORMAT(/, 10x, 'charge density-energy density integrals',/)
     205             : 
     206         344 :             results%te_exc = 0.0
     207         344 :             CALL int_nv(1, stars, vacuum, atoms, sphhar, cell, sym, input,   exc, workDen, results%te_exc)
     208         344 :             WRITE (oUnit, FMT=8080) results%te_exc
     209             : 
     210             : 8080        FORMAT(/, 10x, 'total charge density-energy density integral :', t40, ES20.10)
     211             :          END IF
     212             :       END IF ! fmpi%irank == 0
     213             : 
     214         688 :    END SUBROUTINE vgen_xcpot
     215             : 
     216             : END MODULE m_vgen_xcpot

Generated by: LCOV version 1.14