!-----------------------------------------------------------------------------------------! ! 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: This is calculating the intra-atomic contibution of the potential in the case of an interface taking into account the bulk potential on the two sides. !> Author: !> It uses the structure dependent matrices `AVMAD` which are calculated !> once in the subroutine `MADELUNG2D()` and saved in the DA-file `avmad.unformatted` ( May 2004) !> !> For each site in a layer the summation in all other layers is split !> into three parts: within the slab, over the `NLEFT*NLBASIS` left host !> sites and over the `NRIGHT*NRBASIS` right host sites, the last two !> steps only in case of decimation run !------------------------------------------------------------------------------------ !> @note !> - Adapted for the case of more atoms on the same site, summation is !> done over the occupants of that site, the charge is weighted with !> the appropriate concentration of the occupant V. Popescu feb. 2002 !> @endnote !------------------------------------------------------------------------------------ module mod_vinterface contains !------------------------------------------------------------------------------- !> Summary: This is calculating the intra-atomic contibution of the potential in the case of an interface taking into account the bulk potential on the two sides. !> Author: !> Category: potential, KKRhost !> Deprecated: False !> It uses the structure dependent matrices `AVMAD` which are calculated !> once in the subroutine `MADELUNG2D()` and saved in the DA-file `avmad.unformatted` ( May 2004) !> !> For each site in a layer the summation in all other layers is split !> into three parts: within the slab, over the `NLEFT*NLBASIS` left host !> sites and over the `NRIGHT*NRBASIS` right host sites, the last two !> steps only in case of decimation run !------------------------------------------------------------------------------- !> @note !> - Adapted for the case of more atoms on the same site, summation is !> done over the occupants of that site, the charge is weighted with !> the appropriate concentration of the occupant V. Popescu feb. 2002 !> @endnote !------------------------------------------------------------------------------- subroutine vinterface(cmom,cminst,lpot,nspin,nlayers,natyp,v,zat,r,irws,ircut, & ipan,kshape,noq,kaoez,iqat,conc,catom,icc,hostimp,nlbasis,nleft,nrbasis,nright, & cmomhost,chrgnt,vinters,naez,lmpot) use :: mod_constants, only: pi, czero use :: mod_runoptions, only: print_program_flow, use_decimation, write_kkrimp_input, write_madelung_file use :: global_variables, only: wlength, ipand, nembd1, irmd, npotd use :: mod_main0, only: npol use :: mod_datatypes, only: dp use :: mod_types, only: t_madel implicit none ! .. Input variables .. integer, intent (in) :: icc !! Enables the calculation of off-diagonal elements of the GF.(0=SCF/DOS; 1=cluster; -1=custom) integer, intent (in) :: lpot !! Maximum l component in potential expansion integer, intent (in) :: naez !! Number of atoms in unit cell integer, intent (in) :: lmpot !! (LPOT+1)**2 integer, intent (in) :: nspin !! Counter for spin directions integer, intent (in) :: natyp !! Number of kinds of atoms in unit cell integer, intent (in) :: nleft !! Number of repeated basis for left host to get converged electrostatic potentials integer, intent (in) :: nright !! Number of repeated basis for right host to get converged electrostatic potentials integer, intent (in) :: kshape !! Exact treatment of WS cell integer, intent (in) :: nlayers integer, intent (in) :: nlbasis !! Number of basis layers of left host (repeated units) integer, intent (in) :: nrbasis !! Number of basis layers of right host (repeated units) real (kind=dp), intent (in) :: chrgnt integer, dimension (naez), intent (in) :: noq !! Number of diff. atom types located integer, dimension (natyp), intent (in) :: irws !! R point at WS radius integer, dimension (natyp), intent (in) :: ipan !! Number of panels in non-MT-region integer, dimension (natyp), intent (in) :: iqat !! The site on which an atom is located on a given site integer, dimension (0:natyp), intent (in) :: hostimp integer, dimension (0:ipand, natyp), intent (in) :: ircut !! R points of panel borders integer, dimension (natyp, naez+nembd1-1), intent (in) :: kaoez !! Kind of atom at site in elem. cell real (kind=dp), dimension (natyp), intent (in) :: zat !! Nuclear charge real (kind=dp), dimension (natyp), intent (in) :: conc !! Concentration of a given atom real (kind=dp), dimension (natyp), intent (in) :: catom real (kind=dp), dimension (irmd, natyp), intent (in) :: r !! Radial mesh (in units a Bohr) real (kind=dp), dimension (lmpot, natyp), intent (in) :: cmom !! LM moment of total charge real (kind=dp), dimension (lmpot, natyp), intent (in) :: cminst !! charge moment of interstitial real (kind=dp), dimension (lmpot, nembd1), intent (in) :: cmomhost !! Charge moments of each atom of the (left/right) host ! .. In/out variables real (kind=dp), dimension (irmd, lmpot, npotd), intent (inout) :: v ! .. Local variables integer :: ileft, iright integer :: i, iatom, ib, ih1, ilay1, ilay2, io2 integer :: ipot, irs1, ispin, it1, it2, l, lm, lm2, m integer :: lrecamad, irec, nleftoff, nrightoff, nleftall, nrightall real (kind=dp) :: cm1, fpi logical :: lread real (kind=dp), dimension (lmpot) :: ac real (kind=dp), dimension (lmpot) :: cm real (kind=dp), dimension (2) :: charge real (kind=dp), dimension (naez) :: monopol real (kind=dp), dimension (lmpot, lmpot) :: avmad real (kind=dp), dimension (lmpot, naez) :: vinters if (print_program_flow) write (1337, *) '>>>>>> Vinterface' if (write_madelung_file) then inquire (file='avmad.unformatted', exist=lread) ! ewald2d if (lread) then lrecamad = wlength*2*lmpot*lmpot open (69, access='direct', recl=lrecamad, file='avmad.unformatted', form='unformatted') else lrecamad = wlength*2*lmpot*lmpot + wlength*2*lmpot open (69, access='direct', recl=lrecamad, file='abvmad.unformatted', form='unformatted') end if end if ! madelfil write (1337, fmt=100) write (1337, fmt=110) fpi = 4.e0_dp*pi if (use_decimation) then ! ------------------------------------------------------------------------- ! Setup the charges to put in the ghost layers in the case of ! decimation technique to achieve charge neutrality ! ------------------------------------------------------------------------- charge(1) = -chrgnt/(2.e0_dp*sqrt(fpi)) charge(2) = -chrgnt/(2.e0_dp*sqrt(fpi)) nleftoff = nlayers*nlayers ! record offsets nrightoff = nleftoff + nlayers*nleft*nlbasis ! left and right nleftall = nleft*nlbasis nrightall = nright*nrbasis end if ! ---------------------------------------------------------------------------- ! START CALCULATION IN THE LAYERS ! ---------------------------------------------------------------------------- ! ---------------------------------------------------------------------------- ! Loop over atoms in slab ! ---------------------------------------------------------------------------- do it1 = 1, natyp ! ------------------------------------------------------------------------- ! Take a site occupied by IT1 ! ------------------------------------------------------------------------- ilay1 = iqat(it1) if (kshape/=0) then irs1 = ircut(ipan(it1), it1) else irs1 = irws(it1) end if do lm = 1, lmpot ac(lm) = 0.e0_dp end do ! ------------------------------------------------------------------------- ! 1. Summation in all layers in the slab ! ------------------------------------------------------------------------- do ilay2 = 1, nlayers irec = ilay2 + nlayers*(ilay1-1) if (npol==0) then avmad(:,:) = czero elseif (write_madelung_file) then read (69, rec=irec) avmad else avmad(:,:) = t_madel%avmad(irec,:,:) end if ! ---------------------------------------------------------------------- ! Keep the monopole term -- Hoshino is doing (SMONOPOL(I) -SMONOPOL(0)) ! ---------------------------------------------------------------------- if (ilay1==ilay2) monopol(ilay1) = avmad(1, 1) ! ---------------------------------------------------------------------- ! Loop over all occupants of site ILAY2 ! ---------------------------------------------------------------------- do io2 = 1, noq(ilay2) it2 = kaoez(io2, ilay2) do lm = 1, lmpot cm(lm) = cmom(lm, it2) ! ---------------------------------------------------------------- ! Add contribution of interstial in case of shapes ! ---------------------------------------------------------------- if (kshape/=0) cm(lm) = cm(lm) + cminst(lm, it2) end do cm(1) = cm(1) - zat(it2)/sqrt(fpi) do lm = 1, lmpot do lm2 = 1, lmpot ac(lm) = ac(lm) + avmad(lm, lm2)*cm(lm2)*conc(it2) end do end do end do ! ---------------------------------------------------------------------- ! Loop over all occupants of site ILAY2 ! ---------------------------------------------------------------------- end do ! ILAY2 loop in all interface planes ! ------------------------------------------------------------------------- do ilay2 = 1, nlayers ! ---------------------------------------------------------------------- ! Loop over all occupants of site ILAY2 ! ---------------------------------------------------------------------- do io2 = 1, noq(ilay2) it2 = kaoez(io2, ilay2) cm1 = cmom(1, it2) if (kshape/=0) cm1 = cm1 + cminst(1, it2) cm1 = cm1 - zat(it2)/sqrt(fpi) ac(1) = ac(1) - monopol(ilay1)*cm1*conc(it2) end do ! ---------------------------------------------------------------------- ! Loop over all occupants of site ILAY2 ! ---------------------------------------------------------------------- end do ! ------------------------------------------------------------------------- ! Correction: charge neutrality is imposed (see P. Lang) ! ------------------------------------------------------------------------- if (use_decimation) then ! ---------------------------------------------------------------------- ! 2. Summation in the LEFT bulk side ! ---------------------------------------------------------------------- ! ---------------------------------------------------------------------- ! Loop over all occupants of LEFT host ! ---------------------------------------------------------------------- ileft = 0 do ih1 = 1, nleft do ib = 1, nlbasis ileft = ileft + 1 irec = ileft + nleftall*(ilay1-1) + nleftoff if (npol==0) then avmad(:,:) = czero elseif (write_madelung_file) then read (69, rec=irec) avmad else avmad(:,:) = t_madel%avmad(irec,:,:) end if iatom = ib do lm = 1, lmpot do lm2 = 1, lmpot ac(lm) = ac(lm) + avmad(lm, lm2)*cmomhost(lm2, iatom) end do end do if ((ih1==1) .and. (ib==1)) then ac(1) = ac(1) + (avmad(1,1)-monopol(ilay1))*charge(1) end if end do end do ! ---------------------------------------------------------------------- if (ileft/=nleftall) then write (6, *) ' < VINTERFACE > : index error ', 'ILEFT <> NLEFT*NLBASIS' stop end if ! ---------------------------------------------------------------------- ! 3. Summation in the RIGHT bulk side ! ---------------------------------------------------------------------- ! ---------------------------------------------------------------------- ! Loop over all occupants of RIGHT host ! ---------------------------------------------------------------------- iright = 0 do ih1 = 1, nright do ib = 1, nrbasis iright = iright + 1 irec = iright + nrightall*(ilay1-1) + nrightoff if (npol==0) then avmad(:,:) = czero elseif (write_madelung_file) then read (69, rec=irec) avmad else avmad(:,:) = t_madel%avmad(irec,:,:) end if iatom = nlbasis + ib do lm = 1, lmpot do lm2 = 1, lmpot ac(lm) = ac(lm) + avmad(lm, lm2)*cmomhost(lm2, iatom) end do end do if ((ih1==1) .and. (ib==1)) then ac(1) = ac(1) + (avmad(1,1)-monopol(ilay1))*charge(2) end if end do end do ! ---------------------------------------------------------------------- if (iright/=nrightall) then write (6, *) ' < VINTERFACE > : index error ', 'IRIGHT <> NRIGHT*NRBASIS' stop end if end if ! (OPT(DECIMATE) ! ------------------------------------------------------------------------- write (1337, fmt=120) it1, (catom(it1)-zat(it1)), (ac(1)/sqrt(4.e0_dp*pi)), (ac(3)/sqrt(4.e0_dp*pi)) ! ------------------------------------------------------------------------- ! Loop over spins of atom IT1 ! ------------------------------------------------------------------------- do ispin = 1, nspin ! ---------------------------------------------------------------------- ! Determine the right potential number ! ---------------------------------------------------------------------- ipot = nspin*(it1-1) + ispin ! ---------------------------------------------------------------------- ! In the case of l=0 : r(1)**l is not defined ! ---------------------------------------------------------------------- v(1, 1, ipot) = v(1, 1, ipot) + ac(1) do l = 0, lpot do m = -l, l lm = l*l + l + m + 1 do i = 2, irs1 v(i, lm, ipot) = v(i, lm, ipot) + (-r(i,it1))**l*ac(lm) end do end do end do end do ! ------------------------------------------------------------------------- ! This part (ICC.GT.0) should be presumably reconsidered for impurity ! calculation in host-CPA case ! ------------------------------------------------------------------------- if (icc>0 .or. write_kkrimp_input) then do l = 0, lpot do m = -l, l lm = l*l + l + m + 1 vinters(lm, ilay1) = ac(lm) end do end do end if ! ------------------------------------------------------------------------- end do ! ---------------------------------------------------------------------------- if (write_madelung_file) close (69) write (1337, '(15X,45("-"),/)') write (1337, '(79("="))') if ((icc==0) .and. (.not. write_kkrimp_input)) return ! ---------------------------------------------------------------------------- ! Now Prepare output for Impurity calculation ! ---------------------------------------------------------------------------- open (91, file='intercell_ref', status='unknown', form='formatted') write (1337, *) write (1337, *) ' ', 'Writing intercell potential for impurity' write (1337, '(/,20X,55("-"))') write (1337, 130) hostimp(0), lmpot write (1337, '(20X,55("-"),/,35X," i host lm Vint")') do i = 1, hostimp(0) write (1337, *) lm = 1 write (1337, '(35X,I4,I4,I3,1X,F10.6)') i, hostimp(i), lm, vinters(lm, hostimp(i)) do lm = 2, 9 write (1337, '(43X,I3,1X,F10.6)') lm, vinters(lm, hostimp(i)) end do write (1337, '(20X,55("-"))') end do write (1337, '(79("="),/)') write (91, 140) hostimp(0), lmpot do i = 1, hostimp(0) write (91, 150)(vinters(lm,hostimp(i)), lm=1, lmpot) end do close (91) return 100 format (79('='), /, 25x, ' INTERFACE MADELUNG POTENTIALS ') 110 format (/, 15x, ' ATOM ', ' Delta_Q ', ' MONOPOLE DIPOLE', /, 15x, 45('-')) 120 format (15x, i4, 2x, f10.6, 1x, 1p, d13.6, 1x, 1p, d13.6) 130 format (22x, i4, ' host atoms, LMPOT = ', i2, ' output up to LM = 9') 140 format (3i6) 150 format (4d20.10) end subroutine vinterface end module mod_vinterface