!-----------------------------------------------------------------------------------------! ! Copyright (c) 2018 Peter Grünberg Institut, Forschungszentrum Jülich, Germany ! ! This file is part of Jülich KKR code and available as free software under the conditions! ! of the MIT license as expressed in the LICENSE.md file in more detail. ! !-----------------------------------------------------------------------------------------! !------------------------------------------------------------------------------------ !> Summary: Calculation of Coulomb interaction potential in LDA+U relativistic + SOC (new solver) !> Author: N. Long !> Calculation of Coulomb interaction potential in LDA+U relativistic !> + SOC (new solver) !------------------------------------------------------------------------------------ module mod_wmatldausoc use :: mod_datatypes, only: dp private :: dp contains !------------------------------------------------------------------------------- !> Summary: Calculation of Coulomb interaction potential in LDA+U relativistic + SOC (new solver) !> Author: N. Long !> Category: total-energy, potential, lda+u, spin-orbit-coupling, KKRhost !> Deprecated: False !> Calculation of Coulomb interaction potential in LDA+U relativistic !> + SOC (new solver) !> The expression evaluated (array VLDAU) is: !> $$V_{m1,s,m2,s'} =\delta_{ss'} \sum_{s'',m3,m4} U_{m1,m2,m3,m4}n_{m3,s'',m4,s''}-\sum_{m3,m4} U_{m1,m4,m3,m2} n_{m3,s',m4,s} - \left[Ueff(dentot-1/2) - Jeff n_s - 1/2)\right] \delta_{ss'} \delta_{m1,m2}\$$ !------------------------------------------------------------------------------- !> @note For details see H. Ebert at al., Sol. Stat. Comm. 127 (2003) 443 !> @endnote !------------------------------------------------------------------------------- subroutine wmatldausoc(ntldau,itldau,nspin,denmatn,lopt,ueff,jeff,uldau,wldau,eu, & edc,mmaxd,natyp,nspind,lmax) use :: mod_constants use :: mod_datatypes use :: mod_rclm use :: mod_wmatldau, only: rwrite use :: mod_cinit use :: mod_rinit use :: mod_cmatstr implicit none ! .. Input variables integer, intent (in) :: lmax !! Maximum l component in wave function expansion integer, intent (in) :: natyp !! Number of kinds of atoms in unit cell integer, intent (in) :: nspin !! Counter for spin directions integer, intent (in) :: mmaxd !! 2*LMAX+1 integer, intent (in) :: nspind !! KREL+(1-KREL)*(NSPIN+1) integer, intent (in) :: ntldau !! number of atoms on which LDA+U is applied integer, dimension (natyp), intent (in) :: lopt !! angular momentum QNUM for the atoms on which LDA+U should be applied (-1 to switch it OFF) integer, dimension (natyp), intent (in) :: itldau !! integer pointer connecting the NTLDAU atoms to their corresponding index in the unit cell real (kind=dp), dimension (natyp), intent (in) :: ueff !! input U parameter for each atom real (kind=dp), dimension (natyp), intent (in) :: jeff !! input J parameter for each atom ! .. Input/Output variables real (kind=dp), dimension (natyp), intent (inout) :: eu !! Total energy corrections real (kind=dp), dimension (natyp), intent (inout) :: edc !! Double-counting correction real (kind=dp), dimension (mmaxd, mmaxd, nspind, natyp), intent (inout) :: wldau !! potential matrix real (kind=dp), dimension (mmaxd, mmaxd, mmaxd, mmaxd, natyp), intent (in) :: uldau !! calculated Coulomb matrix elements (EREFLDAU) complex (kind=dp), dimension (mmaxd, mmaxd, 2, 2, natyp), intent (inout) :: denmatn ! .. Local variables integer :: iprint integer :: i1, it, is, js, m1, m2, m3, m4, mm, mmax real (kind=dp) :: dentot real (kind=dp) :: factor complex (kind=dp) :: csum, csum2 character (len=15) :: str15 real (kind=dp), dimension (nspind) :: dentots real (kind=dp), dimension (mmaxd, mmaxd, 2, 2) :: denmat complex (kind=dp), dimension (mmaxd, mmaxd, 2, 2) :: vldau ! .. data iprint/1/ data factor/1.e0_dp/ ! if this is 1. then: n*(n-1) in Edc and ! potential ! if this is 0. then: n**2 in Edc and potential write (1337, '(/,79("#"),/,16X,A,/,79("#"))') 'LDA+U: Calculating interaction potential VLDAU' ! ---------------------------------------------------------------------------- do it = 1, ntldau i1 = itldau(it) ! ------------------------------------------------------------------------- if (lopt(i1)>=0) then call rinit(mmaxd*mmaxd*2*2, denmat(1,1,1,1)) mmax = 2*lopt(i1) + 1 write (1337, 100) i1, lopt(i1) ! ---------------------------------------------------------------------- ! Result is in real Ylm basis. ! It must be converted to complex Ylm basis: ! ---------------------------------------------------------------------- if (iprint>1) write (1337, 110) 'Occupation matrix in REAL basis:' ! ---------------------------------------------------------------------- do is = 1, nspin if (iprint>1) then write (str15, '(4X,"> ",A,I1)') 'ISPIN = ', is call cmatstr(str15, 15, denmatn(1,1,is,is,i1), mmaxd, mmax, 0, 0, 0, 1e-8_dp, 1337) end if ! ------------------------------------------------------------------- ! Convert DENMATC and DENMAT to complex spherical harmonics. ! ------------------------------------------------------------------- do js = 1, nspin call rclm(1, lopt(i1), lmax, denmatn(1,1,js,is,i1)) end do ! js end do ! is ! ---------------------------------------------------------------------- if (iprint>1) write (1337, 110) 'Occupation matrix in COMPLEX basis:' dentot = 0.e0_dp ! ---------------------------------------------------------------------- do is = 1, nspin if (iprint>1) then write (str15, '(4X,"> ",A,I1)') 'ISPIN = ', is call cmatstr(str15, 15, denmatn(1,1,is,is,i1), mmaxd, mmax, 0, 0, 0, 1e-8_dp, 1337) end if ! ------------------------------------------------------------------- ! DENMAT is real: (imag(denmatc)) ! ------------------------------------------------------------------- do js = 1, nspin do m2 = 1, mmax do m1 = 1, mmax denmat(m1, m2, js, is) = (denmatn(m1,m2,js,is,i1)) end do end do end do ! js end do ! is ! ---------------------------------------------------------------------- ! 2. Calculate total occupation numbers: ! ntot_s = Sum_m n_{m,s,m,s}, ntot = n_1 + n_2 ! ---------------------------------------------------------------------- do is = 1, nspin dentots(is) = 0.e0_dp do js = 1, nspin do mm = 1, mmax dentots(is) = dentots(is) + denmat(mm, mm, js, is) end do end do ! JS dentot = dentot + dentots(is) end do ! IS ! ---------------------------------------------------------------------- if (iprint>0) then write (1337, 110) 'Occupation matrix (real):' do is = 1, nspin write (1337, 120) is call rwrite(denmat(1,1,is,is), mmaxd, mmax, 1337) write (1337, 130) 'Trace =', dentots(is) end do write (1337, 140) 'Spins sum =', dentot end if ! ---------------------------------------------------------------------- call cinit(mmaxd*mmaxd*2*2, vldau(1,1,1,1)) do is = 1, nspin ! ------------------------------------------------------------------- ! 3. Use density matrix and Coulomb matrix ULDAU to calculate the ! interaction potential VLDAU ! 3a. First part (always diagonal in spin). ! ------------------------------------------------------------------- do m2 = 1, mmax do m1 = 1, mmax csum = czero do m4 = 1, mmax do m3 = 1, mmax csum2 = czero do js = 1, nspin csum2 = csum2 + denmat(m3, m4, js, js) end do csum = csum + uldau(m1, m2, m3, m4, i1)*csum2 end do end do vldau(m1, m2, is, is) = vldau(m1, m2, is, is) + csum end do end do ! ------------------------------------------------------------------- ! 3b. Second part ! ------------------------------------------------------------------- do js = 1, nspin do m2 = 1, mmax do m1 = 1, mmax csum = czero do m4 = 1, mmax do m3 = 1, mmax csum = csum - uldau(m1, m4, m3, m2, i1)*denmat(m3, m4, js, is) end do end do vldau(m1, m2, js, is) = vldau(m1, m2, js, is) + csum end do end do end do ! js ! ------------------------------------------------------------------- ! 3c. Third part (always spin- and m-diagonal). ! ------------------------------------------------------------------- do m1 = 1, mmax vldau(m1, m1, is, is) = vldau(m1, m1, is, is) - ueff(i1)*(dentot-0.5e0_dp*factor) + jeff(i1)*(dentots(is)-0.5e0_dp*factor) end do end do ! IS ! ---------------------------------------------------------------------- ! 4. Calculate total-energy corrections EU and EDC (double-counting). ! Then the correction is EU - EDC. ! L[LDA+U]=E[LDA]+E[U]-E[DC] !> @note: EU,EDC initialised outside the routine ! ---------------------------------------------------------------------- ! Calculate EDC do is = 1, nspin edc(i1) = edc(i1) + jeff(i1)*dentots(is)*(dentots(is)-factor) end do edc(i1) = 0.5e0_dp*(ueff(i1)*dentot*(dentot-1.e0_dp)-edc(i1)) ! Calculate EU do is = 1, nspin do js = 1, nspin do m4 = 1, mmax do m3 = 1, mmax do m2 = 1, mmax do m1 = 1, mmax eu(i1) = eu(i1) + denmat(m1, m2, is, is)*uldau(m1, m2, m3, m4, i1)*denmat(m3, m4, js, js) end do end do end do end do end do end do do is = 1, nspin do js = 1, nspin do m4 = 1, mmax do m3 = 1, mmax do m2 = 1, mmax do m1 = 1, mmax eu(i1) = eu(i1) - denmat(m1, m2, is, js)*uldau(m1, m4, m3, m2, i1)*denmat(m3, m4, js, is) end do end do end do end do end do end do eu(i1) = 0.5e0_dp*eu(i1) ! ---------------------------------------------------------------------- if (iprint>0) write (1337, 110) 'Interaction potential in COMPLEX basis:' ! ---------------------------------------------------------------------- do is = 1, nspin wldau(:, :, is, i1) = 0e0_dp if (iprint>0) then write (str15, '(4X,"> ",A,I1)') 'ISPIN = ', is call cmatstr(str15, 15, vldau(1,1,is,is), mmaxd, mmax, 0, 0, 0, 1e-8_dp, 1337) end if ! ------------------------------------------------------------------- ! 5. Transform VLDAU into real spherical harmonics basis ! ------------------------------------------------------------------- do js = 1, nspin call rclm(2, lopt(i1), lmax, vldau(1,1,js,is)) ! ---------------------------------------------------------------- ! Copy transformed VLDAU to real WLDAU ! Apply damping to the interaction matrix WLDAU ? Here not. ! ---------------------------------------------------------------- do m2 = 1, mmax do m1 = 1, mmax wldau(m1, m2, is, i1) = wldau(m1, m2, is, i1) + real(vldau(m1,m2,js,is)) end do end do end do ! js end do ! is ! ---------------------------------------------------------------------- if (iprint>0) then write (1337, 110) 'Interaction potential in REAL basis:' do is = 1, nspin write (str15, '(4X,"> ",A,I1)') 'ISPIN = ', is call cmatstr(str15, 15, vldau(1,1,is,is), mmaxd, mmax, 0, 0, 0, 1e-8_dp, 1337) end do end if ! ---------------------------------------------------------------------- write (1337, 110) 'Interaction potential (real):' do is = 1, nspin write (1337, 120) is call rwrite(wldau(1,1,is,i1), mmaxd, mmax, 1337) end do write (1337, *) ! ---------------------------------------------------------------------- ! Corrections in total energy: ! Write out corrections on energy: ! E[LDA+U] = E[LDA] + EU - EDC ! ---------------------------------------------------------------------- write (1337, 110) 'Corrections to the total energy:' write (1337, *) write (1337, 130) 'EU =', eu(i1) write (1337, 130) 'Edc =', edc(i1) write (1337, 150) 'E[LDA+U] = E[LDA] + EU - Edc' end if ! ------------------------------------------------------------------------- end do ! I1 = 1,NTLDAU ! ---------------------------------------------------------------------------- 100 format (/, 6x, 65('='), /, 6x, 'Atom :', i3, ' (l =', i2, ')', /, 6x, 18('=')) 110 format (8x, '* ', a) 120 format (/, 15x, '> ISPIN =', i1) 130 format (10x, a, f10.6) 140 format (10x, 21('-'), /, 10x, a, f10.6, /, 10x, 60('-'), /) 150 format (27x, a, /) end subroutine wmatldausoc end module mod_wmatldausoc