mkxcpe.f90 Source File


Source Code

!-----------------------------------------------------------------------------------------!
! 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: PW91 exchange correlation functional
!> Author: 
!> Exchange correlation potential making use of GGA, the parametrization is given
!> by the PW91 functional
!------------------------------------------------------------------------------------
module mod_mkxcpe
  use :: mod_datatypes, only: dp
  private :: dp

contains

  !-------------------------------------------------------------------------------  
  !> Summary: PW91 exchange correlation functional
  !> Author: 
  !> Category: xc-potential, potential, KKRhost 
  !> Deprecated: False 
  !> Exchange correlation potential making use of GGA, the parametrization is given
  !> by the PW91 functional
  !-------------------------------------------------------------------------------  
  subroutine mkxcpe(nspin,ir,np,l1max,rv,rholm,vxcp,excp,thet,ylm,dylmt1,dylmt2,    &
    dylmf1,dylmf2,dylmtf,drrl,ddrrl,drrul,ddrrul,irmd,lmpotd)
    use :: mod_gxcpt, only: gxcpt
    ! ..
    implicit none
    ! .. Parameters ..
    real (kind=dp), parameter :: eps = 1.0e-12_dp
    integer :: ijd
    parameter (ijd=434)
    ! .. Input variables
    integer, intent(in) :: ir
    integer, intent(in) :: np
    integer, intent(in) :: irmd    !! Maximum number of radial points
    integer, intent(in) :: l1max   !! lmax + 1
    integer, intent(in) :: nspin   !! Counter for spin directions
    integer, intent(in) :: lmpotd  !! (lpot+1)**2
    real (kind=dp), intent(in) :: rv
    real (kind=dp), dimension(ijd), intent(in) :: thet
    real (kind=dp), dimension(ijd, lmpotd), intent(in)  :: ylm !! real spherical harmonic to a given l,m
    real (kind=dp), dimension(irmd, lmpotd), intent(in) :: drrl
    real (kind=dp), dimension(lmpotd, 2), intent(in)    :: rholm !! l,m decomposed charge density
    real (kind=dp), dimension(irmd, lmpotd), intent(in) :: drrul
    real (kind=dp), dimension(irmd, lmpotd), intent(in) :: ddrrl
    real (kind=dp), dimension(irmd, lmpotd), intent(in) :: ddrrul
    real (kind=dp), dimension(ijd, lmpotd), intent(in)  :: dylmf1
    real (kind=dp), dimension(ijd, lmpotd), intent(in)  :: dylmf2
    real (kind=dp), dimension(ijd, lmpotd), intent(in)  :: dylmt1
    real (kind=dp), dimension(ijd, lmpotd), intent(in)  :: dylmt2
    real (kind=dp), dimension(ijd, lmpotd), intent(in)  :: dylmtf
    ! .. In/Out variables
    real (kind=dp), dimension(ijd), intent(inout) :: excp !! XC-energy
    real (kind=dp), dimension(ijd,2), intent(inout) :: vxcp !! XC-potential
    ! ..
    ! .. Local Scalars ..
    real (kind=dp) :: agr, agrd, agru, cedg, cedl, chg, cosx, dagrf, dagrfd, dagrfu
    real (kind=dp) :: dagrr, dagrrd, dagrru, dagrt, dagrtd, dagrtu, ddrr, ddrrd, zta 
    real (kind=dp) :: ddrru, df1, df2, drr, drrd, drru, dt1, dt2, dtf, dzdfs, dzdr
    real (kind=dp) :: dzdtr, etot0, etota0, g2r, g2rd, g2ru, gggr, gggrd, gggru, grf
    real (kind=dp) :: grfd, grfu, grgrd, grgru, grr, grrd, grru, grt, grtd
    real (kind=dp) :: grtu, gzgr, rdspr, ro, rod, rou, rv2, rv3, rvsin1, ry2
    real (kind=dp) :: rylm, sint1, sint2, smag, spi, tant1, vcg1, vcg2, vcl1, vcl2
    real (kind=dp) :: vtot1, vtot2, vtota1, vtota2, vxg1, vxg2, vxl1, vxl2, xedg, xedl
    integer :: idspr, im, ip, l1, ll, lm, nn, nn1
    ! ..
    ! .. Local Arrays ..
    real (kind=dp), dimension(ijd) :: ddry, ddryd, ddryu, drdf, drdfd, drdfu, drdt
    real (kind=dp), dimension(ijd) :: rdf1d, rdf1u, rdf2, rdf2d, rdf2u, rdt1, rdt1d 
    real (kind=dp), dimension(ijd) :: rdt1u, rdt2, rdt2d, rdt2u, rdtf, rdtfd, rdtfu
    real (kind=dp), dimension(ijd) :: ry,  drdtd, drdtu, dry, dryd, dryu, rdf1,ryd, ryu
    ! ..
    ! .. Data statements ..
    data rdspr/9.0e0_dp/
    ! ..
    ! .....------------------------------------------------------------------
    ! rl: charge=sumlm(rl*ylm)
    ! ry=sumlm(ro*ylm), dry=sumlm(drr*ylm), ddry=sumlm(ddrr*ylm),
    ! c    rdt1=sumlm(ro*dylmt1), rdt2=sumlm(ro*dylmt2), ...
    ! c    rdf1=sumlm(ro*dylmf1), rdf2=sumlm(ro*dylmf2), ...
    ! c    rdtf=sumlm(ro*dylmtf), rdf2=sumlm(ro*dylmf2), ...
    ! c    drdt=sumlm(drr*dylmt1),drdf=sumlm(drr*dylmf1),

    ! agr: abs(grad(ro)), g2r: laplacian(ro),
    ! c    gggr: grad(ro)*grad(agr),
    ! c    grgru,d: grad(ro)*grad(rou),for rod., gzgr: grad(zeta)*grad(ro).

    ! dagrr,-t,-f: d(agr)/dr, d(agr)/dth, d(agr)/dfi.
    ! .....------------------------------------------------------------------
    ! if(meshx.ne.IRMD .or. lLMPOTD.ne.LMPOTD .or.
    ! &   mesh.gt.IRMD  .or. l1max.gt.LMPOTD .or. np.gt.IJD) then
    ! write(6,'(/'' meshx.ne.IRMD .or. lLMPOTD.ne.LMPOTD .or. '',
    ! &    ''mesh.gt.IRMD  .or. l1max.gt.LMPOTD .or. np.gt.IJD.''/
    ! &    '' meshx,IRMD,lLMPOTD,LMPOTD,mesh,IRMD,l1max,LMPOTD,np,IJD='',
    ! & 10i4)') meshx,IRMD,lLMPOTD,LMPOTD,mesh,IRMD,l1max,LMPOTD,np,IJD
    ! stop14
    ! endif
    ! heck  ist=mesh
    ! lmax2=lmax*2
    ! llmax2=(lmax2+1)**2
    ! lmax3=lmax*1
    ! llmax3=(lmax3+1)**2

    ! write(6,9030) (ii,drrs(ii,1),ddrrs(ii,1),drrus(ii,1),
    ! &               ddrrus(ii,1),ii=ir,ir)
    ! 9030 format(1x,' ist drrs  ddrrs drrus ddrrus',i5,4e12.5)


    do ip = 1, np

      ry(ip) = 0.e0_dp
      dry(ip) = 0.e0_dp
      ddry(ip) = 0.e0_dp
      rdt1(ip) = 0.e0_dp
      rdt2(ip) = 0.e0_dp
      rdf1(ip) = 0.e0_dp
      rdf2(ip) = 0.e0_dp
      rdtf(ip) = 0.e0_dp
      drdt(ip) = 0.e0_dp
      drdf(ip) = 0.e0_dp

      ryu(ip) = 0.e0_dp
      dryu(ip) = 0.e0_dp
      ddryu(ip) = 0.e0_dp
      rdt1u(ip) = 0.e0_dp
      rdt2u(ip) = 0.e0_dp
      rdf1u(ip) = 0.e0_dp
      rdf2u(ip) = 0.e0_dp
      rdtfu(ip) = 0.e0_dp
      drdtu(ip) = 0.e0_dp
      drdfu(ip) = 0.e0_dp

      ryd(ip) = 0.e0_dp
      dryd(ip) = 0.e0_dp
      ddryd(ip) = 0.e0_dp
      rdt1d(ip) = 0.e0_dp
      rdt2d(ip) = 0.e0_dp
      rdf1d(ip) = 0.e0_dp
      rdf2d(ip) = 0.e0_dp
      rdtfd(ip) = 0.e0_dp
      drdtd(ip) = 0.e0_dp
      drdfd(ip) = 0.e0_dp

    end do

    ! write(6,'(/'' nspin,mesh,np,l1max='',4i5)') nspin,mesh,np,l1max

    lm = 0

    do l1 = 1, l1max

      ll = l1 - 1



      do im = -ll, ll

        lm = lm + 1


        ro = rholm(lm, 1)*2.e0_dp
        rou = ro/2.e0_dp
        rod = rou

        if (nspin/=1) then

          ro = rholm(lm, 1) + rholm(lm, 2)
          rou = rholm(lm, 2)
          rod = rholm(lm, 1)
          ! write(6,9001) ro,rou,rod
        end if
        drr = drrl(ir, lm)
        ddrr = ddrrl(ir, lm)
        drru = drrul(ir, lm)
        ddrru = ddrrul(ir, lm)
        drrd = drr - drru
        ddrrd = ddrr - ddrru


        do ip = 1, np

          rylm = ylm(ip, lm)
          dt1 = dylmt1(ip, lm)
          dt2 = dylmt2(ip, lm)
          df1 = dylmf1(ip, lm)
          df2 = dylmf2(ip, lm)
          dtf = dylmtf(ip, lm)

          ry(ip) = ry(ip) + ro*rylm
          dry(ip) = dry(ip) + drr*rylm
          ddry(ip) = ddry(ip) + ddrr*rylm

          ryu(ip) = ryu(ip) + rou*rylm
          dryu(ip) = dryu(ip) + drru*rylm
          ddryu(ip) = ddryu(ip) + ddrru*rylm

          ryd(ip) = ryd(ip) + rod*rylm
          dryd(ip) = dryd(ip) + drrd*rylm
          ddryd(ip) = ddryd(ip) + ddrrd*rylm

          rdt1(ip) = rdt1(ip) + ro*dt1
          rdt2(ip) = rdt2(ip) + ro*dt2
          rdf1(ip) = rdf1(ip) + ro*df1
          rdf2(ip) = rdf2(ip) + ro*df2
          rdtf(ip) = rdtf(ip) + ro*dtf
          drdt(ip) = drdt(ip) + drr*dt1
          drdf(ip) = drdf(ip) + drr*df1

          rdt1u(ip) = rdt1u(ip) + rou*dt1
          rdt2u(ip) = rdt2u(ip) + rou*dt2
          rdf1u(ip) = rdf1u(ip) + rou*df1
          rdf2u(ip) = rdf2u(ip) + rou*df2
          rdtfu(ip) = rdtfu(ip) + rou*dtf
          drdtu(ip) = drdtu(ip) + drru*dt1
          drdfu(ip) = drdfu(ip) + drru*df1

          rdt1d(ip) = rdt1d(ip) + rod*dt1
          rdt2d(ip) = rdt2d(ip) + rod*dt2
          rdf1d(ip) = rdf1d(ip) + rod*df1
          rdf2d(ip) = rdf2d(ip) + rod*df2
          rdtfd(ip) = rdtfd(ip) + rod*dtf
          drdtd(ip) = drdtd(ip) + drrd*dt1
          drdfd(ip) = drdfd(ip) + drrd*df1
          ! rc             if (ip.eq.5.or.ip.eq.6) then
          ! write(6,9907) lm,rylm,dt1,dt2,df1,df2,dtf
          ! 9907         format(1x,' lmt ',i3,6d12.6)
          ! write(6,*) 'nikos',dry(ip),ddry(ip)
          ! end if


        end do
      end do
    end do



    do ip = 1, np
      sint1 = sin(thet(ip))
      sint2 = sint1**2
      tant1 = tan(thet(ip))
      if (abs(sint1)<eps) then
        vxcp(ip, 1) = 0.e0_dp
        vxcp(ip, 2) = 0.e0_dp
        excp(ip) = 0.e0_dp
        ! WRITE (6,FMT=*) 'interpolate'

        ! set values later
      else
        rv2 = rv**2
        rv3 = rv**3


        rvsin1 = rv*sint1

        grr = dry(ip)
        grt = rdt1(ip)/rv
        grf = rdf1(ip)/rvsin1
        ry2 = ry(ip)**2

        agr = sqrt(grr**2+grt**2+grf**2)

        dagrr = (dry(ip)*ddry(ip)*rv3+rdt1(ip)*(drdt(ip)*rv-rdt1(ip))+rdf1(ip)*(drdf(ip)*rv-rdf1(ip))/sint2)/agr/rv3

        dagrt = (dry(ip)*drdt(ip)*rv2+rdt1(ip)*rdt2(ip)+rdf1(ip)*(-rdf1(ip)/tant1+rdtf(ip))/sint2)/(agr*rv3)

        dagrf = (dry(ip)*drdf(ip)*rv2+rdt1(ip)*rdtf(ip)+rdf1(ip)*rdf2(ip)/sint2)/(agr*rv3*sint1)

        dzdr = ((dryu(ip)-dryd(ip))*ry(ip)-(ryu(ip)-ryd(ip))*dry(ip))/ry2

        dzdtr = ((rdt1u(ip)-rdt1d(ip))*ry(ip)-(ryu(ip)-ryd(ip))*rdt1(ip))/ry2/rv

        dzdfs = ((rdf1u(ip)-rdf1d(ip))*ry(ip)-(ryu(ip)-ryd(ip))*rdf1(ip))/ry2/rvsin1

        g2r = ddry(ip) + 2.e0_dp*dry(ip)/rv + (rdt2(ip)+rdt1(ip)/tant1+rdf2(ip)/sint2)/rv2

        gggr = grr*dagrr + grt*dagrt + grf*dagrf

        gzgr = dzdr*grr + dzdtr*grt + dzdfs*grf

        chg = ry(ip)
        spi = ryu(ip) - ryd(ip)
        chg = max(1.0e-12_dp, chg)
        smag = sign(1.0e0_dp, spi)
        spi = smag*min(chg-1.0e-12_dp, abs(spi))
        zta = spi/chg

        grru = dryu(ip)
        grtu = rdt1u(ip)/rv
        grfu = rdf1u(ip)/rvsin1

        agru = sqrt(grru**2+grtu**2+grfu**2)

        dagrru = (dryu(ip)*ddryu(ip)*rv3+rdt1u(ip)*(drdtu(ip)*rv-rdt1u(ip))+rdf1u(ip)*(drdfu(ip)*rv-rdf1u(ip))/sint2)/agru/rv3

        dagrtu = (dryu(ip)*drdtu(ip)*rv2+rdt1u(ip)*rdt2u(ip)+rdf1u(ip)*(-rdf1u(ip)/tant1+rdtfu(ip))/sint2)/(agru*rv3)

        dagrfu = (dryu(ip)*drdfu(ip)*rv2+rdt1u(ip)*rdtfu(ip)+rdf1u(ip)*rdf2u(ip)/sint2)/(agru*rv3*sint1)

        g2ru = ddryu(ip) + 2.e0_dp*dryu(ip)/rv + (rdt2u(ip)+rdt1u(ip)/tant1+rdf2u(ip)/sint2)/rv2

        gggru = grru*dagrru + grtu*dagrtu + grfu*dagrfu

        grgru = grr*grru + grt*grtu + grf*grfu

        grrd = dryd(ip)
        grtd = rdt1d(ip)/rv
        grfd = rdf1d(ip)/rvsin1

        agrd = sqrt(grrd**2+grtd**2+grfd**2)

        dagrrd = (dryd(ip)*ddryd(ip)*rv3+rdt1d(ip)*(drdtd(ip)*rv-rdt1d(ip))+rdf1d(ip)*(drdfd(ip)*rv-rdf1d(ip))/sint2)/agrd/rv3

        dagrtd = (dryd(ip)*drdtd(ip)*rv2+rdt1d(ip)*rdt2d(ip)+rdf1d(ip)*(-rdf1d(ip)/tant1+rdtfd(ip))/sint2)/(agrd*rv3)

        dagrfd = (dryd(ip)*drdfd(ip)*rv2+rdt1d(ip)*rdtfd(ip)+rdf1d(ip)*rdf2d(ip)/sint2)/(agrd*rv3*sint1)

        g2rd = ddryd(ip) + 2.e0_dp*dryd(ip)/rv + (rdt2d(ip)+rdt1d(ip)/tant1+rdf2d(ip)/sint2)/rv2

        gggrd = grrd*dagrrd + grtd*dagrtd + grfd*dagrfd

        grgrd = grr*grrd + grt*grtd + grf*grfd

        idspr = 0
        if (rv>rdspr) idspr = 1

        ! for debug
        call gxcpt(idspr,chg,zta,agr,agru,agrd,g2r,g2ru,g2rd,gggr,gggru,gggrd,grgru,&
          grgrd,gzgr,vxcp(ip,2),vxcp(ip,1),excp(ip),vxl1,vxl2,vcl1,vcl2,xedl,cedl,  &
          vxg1,vxg2,vcg1,vcg2,xedg,cedg)


        ! if(ip.eq.202) then
        ! write(6,9912) ir,ip,ry(ip),zta,vxcp(ip,2),vxcp(ip,1)
        ! 9912 format(1x,' ir ip ry zta',2i5,5e15.6)
        ! write(6,*) 'mkxcpe',sint1,sint2,tant1,thet(ip)

        ! write(6,9911) agr,agru,agrd,g2r,g2ru,g2rd,gggr,gggru,
        ! &              gggrd,grgru,grgrd,gzgr
        ! 9911 format(1x,' agr  ',6E15.6)

        ! write(6,7777) vxcp(ip,1),vxcp(ip,2),
        ! &              vxl1,vxl2,vcl1,vcl2
        ! write(6,7778) vxg1,vxg2,vcg1,vcg2
        ! 7777 format(1x,'vxcp(1,2) vxl(1,2) vcl(1,2) ',6D15.6)
        ! 7778 format(1x,'vxg(1,2) vcg(1,2)  (asada)  ',4D15.6)

        ! end if
      end if

    end do

    ! This is expected to work only for the Lebedev points
    nn = 0
    nn1 = 0
    vtot1 = 0.e0_dp
    vtot2 = 0.e0_dp
    etot0 = 0.e0_dp
    vtota1 = 0.e0_dp
    vtota2 = 0.e0_dp
    etota0 = 0.e0_dp
    do ip = 1, np
      cosx = cos(thet(ip))
      if (cosx>0.99e0_dp .and. abs(cosx-1.e0_dp)>eps) then
        nn = nn + 1
        vtot1 = vtot1 + vxcp(ip, 1)
        vtot2 = vtot2 + vxcp(ip, 2)
        etot0 = etot0 + excp(ip)
        ! write(6,*) 'more',ip,vxcp(ip,1),nn
      end if
      if (cosx<-0.99e0_dp .and. abs(cosx+1.e0_dp)>eps) then
        nn1 = nn1 + 1
        vtota1 = vtota1 + vxcp(ip, 1)
        vtota2 = vtota2 + vxcp(ip, 2)
        etota0 = etota0 + excp(ip)
        ! write(6,*) 'less',ip,vxcp(ip,1),nn1
      end if
    end do
    do ip = 1, np
      cosx = cos(thet(ip))
      if (abs(cosx-1.e0_dp)<eps) then
        vxcp(ip, 1) = vtot1/nn
        vxcp(ip, 2) = vtot2/nn
        excp(ip) = etot0/nn
        ! write(6,*) 'averaging ',ip,vxcp(ip,1),vxcp(ip,2),excp(ip)
        ! write(6,*) 'averaging1 ',vtot1,vtot2,etot0,nn
      end if
      if (abs(cosx+1.e0_dp)<eps) then
        vxcp(ip, 1) = vtota1/nn1
        vxcp(ip, 2) = vtota2/nn1
        excp(ip) = etota0/nn1
        ! write(6,*) 'averaging ',ip,cosx,vxcp(ip,1),vxcp(ip,2),excp(ip)
        ! write(6,*)'averaging2 ',vtota1,vtota2,etota0,nn1
      end if
    end do
    return
  end subroutine mkxcpe

end module mod_mkxcpe