LCOV - code coverage report
Current view: top level - ldaX - crystalfield.F90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 0 61 0.0 %
Date: 2024-05-15 04:28:08 Functions: 0 1 0.0 %

          Line data    Source code
       1             : MODULE m_crystalfield
       2             : 
       3             :    !------------------------------------------------------------------------------
       4             :    !
       5             :    ! MODULE: m_crystalfield
       6             :    !
       7             :    !> @author
       8             :    !> Henning Janßen
       9             :    !
      10             :    ! DESCRIPTION:
      11             :    !>       -calculates the crystal-field-contrbution for the local hamiltonian
      12             :    !
      13             :    !------------------------------------------------------------------------------
      14             :    USE m_juDFT
      15             :    USE m_types
      16             :    USE m_constants
      17             :    USE m_trapz
      18             :    USE m_sgml
      19             :    USE m_rotMMPmat
      20             : 
      21             :    IMPLICIT NONE
      22             : 
      23             :    CONTAINS
      24             : 
      25           0 :    SUBROUTINE crystal_field(atoms,gfinp,input,noco,nococonv,greensfImagPart,v,ef,hub1data)
      26             : 
      27             :       !calculates the crystal-field matrix for the local hamiltonian
      28             : 
      29             :       TYPE(t_greensfImagPart),   INTENT(IN)    :: greensfImagPart
      30             :       TYPE(t_atoms),             INTENT(IN)    :: atoms
      31             :       TYPE(t_gfinp),             INTENT(IN)    :: gfinp
      32             :       TYPE(t_input),             INTENT(IN)    :: input
      33             :       TYPE(t_noco),              INTENT(IN)    :: noco
      34             :       TYPE(t_nococonv),          INTENT(IN)    :: nococonv
      35             :       TYPE(t_potden),            INTENT(IN)    :: v !LDA+U potential (should be removed from h_loc)
      36             :       REAL,                      INTENT(IN)    :: ef
      37             :       TYPE(t_hub1data),          INTENT(INOUT) :: hub1data
      38             : 
      39             :       !-Local Scalars
      40             :       INTEGER i_gf,l,nType,jspin,m,mp,ie,i_hia,i_u,isp,i_elem
      41             :       REAL    tr,del,eb
      42             :       COMPLEX vso
      43             :       LOGICAL, PARAMETER :: l_correctMinus = .FALSE.
      44             :       REAL, PARAMETER :: excTolerance = 0.2/hartree_to_ev_const
      45             :       !-Local Arrays
      46           0 :       REAL :: h_loc(-lmaxU_const:lmaxU_const,-lmaxU_const:lmaxU_const,atoms%n_hia,input%jspins)
      47             :       REAL :: ex(-lmaxU_const:lmaxU_const,-lmaxU_const:lmaxU_const)
      48             :       REAL :: shift(-lmaxU_const:lmaxU_const,-lmaxU_const:lmaxU_const)
      49           0 :       REAL :: integrand(gfinp%ne), norm(gfinp%ne)
      50           0 :       COMPLEX, ALLOCATABLE :: imag(:,:,:)
      51           0 :       COMPLEX, ALLOCATABLE :: potmmpmat(:,:,:)
      52             : 
      53             : 
      54           0 :       ALLOCATE(potmmpmat(-lmaxU_const:lmaxU_const, -lmaxU_const:lmaxU_const, input%jspins))
      55           0 :       ALLOCATE(imag(gfinp%ne,-lmaxU_const:lmaxU_const, -lmaxU_const:lmaxU_const),source=cmplx_0)
      56             : 
      57           0 :       h_loc = 0.0
      58           0 :       DO i_hia = 1, atoms%n_hia
      59             : 
      60           0 :          l     = atoms%lda_u(atoms%n_u+i_hia)%l
      61           0 :          nType = atoms%lda_u(atoms%n_u+i_hia)%atomType
      62             : 
      63           0 :          i_gf = gfinp%hiaElem(i_hia)
      64           0 :          i_elem = gfinp%uniqueElements(atoms,max_index=i_gf,l_sphavg=.TRUE., l_kresolved_int=.false.)
      65             :          !---------------------------------------------------------
      66             :          ! Perform the integration
      67             :          !---------------------------------------------------------
      68             :          ! \int_{E_b}^{E_c} dE E * N_LL'(E)
      69             :          !---------------------------------------------------------
      70             :          ! N_LL' is the l projected density of states and
      71             :          ! connected to the imaginary part of the greens function
      72             :          ! with a factor -1/pi
      73             :          !---------------------------------------------------------
      74           0 :          CALL gfinp%eMesh(ef,del,eb)
      75           0 :          DO jspin = 1, input%jspins
      76             :             !Use the same cutoffs as in the kramer kronigs integration
      77           0 :             norm = 0.0
      78           0 :             imag = greensfImagPart%applyCutoff(i_elem,i_gf,jspin,.TRUE.)/(3.0-input%jspins)
      79           0 :             DO m = -l, l
      80           0 :                DO mp = -l, l
      81           0 :                   integrand = 0.0
      82           0 :                   DO ie = 1, gfinp%ne
      83           0 :                      integrand(ie) = -1.0/pi_const * ((ie-1) * del+eb) * imag(ie,m,mp)
      84           0 :                      IF(m.EQ.mp) norm(ie) = norm(ie) -1.0/pi_const * imag(ie,m,mp)
      85             :                   ENDDO
      86           0 :                   h_loc(m,mp,i_hia,jspin) = trapz(integrand,del,gfinp%ne)
      87             :                ENDDO
      88             :             ENDDO
      89             :          ENDDO
      90             : #ifdef CPP_DEBUG
      91             :          WRITE(*,*) "UP"
      92             :          WRITE(*,"(7f7.3)") h_loc(-3:3,-3:3,i_hia,1)
      93             :          IF(input%jspins.EQ.2) THEN
      94             :             WRITE(*,*) "DOWN"
      95             :             WRITE(*,"(7f7.3)") h_loc(-3:3,-3:3,i_hia,2)
      96             :          ENDIF
      97             : #endif
      98             :          !Remove LDA+U potential
      99           0 :          i_u = atoms%n_u+i_hia !position in the v%mmpmat array
     100             :          !Rotate the occupation matrix into the global frame in real-space
     101           0 :          IF(noco%l_noco) THEN
     102           0 :             potmmpmat = rotMMPmat(v%mmpmat(:,:,i_u,:input%jspins),0.0,-nococonv%beta(nType),-nococonv%alph(nType),l)
     103           0 :          ELSE IF(noco%l_soc) THEN
     104           0 :             potmmpmat = rotMMPmat(v%mmpmat(:,:,i_u,:input%jspins),0.0,-nococonv%theta,-nococonv%phi,l)
     105             :          ENDIF
     106           0 :          DO jspin = 1, input%jspins
     107           0 :             DO m = -l, l
     108           0 :                DO mp = -l, l
     109           0 :                   IF(ABS(potmmpmat(m,mp,jspin)).GT.1e-4) THEN
     110           0 :                      h_loc(m,mp,i_hia,jspin) = h_loc(m,mp,i_hia,jspin) - potmmpmat(m,mp,jspin)
     111             :                   ENDIF
     112             :                ENDDO
     113             :             ENDDO
     114             :          ENDDO
     115           0 :          IF(ABS(hub1data%xi(i_hia)).GT.1e-12) THEN
     116             :             !Remove SOC potential (only spin-diagonal)
     117           0 :             DO jspin = 1, 2
     118           0 :                DO m = -l, l
     119           0 :                   DO mp = -l, l
     120           0 :                      isp = 3-2*jspin !1,-1
     121           0 :                      vso = CMPLX(sgml(l,m,isp,l,mp,isp),0.0)
     122           0 :                      h_loc(m,mp,i_hia,jspin) = h_loc(m,mp,i_hia,jspin) - REAL(vso)/2.0 * hub1data%xi(i_hia)/hartree_to_ev_const
     123             :                   ENDDO
     124             :                ENDDO
     125             :             ENDDO
     126             :          ENDIF
     127             : #ifdef CPP_DEBUG
     128             :          WRITE(*,*) "UP-REMOVED"
     129             :          WRITE(*,"(7f7.3)") h_loc(-3:3,-3:3,i_hia,1)
     130             :          IF(input%jspins.EQ.2) THEN
     131             :             WRITE(*,*) "DOWN-REMOVED"
     132             :             WRITE(*,"(7f7.3)") h_loc(-3:3,-3:3,i_hia,2)
     133             :          ENDIF
     134             : #endif
     135           0 :          IF(input%jspins.EQ.2) THEN
     136             :             ex = 0.0
     137           0 :             DO m= -l, l
     138           0 :                DO mp = -l, l
     139           0 :                   ex(m,mp) = h_loc(m,mp,i_hia,1)-h_loc(m,mp,i_hia,2)
     140             :                ENDDO
     141             :             ENDDO
     142             : #ifdef CPP_DEBUG
     143             :             WRITE(*,*) "Exchange (eV)"
     144             :             WRITE(*,"(7f7.3)") ex(-3:3,-3:3)*hartree_to_ev_const*0.5
     145             : #endif
     146             :             !------------------------------------------------------------------------------------
     147             :             ! If states move close to the cutoff we get some shift in the results on the diagonal
     148             :             ! The reason for this is a bit unclear we remove these results and replace them
     149             :             ! with either the -m or corresponding opposite spin result (only diagonal)
     150             :             !------------------------------------------------------------------------------------
     151             :             !Shift m=0 exchange to 0
     152             :             IF(l_correctMinus)THEN
     153             :                IF(ABS(ex(0,0)).LT.excTolerance) THEN
     154             :                   !There is no big discrepancy between m=0 spin up/down => simply eleminate the exchange
     155             :                   DO m = -l, l
     156             :                      h_loc(m,m,i_hia,1) = h_loc(m,m,i_hia,1) - ex(0,0)/2.0
     157             :                      h_loc(m,m,i_hia,2) = h_loc(m,m,i_hia,2) + ex(0,0)/2.0
     158             :                   ENDDO
     159             :                ELSE
     160             :                   !There is a big discrepancy due to numerical problems => Take the spin up part
     161             :                   h_loc(0,0,i_hia,2) = h_loc(0,0,i_hia,1)
     162             :                ENDIF
     163             : 
     164             :                !Recalculate exchange
     165             :                ex = 0.0
     166             :                DO m= -l, l
     167             :                   DO mp = -l, l
     168             :                      ex(m,mp) = h_loc(m,mp,i_hia,1)-h_loc(m,mp,i_hia,2)
     169             :                   ENDDO
     170             :                ENDDO
     171             : #ifdef CPP_DEBUG
     172             :                WRITE(*,*) "Exchange shifted (eV)"
     173             :                WRITE(*,"(7f7.3)") ex(-3:3,-3:3)*hartree_to_ev_const*0.5
     174             : #endif
     175             :                !Calculate shifts for numerically "troubled" elements
     176             :                shift=0.0
     177             :                DO m = -l, -1
     178             :                   !Normal leftover from SOC+numerical problems
     179             :                   IF(ABS(ex(m,m)).LT.excTolerance) CYCLE
     180             :                   shift(m,m) = ex(m,m) + ex(-m,-m)
     181             :                ENDDO
     182             :                h_loc(:,:,i_hia,2) = h_loc(:,:,i_hia,2) + shift
     183             : 
     184             : #ifdef CPP_DEBUG
     185             :                !Recalculate differences for verification
     186             :                ex = 0.0
     187             :                DO m= -l, l
     188             :                   DO mp = -l, l
     189             :                      ex(m,mp) = h_loc(m,mp,i_hia,1)-h_loc(m,mp,i_hia,2)
     190             :                   ENDDO
     191             :                ENDDO
     192             : 
     193             :                WRITE(*,*) "Exchange after Correction (eV)"
     194             :                WRITE(*,"(7f7.3)") ex(-3:3,-3:3)*hartree_to_ev_const*0.5
     195             : #endif
     196             :             ENDIF
     197             :         ENDIF
     198             : 
     199             :          !Average over spins
     200           0 :          hub1data%ccfmat(i_hia,:,:) = 0.0
     201           0 :          DO m = -l, l
     202           0 :             DO mp = -l, l
     203           0 :                hub1data%ccfmat(i_hia,m,mp) = SUM(h_loc(m,mp,i_hia,:))/2.0
     204             :                !For jspins.EQ.1 we need to take care of the fact that the spin-orbit coupling is opposite in spin 1/2
     205           0 :                IF(input%jspins.EQ.1) hub1data%ccfmat(i_hia,m,mp) = (h_loc(m,mp,i_hia,1)+h_loc(-m,-mp,i_hia,1))/2.0
     206             :             ENDDO
     207             :          ENDDO
     208             : #ifdef CPP_DEBUG
     209             :          WRITE(*,*) "Average"
     210             :          WRITE(*,"(7f7.3)") hub1data%ccfmat(i_hia,-3:3,-3:3)
     211             : #endif
     212             : 
     213             :          !-----------------------------------
     214             :          ! Symmetrize Matrix
     215             :          ! Delta_CF(m,mp) = Delta_CF(-m,-mp)
     216             :          !-----------------------------------
     217           0 :          IF(input%jspins.EQ.2) THEN
     218           0 :             DO m = -l, l
     219           0 :                DO mp = -l, l
     220           0 :                   hub1data%ccfmat(i_hia,m,mp) = (hub1data%ccfmat(i_hia,m,mp)+hub1data%ccfmat(i_hia,-m,-mp))/2.0
     221           0 :                   hub1data%ccfmat(i_hia,-m,-mp) = hub1data%ccfmat(i_hia,m,mp)
     222             :                ENDDO
     223             :             ENDDO
     224             :          ENDIF
     225             : #ifdef CPP_DEBUG
     226             :          WRITE(*,*) "Average symmetrized"
     227             :          WRITE(*,"(7f7.3)") hub1data%ccfmat(i_hia,-3:3,-3:3)
     228             : #endif
     229             : 
     230           0 :          tr = 0.0
     231             :          !calculate the trace
     232           0 :          DO m = -l, l
     233           0 :             tr = tr + hub1data%ccfmat(i_hia,m,m)
     234             :          ENDDO
     235             : #ifdef CPP_DEBUG
     236             :          WRITE(*,*) "TRACE"
     237             :          WRITE(*,"(2f7.3)") tr, tr/(2*l+1)
     238             : #endif
     239             :          !Remove trace
     240           0 :          DO m = -l, l
     241           0 :             hub1data%ccfmat(i_hia,m,m) = hub1data%ccfmat(i_hia,m,m) - tr/(2*l+1)
     242             :          ENDDO
     243             : 
     244             : #ifdef CPP_DEBUG
     245             :          WRITE(*,*) "TRACELESS ccf (eV)"
     246             :          WRITE(*,"(7f7.3)") hub1data%ccfmat(i_hia,-3:3,-3:3)*hartree_to_ev_const
     247             : #endif
     248             :       ENDDO
     249           0 :    END SUBROUTINE crystal_field
     250             : 
     251             : END MODULE m_crystalfield

Generated by: LCOV version 1.14