LCOV - code coverage report
Current view: top level - ldaX - slater.f90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 80 82 97.6 %
Date: 2024-05-14 04:27:50 Functions: 1 1 100.0 %

          Line data    Source code
       1             : module m_slater
       2             : 
       3             :    use m_types
       4             :    use m_constants
       5             :    use m_juDFT
       6             :    use m_differ
       7             :    use m_intgr
       8             :    use m_xmlOutput
       9             : 
      10             :    implicit none
      11             : 
      12             : contains
      13         144 :    subroutine slater(input, jspin, atoms, vr, l_write, slater_parameters)
      14             : 
      15             :       ! Calculate the slater integrals for the orbitals specified
      16             :       ! to be corrected with LDA+OP
      17             :       !
      18             :       ! Adapted from core/cored.F90
      19             :       ! Author: Henning Janssen 2021
      20             : 
      21             :       type(t_input),     intent(in) :: input
      22             :       type(t_atoms),     intent(in) :: atoms
      23             :       integer,           intent(in) :: jspin
      24             :       real,              intent(in) :: vr(:, :)
      25             :       logical, optional, intent(in) :: l_write
      26             :       real, allocatable, optional, intent(out) :: slater_parameters(:,:)
      27             : 
      28             :       real    :: eig, fj, fl, fn, t2
      29             :       real    :: d, dxx, rn, rnot, z, t1, rr, r, c
      30             :       integer :: i, n, ncmsh, l, ierr, kk
      31             :       integer :: i_opc, atomType, ipm
      32             : 
      33         144 :       real :: vrd(atoms%msh), f(0:3, 2, atoms%n_opc)
      34         144 :       real :: a(atoms%msh), b(atoms%msh), ain(atoms%msh), ahelp(atoms%msh)
      35             :       real :: lambda
      36             :       character(LEN=20) :: attributes(6)
      37             : 
      38             :       logical :: l_write_arg
      39             : 
      40         144 :       l_write_arg = .false.
      41         144 :       if (present(l_write)) l_write_arg = l_write
      42             : 
      43         144 :       if (l_write_arg) call openXMLElementNoAttributes('slaterIntegrals')
      44             : 
      45         144 :       c = c_light(1.0)
      46             : 
      47         432 :       do i_opc = 1, atoms%n_opc
      48             : 
      49         288 :          l = atoms%lda_opc(i_opc)%l
      50         288 :          n = atoms%lda_opc(i_opc)%n
      51         288 :          atomType = atoms%lda_opc(i_opc)%atomType
      52         288 :          lambda = 0.0  !Set for OPC since it does not matter there
      53             : 
      54         288 :          z = atoms%zatom(atomType)
      55         288 :          dxx = atoms%dx(atomType)
      56         288 :          rnot = atoms%rmsh(1, atomType)
      57         288 :          d = exp(atoms%dx(atomType))
      58         288 :          ncmsh = nint(log((atoms%rmt(atomType) + 10.0)/rnot)/dxx + 1)
      59         288 :          ncmsh = min(ncmsh, atoms%msh)
      60         288 :          rn = rnot*(d**(ncmsh - 1))
      61         288 :          if (l_write_arg) write (oUnit, fmt=8000) z, rnot, dxx, atoms%jri(atomType)
      62      215424 :          vrd(:atoms%jri(atomType)) = vr(:atoms%jri(atomType), atomType)
      63             : 
      64             :          !
      65         288 :          if (input%l_core_confpot) then
      66             :             !--->    linear extension of the potential with slope t1 / a.u.
      67         288 :             t1 = 0.125
      68             :             t1 = max((vrd(atoms%jri(atomType)) - vrd(atoms%jri(atomType) - 1)*d)* &
      69         288 :                      d/(atoms%rmt(atomType)**2*(d - 1)), t1)
      70         288 :             t2 = vrd(atoms%jri(atomType))/atoms%rmt(atomType) - atoms%rmt(atomType)*t1
      71         288 :             rr = atoms%rmt(atomType)
      72             :          else
      73           0 :             t2 = vrd(atoms%jri(atomType))/(atoms%jri(atomType) - ncmsh)
      74             :          end if
      75         288 :          if (atoms%jri(atomType) < ncmsh) then
      76       30816 :             do i = atoms%jri(atomType) + 1, ncmsh
      77       30816 :                if (input%l_core_confpot) then
      78       30528 :                   rr = d*rr
      79       30528 :                   vrd(i) = rr*(t2 + rr*t1)
      80             :                   !               vrd(i) = 2*vrd(jri(jatom)) - rr*( t2 + rr*t1 )
      81             :                else
      82           0 :                   vrd(i) = vrd(atoms%jri(atomType)) + t2*(i - atoms%jri(atomType))
      83             :                end if
      84             :                !
      85             :             end do
      86             :          end if
      87             : 
      88         288 :          fl = real(l)
      89         288 :          fn = real(n)
      90         864 :          do ipm = 1, 2
      91         576 :             fj = fl + (ipm - 1.5)
      92             : 
      93         576 :             eig = -2*(z/(fn + fl))**2
      94         576 :             call differ(fn, fl, fj, c, z, dxx, rnot, rn, d, ncmsh, vrd, eig, a, b, ierr)
      95         576 :             if (l_write_arg) write (oUnit, fmt=8010) fn, fl, fj, eig
      96             : 
      97         576 :             if (ierr /= 0) call juDFT_error("error in slater routine", calledby="slater")
      98             : 
      99        3168 :             do kk = 0, 2*l, 2  ! F0 for s, F0 + F2 for p etc.
     100             :                !lambda = 3.5449*sqrt((l+1.0)/100)     ! screening (TF) sqrt(4pi N(ef))
     101             :                !IF (kk.GT.0) lambda = 2*lambda
     102        1728 :                r = rnot
     103     1475712 :                do i = 1, ncmsh
     104     1473984 :                   ain(i) = a(i)**2*r**(-kk - 1)      ! prepare inner integrand
     105             :                   if (kk == 0) then
     106             :                      ain(i) = ain(i)*exp(-r*lambda)
     107             :                   end if
     108     1475712 :                   r = r*d
     109             :                end do
     110        1728 :                call intgr1(ain, rnot, dxx, ncmsh, ahelp)
     111             : 
     112        1728 :                r = rnot
     113     1473984 :                do i = 1, ncmsh - 1
     114     1472256 :                   ain(i) = a(i)**2*r**kk*(ahelp(ncmsh) - ahelp(i))
     115             :                   if (kk == 0) then
     116             :                      ain(i) = ain(i)*exp(r*lambda)
     117             :                   end if
     118     1473984 :                   r = r*d
     119             :                end do
     120        2304 :                call intgr0(ain, rnot, dxx, ncmsh - 1, f(kk/2, ipm, i_opc))
     121             :             end do
     122             :          end do
     123        2592 :          f(0:l, :, i_opc) = f(0:l, :, i_opc)*2
     124         288 :          if (l_write_arg) then
     125         144 :             write (oUnit, fmt=8020) n, l, jspin, lambda
     126         576 :             write (oUnit, '(12x,i3,f7.1,4f20.10)') l, fj, (f(kk, 1, i_opc)*hartree_to_ev_const, kk=0, l)
     127         576 :             write (oUnit, '(12x,i3,f7.1,4f20.10)') l, fj, (f(kk, 2, i_opc)*hartree_to_ev_const, kk=0, l)
     128             :          end if
     129             : 
     130         144 :          if (l_write_arg) then
     131        1008 :             attributes = ''
     132         144 :             write (attributes(1), '(i0)') atomType
     133         144 :             write (attributes(2), '(i0)') nint(z)
     134         144 :             write (attributes(3), '(i0)') jspin
     135         144 :             write (attributes(4), '(i0)') l
     136         144 :             write (attributes(5), '(i0)') n
     137         144 :             write (attributes(6), '(f10.7)') lambda
     138             :             call openXMLElementForm('slaterIntegral', (/'atomType     ', 'atomicNumber ', 'spin         ', 'l            ', &
     139             :                                                         'n            ', 'screening    '/), &
     140        1008 :                                     attributes, reshape((/8, 12, 4, 1, 1, 9, 6, 3, 1, 1, 1, 18/), (/6, 2/)))
     141         432 :             do ipm = 1, 2
     142         288 :                fj = fl + (ipm - 1.5)
     143        2016 :                attributes = ''
     144         288 :                write (attributes(1), '(i0)') n
     145         288 :                write (attributes(2), '(i0)') nint(fl)
     146         288 :                write (attributes(3), '(f4.1)') fj
     147         288 :                write (attributes(4), '(a)') 'eV'
     148             :                call writeXMLElementPoly('state', (/'n    ', 'l    ', 'j    ','units'/), &
     149        2736 :                                         attributes(1:4), contentList=f(0:l, ipm, i_opc)*hartree_to_ev_const)
     150             :             end do
     151         144 :             call closeXMLElement('slaterIntegral')
     152             :          end if
     153             :       end do
     154             : 
     155         144 :       if (l_write_arg) call closeXMLElement('slaterIntegrals')
     156             : 
     157         144 :       if (present(slater_parameters)) then
     158        1248 :          allocate(slater_parameters(0:lmaxU_const,atoms%n_opc), source=0.0)
     159         288 :          do i_opc = 1, atoms%n_opc
     160         192 :             l = atoms%lda_opc(i_opc)%l
     161             :          !Is simply averaging the right approach??
     162         864 :             slater_parameters(0:l, i_opc) =  (f(0:l,1,i_opc) + f(0:l,2,i_opc))/2.0
     163             :          enddo
     164             :       endif
     165             : 
     166             : 8000  format(/, /, 10x, 'z=', f4.0, 5x, 'r(1)=', e14.6, 5x, 'dx=', f9.6, 5x,&
     167             :           &       'm.t.index=', i4, /, 15x, 'n', 4x, 'l', 5x, 'j', 4x, 'energy')
     168             : 8010  format(12x, 2f5.0, f6.1, f10.4, f12.4)
     169             : 8020  format(/, /, 10x, 'Slater integrals: n=', i2, 5x, 'l=', i2, 5x, 'spin=', i2, 5x, 'screening=', f9.6, 5x,&
     170             :           &       /, 14x, 'l', 4x, 'j', 9x, 'F(0,2,4,6)')
     171         144 :    end subroutine slater
     172             : end module m_slater

Generated by: LCOV version 1.14