LCOV - code coverage report
Current view: top level - greensf - greensfCalcRealPart.F90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 110 151 72.8 %
Date: 2024-05-15 04:28:08 Functions: 2 2 100.0 %

          Line data    Source code
       1             : MODULE m_greensfCalcRealPart
       2             : 
       3             :    !------------------------------------------------------------------------------
       4             :    !
       5             :    ! MODULE: m_greensfCalcRealPart
       6             :    !
       7             :    !> @author
       8             :    !> Henning Janßen
       9             :    !
      10             :    ! DESCRIPTION:
      11             :    !>  This module contains the functions to calculate the imaginary part of the
      12             :    !>  onsite GF with and without radial dependence
      13             :    !>  Further we can transform this imaginary part to obtain the Green's Function
      14             :    !>  using the Kramer Kronig Transformation
      15             :    !
      16             :    !------------------------------------------------------------------------------
      17             : 
      18             :    USE m_juDFT
      19             :    USE m_types
      20             :    USE m_constants
      21             :    USE m_kkintgr
      22             :    USE m_kk_cutoff
      23             : 
      24             :    IMPLICIT NONE
      25             : 
      26             :    private
      27             :    public greensfCalcRealPart
      28             : 
      29             :    CONTAINS
      30             : 
      31          42 :    SUBROUTINE greensfCalcRealPart(atoms,gfinp,sym,input,enpara,noco,kpts,fmpi,ef,greensfImagPart,g)
      32             : 
      33             :       TYPE(t_atoms),             INTENT(IN)     :: atoms
      34             :       TYPE(t_gfinp),             INTENT(IN)     :: gfinp
      35             :       TYPE(t_sym),               INTENT(IN)     :: sym
      36             :       TYPE(t_noco),              INTENT(IN)     :: noco
      37             :       TYPE(t_kpts),              INTENT(IN)     :: kpts
      38             :       TYPE(t_input),             INTENT(IN)     :: input
      39             :       TYPE(t_mpi),               INTENT(IN)     :: fmpi
      40             :       type(t_enpara),            intent(in)     :: enpara
      41             :       REAL,                      INTENT(IN)     :: ef
      42             :       TYPE(t_greensfImagPart),   INTENT(INOUT)  :: greensfImagPart
      43             :       TYPE(t_greensf),           INTENT(INOUT)  :: g(:)
      44             : 
      45             :       INTEGER :: i_gf,i_elem,l,m,mp,indUnique,nLO,iLO,iLOp,i_elemLO
      46             :       INTEGER :: jspin,nspins,ipm,lp,refCutoff
      47             :       INTEGER :: contourShape, iContour
      48             :       INTEGER :: i_gf_start,i_gf_end,spin_start,spin_end
      49             :       INTEGER :: ikpt, ikpt_i, refElem
      50             :       LOGICAL :: l_fixedCutoffset,l_sphavg,l_kresolved_int,l_kresolved
      51             :       REAL    :: del,eb,fixedCutoff,bk(3)
      52          42 :       REAL,    ALLOCATABLE :: eMesh(:)
      53          42 :       COMPLEX, ALLOCATABLE :: gmat(:,:,:),imag(:,:,:)
      54             : 
      55             :       !Get the information on the real axis energy mesh
      56          42 :       CALL gfinp%eMesh(ef,del,eb,eMesh=eMesh)
      57             : 
      58          42 :       nspins = MERGE(3,input%jspins,gfinp%l_mperp)
      59             : 
      60          42 :       IF(fmpi%irank.EQ.0) THEN
      61          21 :          CALL timestart("Green's Function: Integration Cutoff")
      62         530 :          DO i_gf = 1, gfinp%n
      63             : 
      64             :             !Get the information of ith current element
      65         509 :             l  = g(i_gf)%elem%l
      66         509 :             lp = g(i_gf)%elem%lp
      67         509 :             l_sphavg = g(i_gf)%elem%l_sphavg
      68         509 :             l_fixedCutoffset = g(i_gf)%elem%l_fixedCutoffset
      69         509 :             fixedCutoff      = g(i_gf)%elem%fixedCutoff
      70         509 :             refCutoff        = g(i_gf)%elem%refCutoff
      71         509 :             l_kresolved_int = g(i_gf)%elem%l_kresolved_int
      72             : 
      73         509 :             IF(refCutoff /= -1) CYCLE
      74             : 
      75          31 :             IF(l_fixedCutoffset) THEN
      76           0 :                greensfImagPart%kkintgr_cutoff(i_gf,:,1) = 1
      77           0 :                greensfImagPart%kkintgr_cutoff(i_gf,:,2) = INT((fixedCutoff+ef-eb)/del)+1
      78             :                CYCLE
      79             :             ENDIF
      80             : 
      81          52 :             IF(.NOT.gfinp%isUnique(i_gf,distinct_kresolved_int=.TRUE.)) THEN
      82           2 :                indUnique = gfinp%getUniqueElement(i_gf,distinct_kresolved_int=.TRUE.)
      83             :                !This cutoff was already calculated
      84          14 :                greensfImagPart%kkintgr_cutoff(i_gf,:,:) = greensfImagPart%kkintgr_cutoff(indUnique,:,:)
      85             :             ELSE
      86          29 :                i_elem = gfinp%uniqueElements(atoms,max_index=i_gf,l_sphavg=l_sphavg,l_kresolved_int=l_kresolved_int)
      87             :                IF(.not. g(i_gf)%elem%isOffDiag() .and. &
      88          29 :                   .not. has_sclos(g(i_gf)%elem, atoms,enpara) .and. &
      89         478 :                   .not. l_kresolved_int) THEN
      90             :                   !
      91             :                   !Check the integral over the PDOS to define a cutoff for the Kramer-Kronigs-Integration
      92             :                   ! with SCLOs I just use a fixed cutoff or reference otherwise I would need to check whether
      93             :                   ! the SCLO lies in the energy boundary and raise the expected number of states accordingly
      94          26 :                   IF(l_sphavg) THEN
      95             :                      CALL kk_cutoff(greensfImagPart%sphavg(:,:,:,i_elem,:),noco,gfinp%l_mperp,l,input%jspins,&
      96          22 :                                     eMesh,greensfImagPart%kkintgr_cutoff(i_gf,:,:),greensfImagPart%scalingFactorSphavg(i_elem,:))
      97           4 :                   ELSE IF(g(i_gf)%elem%countLOs(atoms)==0) then
      98             :                      !Onsite element with radial dependence
      99             :                      CALL kk_cutoffRadial(greensfImagPart%uu(:,:,:,i_elem,:),greensfImagPart%ud(:,:,:,i_elem,:),&
     100             :                                           greensfImagPart%du(:,:,:,i_elem,:),greensfImagPart%dd(:,:,:,i_elem,:),&
     101             :                                           noco,g(i_gf)%scalarProducts,gfinp%l_mperp,l,input,eMesh,&
     102           2 :                                           greensfImagPart%kkintgr_cutoff(i_gf,:,:),greensfImagPart%scalingFactorRadial(i_elem,:))
     103             :                   ELSE
     104             :                      CALL kk_cutoffRadialLO(greensfImagPart%uu(:,:,:,i_elem,:),greensfImagPart%ud(:,:,:,i_elem,:),&
     105             :                                           greensfImagPart%du(:,:,:,i_elem,:),greensfImagPart%dd(:,:,:,i_elem,:),&
     106             :                                           greensfImagPart%uulo(:,:,:,:,i_elem,:),greensfImagPart%dulo(:,:,:,:,i_elem,:),&
     107             :                                           greensfImagPart%ulou(:,:,:,:,i_elem,:),greensfImagPart%ulod(:,:,:,:,i_elem,:),&
     108             :                                           greensfImagPart%uloulop(:,:,:,:,:,i_elem,:),&
     109             :                                           atoms,noco,g(i_gf)%scalarProducts,gfinp%l_mperp,l,g(i_gf)%elem%atomType,input,eMesh,&
     110           2 :                                           greensfImagPart%kkintgr_cutoff(i_gf,:,:),greensfImagPart%scalingFactorRadial(i_elem,:))
     111             :                   ENDIF
     112             :                ELSE
     113             :                   !For all other elements we just use ef+elup as a hard cutoff
     114           9 :                   greensfImagPart%kkintgr_cutoff(i_gf,:,1) = 1
     115           9 :                   greensfImagPart%kkintgr_cutoff(i_gf,:,2) = gfinp%ne
     116             :                ENDIF
     117             :             ENDIF
     118             : 
     119             :          ENDDO
     120             : 
     121             :          !Getting reference Cutoffs and perform scaling
     122         530 :          DO i_gf = 1, gfinp%n
     123         509 :             refCutoff       = g(i_gf)%elem%refCutoff
     124         509 :             l_kresolved_int = g(i_gf)%elem%l_kresolved_int
     125         509 :             l_sphavg = g(i_gf)%elem%l_sphavg
     126         509 :             i_elem = gfinp%uniqueElements(atoms,max_index=i_gf,l_sphavg=l_sphavg,l_kresolved_int=l_kresolved_int)
     127         509 :             i_elemLO = gfinp%uniqueElements(atoms,max_index=i_gf,l_sphavg=l_sphavg,l_kresolved_int=l_kresolved_int,lo=.TRUE.)
     128         509 :             nLO = g(i_gf)%elem%countLOs(atoms)
     129             : 
     130         509 :             IF(refCutoff/=-1) THEN
     131             :                !Overwrite cutoff with reference from other elements
     132        3346 :                greensfImagPart%kkintgr_cutoff(i_gf,:,:) = greensfImagPart%kkintgr_cutoff(refCutoff,:,:)
     133             :                
     134             :                ! refElem = gfinp%getUniqueElement(refCutoff,distinct_kresolved_int=.TRUE.)
     135             :                ! if (l_sphavg .and. .not. l_kresolved_int) then
     136             :                !    greensfImagPart%scalingFactorSphavg(i_elem,:) = greensfImagPart%scalingFactorSphavg(refElem,:)
     137             :                ! else if(.not.l_sphavg) then
     138             :                !    greensfImagPart%scalingFactorRadial(i_elem,:) = greensfImagPart%scalingFactorRadial(refElem,:)
     139             :                ! else
     140             :                !    greensfImagPart%scalingFactorSphavgKres(i_elem,:) = greensfImagPart%scalingFactorSphavgKres(refElem,:)
     141             :                ! endif
     142             :             ENDIF
     143         509 :             if(.NOT.gfinp%isUnique(i_gf,distinct_kresolved_int=.TRUE.)) cycle
     144         151 :             CALL greensfImagPart%scale(i_elem,i_elemLO,l_sphavg,nLO,k_resolved=l_kresolved_int)
     145             :          ENDDO
     146          21 :          CALL timestop("Green's Function: Integration Cutoff")
     147             :       ENDIF
     148             : 
     149             :       !Broadcast cutoffs and modified imaginary parts
     150          42 :       CALL greensfImagPart%mpi_bc(fmpi%mpi_comm)
     151             : 
     152             :       !Distribute the Calculations
     153          42 :       CALL gfinp%distribute_elements(fmpi%irank, fmpi%isize, nspins, i_gf_start, i_gf_end, spin_start, spin_end)
     154             : 
     155             :       !Initialize kkintgr_module variables
     156         559 :       DO i_gf = i_gf_start, i_gf_end
     157         517 :          IF(i_gf.LT.1 .OR. i_gf.GT.gfinp%n) CYCLE !Make sure to not produce segfaults with mpi
     158         517 :          contourShape = gfinp%contour(g(i_gf)%elem%iContour)%shape
     159             : 
     160         559 :          CALL kkintgr_init(eMesh,g(i_gf)%contour%e,g(i_gf)%elem%iContour,gfinp%numberContours, contourShape, gfinp%additional_smearing)
     161             :       ENDDO
     162             : 
     163         559 :       DO i_gf = i_gf_start, i_gf_end
     164             : 
     165         517 :          IF(i_gf.LT.1 .OR. i_gf.GT.gfinp%n) CYCLE !Make sure to not produce segfaults with mpi
     166             : 
     167             :          !Get the information of ith current element
     168         517 :          l  = g(i_gf)%elem%l
     169         517 :          lp = g(i_gf)%elem%lp
     170         517 :          l_sphavg = g(i_gf)%elem%l_sphavg
     171         517 :          iContour = g(i_gf)%elem%iContour
     172         517 :          nLO = g(i_gf)%elem%countLOs(atoms)
     173         517 :          IF(g(i_gf)%elem%representative_elem > 0) CYCLE
     174         140 :          IF(g(i_gf)%elem%l_kresolved_int) CYCLE
     175             : 
     176         140 :          i_elem = gfinp%uniqueElements(atoms,max_index=i_gf,l_sphavg=l_sphavg,l_kresolved_int=.FALSE.)
     177         140 :          i_elemLO = gfinp%uniqueElements(atoms,max_index=i_gf,l_sphavg=l_sphavg,lo=.TRUE.,l_kresolved_int=.FALSE.)
     178             : 
     179         140 :          CALL timestart("Green's Function: Kramer-Kronigs-Integration")
     180         408 :          DO jspin = spin_start, spin_end
     181         944 :             DO ipm = 1, 2 !upper or lower half of the complex plane (G(E \pm i delta))
     182             : 
     183         804 :                IF(l_sphavg) THEN
     184   183897296 :                   imag = greensfImagPart%applyCutoff(i_elem,i_gf,jspin,l_sphavg)
     185         512 :                   CALL kkintgr(imag,ipm==2,g(i_gf)%gmmpMat(:,:,:,jspin,ipm),iContour)
     186             :                ELSE
     187             :                   ! In the case of radial dependence we perform the kramers-kronig-integration seperately for uu,dd,etc.
     188             :                   ! We can do this because the radial functions are independent of E
     189     6351792 :                   imag = greensfImagPart%applyCutoff(i_elem,i_gf,jspin,l_sphavg,imat=1)
     190          24 :                   CALL kkintgr(imag,ipm==2,g(i_gf)%uu(:,:,:,jspin,ipm),iContour)
     191     6351792 :                   imag = greensfImagPart%applyCutoff(i_elem,i_gf,jspin,l_sphavg,imat=2)
     192          24 :                   CALL kkintgr(imag,ipm==2,g(i_gf)%dd(:,:,:,jspin,ipm),iContour)
     193     6351792 :                   imag = greensfImagPart%applyCutoff(i_elem,i_gf,jspin,l_sphavg,imat=3)
     194          24 :                   CALL kkintgr(imag,ipm==2,g(i_gf)%ud(:,:,:,jspin,ipm),iContour)
     195     6351792 :                   imag = greensfImagPart%applyCutoff(i_elem,i_gf,jspin,l_sphavg,imat=4)
     196          24 :                   CALL kkintgr(imag,ipm==2,g(i_gf)%du(:,:,:,jspin,ipm),iContour)
     197             : 
     198             :                   !KKT for LOs
     199          24 :                   IF(nLO>0) THEN
     200          36 :                      DO iLO = 1, nLO
     201     5293160 :                         imag = greensfImagPart%applyCutoff(i_elemLO,i_gf,jspin,l_sphavg,imat=1,iLO=iLO)
     202          20 :                         CALL kkintgr(imag,ipm==2,g(i_gf)%uulo(:,:,:,iLO,jspin,ipm),iContour)
     203     5293160 :                         imag = greensfImagPart%applyCutoff(i_elemLO,i_gf,jspin,l_sphavg,imat=2,iLO=iLO)
     204          20 :                         CALL kkintgr(imag,ipm==2,g(i_gf)%ulou(:,:,:,iLO,jspin,ipm),iContour)
     205     5293160 :                         imag = greensfImagPart%applyCutoff(i_elemLO,i_gf,jspin,l_sphavg,imat=3,iLO=iLO)
     206          20 :                         CALL kkintgr(imag,ipm==2,g(i_gf)%dulo(:,:,:,iLO,jspin,ipm),iContour)
     207     5293160 :                         imag = greensfImagPart%applyCutoff(i_elemLO,i_gf,jspin,l_sphavg,imat=4,iLO=iLO)
     208          20 :                         CALL kkintgr(imag,ipm==2,g(i_gf)%ulod(:,:,:,iLO,jspin,ipm),iContour)
     209             : 
     210          64 :                         DO iLOp = 1, nLO
     211     7410424 :                            imag = greensfImagPart%applyCutoff(i_elemLO,i_gf,jspin,l_sphavg,iLO=iLO,iLOp=iLop)
     212          48 :                            CALL kkintgr(imag,ipm==2,g(i_gf)%uloulop(:,:,:,iLO,iLOp,jspin,ipm),iContour)
     213             :                         ENDDO
     214             :                      ENDDO
     215             :                   ENDIF
     216             :                ENDIF
     217             :             ENDDO
     218             :          ENDDO
     219         559 :          CALL timestop("Green's Function: Kramer-Kronigs-Integration")
     220             :       ENDDO
     221          42 :       CALL kkintgr_free()
     222             : 
     223        1060 :       IF(ANY(gfinp%elem(:)%l_kresolved_int)) THEN
     224           0 :          CALL gfinp%distribute_elements(fmpi%n_rank, fmpi%n_size, nspins, i_gf_start, i_gf_end, spin_start, spin_end, k_resolved=.TRUE.)
     225             :          !Initialize kkintgr_module variables
     226           0 :          DO i_gf = i_gf_start, i_gf_end
     227           0 :             IF(i_gf.LT.1 .OR. i_gf.GT.gfinp%n) CYCLE !Make sure to not produce segfaults with mpi
     228           0 :             contourShape = gfinp%contour(g(i_gf)%elem%iContour)%shape
     229           0 :             CALL kkintgr_init(eMesh,g(i_gf)%contour%e,g(i_gf)%elem%iContour,gfinp%numberContours, contourShape, gfinp%additional_smearing)
     230             :          ENDDO
     231           0 :          CALL timestart("Green's Function: K-Resolved Kramer-Kronigs-Integration")
     232           0 :          DO ikpt_i = 1, SIZE(fmpi%k_list)
     233           0 :             ikpt = fmpi%k_list(ikpt_i)
     234           0 :             bk = kpts%bk(:,ikpt)
     235           0 :             DO i_gf = i_gf_start, i_gf_end
     236             : 
     237           0 :                IF(i_gf.LT.1 .OR. i_gf.GT.gfinp%n) CYCLE !Make sure to not produce segfaults with mpi
     238             : 
     239             :                !Get the information of ith current element
     240           0 :                l  = g(i_gf)%elem%l
     241           0 :                lp = g(i_gf)%elem%lp
     242           0 :                l_sphavg = g(i_gf)%elem%l_sphavg
     243           0 :                l_kresolved = g(i_gf)%elem%l_kresolved
     244           0 :                iContour = g(i_gf)%elem%iContour
     245           0 :                nLO = g(i_gf)%elem%countLOs(atoms)
     246           0 :                IF(g(i_gf)%elem%representative_elem > 0) CYCLE
     247           0 :                IF(.NOT.g(i_gf)%elem%l_kresolved_int) CYCLE
     248             : 
     249           0 :                i_elem = gfinp%uniqueElements(atoms,max_index=i_gf,l_sphavg=l_sphavg,l_kresolved_int=.TRUE.)
     250           0 :                i_elemLO = gfinp%uniqueElements(atoms,max_index=i_gf,l_sphavg=l_sphavg,lo=.TRUE.,l_kresolved_int=.TRUE.)
     251             : 
     252           0 :                IF(.NOT.l_kresolved) ALLOCATE(gmat(SIZE(g(i_gf)%contour%e),-lmaxU_const:lmaxU_const,-lmaxU_const:lmaxU_const), source=cmplx_0)
     253             : 
     254           0 :                CALL timestart("Green's Function: Kramer-Kronigs-Integration")
     255           0 :                DO jspin = spin_start, spin_end
     256           0 :                   DO ipm = 1, 2 !upper or lower half of the complex plane (G(E \pm i delta))
     257             : 
     258           0 :                      IF(l_sphavg) THEN
     259           0 :                         imag = greensfImagPart%applyCutoff(i_elem,i_gf,jspin,l_sphavg,ikpt=ikpt_i)
     260           0 :                         IF(l_kresolved) THEN
     261           0 :                            CALL kkintgr(imag,ipm==2,g(i_gf)%gmmpMat_k(:,:,:,jspin,ipm,ikpt),iContour)
     262             :                         ELSE
     263           0 :                            CALL kkintgr(imag,ipm==2,gmat,iContour)
     264           0 :                            g(i_gf)%gmmpMat(:,:,:,jspin,ipm) = g(i_gf)%gmmpMat(:,:,:,jspin,ipm) + gmat
     265             :                         ENDIF
     266             :                      ELSE
     267           0 :                         CALL juDFT_error("No Green's function with k-resolution and radial dependence implemented")
     268             :                      ENDIF
     269             : 
     270             :                   ENDDO
     271             :                ENDDO
     272           0 :                CALL timestop("Green's Function: Kramer-Kronigs-Integration")
     273           0 :                IF(.NOT.l_kresolved) DEALLOCATE(gmat)
     274             :             ENDDO
     275             :          ENDDO
     276           0 :          CALL timestop("Green's Function: K-Resolved Kramer-Kronigs-Integration")
     277           0 :          CALL kkintgr_free()
     278             :       ENDIF
     279             : 
     280             : 
     281             : #ifdef CPP_MPI
     282          42 :       CALL timestart("Green's Function: Collect")
     283             :       !Collect all the greensFuntions
     284        1060 :       DO i_gf = 1, gfinp%n
     285        1060 :          CALL g(i_gf)%collect(fmpi%mpi_comm)
     286             :       ENDDO
     287          42 :       CALL timestop("Green's Function: Collect")
     288             : #endif
     289             : 
     290          42 :       IF(fmpi%irank.EQ.0) THEN
     291             :          !perform rotations for intersite elements
     292         530 :          DO i_gf = 1, gfinp%n
     293         509 :             IF(g(i_gf)%elem%representative_elem <= 0) CYCLE
     294         377 :             CALL g(i_gf)%set_gfdata(g(g(i_gf)%elem%representative_elem))
     295         530 :             CALL g(i_gf)%rotate(sym,atoms)
     296             :          ENDDO
     297             :       ENDIF
     298             : 
     299        1060 :       DO i_gf = 1, gfinp%n
     300        1060 :          CALL g(i_gf)%mpi_bc(fmpi%mpi_comm)
     301             :       ENDDO
     302             : 
     303          42 :    END SUBROUTINE greensfCalcRealPart
     304             : 
     305          29 :    logical function has_sclos(elem,atoms, enpara)
     306             : 
     307             :       type(t_gfelementtype), intent(in) :: elem
     308             :       type(t_atoms),         intent(in) :: atoms
     309             :       type(t_enpara),        intent(in) :: enpara
     310             : 
     311             :       integer :: ilo
     312             : 
     313          29 :       has_sclos = .false.
     314          93 :       DO ilo = 1, atoms%nlo(elem%atomType)
     315          64 :          if(atoms%llo(ilo,elem%atomType).NE.elem%l) cycle
     316             :          !Check for HELO (negative energy parameter) and HDLO (eDeriv > 0)
     317          11 :          if(all(enpara%qn_ello(ilo,elem%atomType,:)<0).or.atoms%ulo_der(ilo, elem%atomType)>=1) cycle
     318         154 :          has_sclos = .true.
     319             :       ENDDO
     320             : 
     321          29 :       IF(elem%l.NE.elem%lp.OR.elem%atomType.NE.elem%atomTypep) THEN
     322           0 :          DO ilo = 1, atoms%nlo(elem%atomTypep)
     323           0 :             if(atoms%llo(ilo,elem%atomTypep).NE.elem%lp) cycle
     324             :             !Check for HELO (negative energy parameter) and HDLO (eDeriv > 0)
     325           0 :             if(all(enpara%qn_ello(ilo,elem%atomTypep,:)<0).or.atoms%ulo_der(ilo, elem%atomTypep)>=1) cycle
     326          29 :             has_sclos = .true.
     327             :          ENDDO
     328             :       ENDIF
     329             : 
     330          29 :    end function
     331             : 
     332             : END MODULE m_greensfCalcRealPart

Generated by: LCOV version 1.14