!-----------------------------------------------------------------------------------------! ! 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: Reads the potential and shape functions of impurity !> Author: N. H. Long !> Reads the potential and shape functions of impurity !------------------------------------------------------------------------------------ !> @note Jonathan Chico: There is an array called `scale` used in this routine, !> this is the same name than the `FORTRAN` intrinsic function `scale()`. It !> might be a good idea to change this name. !> @endnote !------------------------------------------------------------------------------------ module mod_readimppot use :: mod_datatypes, only: dp private :: dp contains !------------------------------------------------------------------------------- !> Summary: Reads the potential and shape functions of impurity !> Author: N. H. Long !> Category: input-output, shape-functions, potential, KKRhost !> Deprecated: False !> Reads the potential and shape functions of impurity !------------------------------------------------------------------------------- !> @note Jonathan Chico: There is an array called `scale` used in this routine, !> this is the same name than the `FORTRAN` intrinsic function `scale()`. It !> might be a good idea to change this name. !> @endnote !------------------------------------------------------------------------------- subroutine readimppot(natomimp,ins,ipf,ipfe,ipe,kws,nspin,lpot,ipanimp,thetasimp, & ircutimp,irwsimp,khfeld,hfield,vinsimp,vm2zimp,irminimp,rimp,zimp,irmd,irnsd, & irid,nfund,ipand) use :: mod_calrmt use :: mod_potcut implicit none ! .. Parameters .. integer :: nspin, natomimp, irmd, irnsd, irid, nfund, ipand ! .. ! .. Scalar Arguments .. real (kind=dp) :: alat, hfield, vbc(2) integer :: ins, ipe, ipf, ipfe, khfeld, kws, lpot ! .. ! .. Array Arguments .. real (kind=dp) :: a(natomimp), b(natomimp), drdi(irmd, natomimp), ecore(20, nspin*natomimp), rimp(irmd, natomimp), rmt(natomimp), rmtnew(natomimp), & rws(natomimp), thetasimp(irid, nfund, natomimp), vinsimp((irmd-irnsd):irmd, (lpot+1)**2, natomimp*nspin), vm2zimp(irmd, natomimp*nspin), zimp(natomimp) integer :: imt(natomimp), ipanimp(natomimp), ircutimp(0:ipand, natomimp), irminimp(natomimp), irwsimp(natomimp), ititle(20, nspin*natomimp), lcore(20, nspin*natomimp), & ncore(nspin*natomimp), nfu(natomimp) ! .. ! .. Local Arrays .. real (kind=dp) :: dummy2(irmd, natomimp*nspin) ! .. ! .. Local Scalars .. real (kind=dp) :: a1, b1, ea, efnew, dummy integer :: i, ia, icell, icore, ifun, ih, imt1, inew, io, ipan1, ir, irc1, iri, irminm, irminp, irns1p, irt1p, irws1, isave, ispin, isum, j, lm, lm1, lmpot, lmpotp, n, ncell, & nfun, nr ! .. ! .. Local Arrays .. real (kind=dp) :: drn(irid, natomimp), scale(1), u(irmd), xrn(irid, natomimp) integer :: meshn(natomimp), nm(ipand, natomimp), npan(natomimp) ! .. ! ------------------------------------------------------------------ write (1337, *) 'in readimppot' vinsimp = 0e0_dp ! ------------------------------------------------------------------ ! read data from shapefun_imp file if (ins>0) then open (unit=20, file='shapefun_imp', form='FORMATTED') read (20, *) ncell read (20, *) scale(1) do icell = 1, ncell read (20, fmt=100) npan(icell), meshn(icell) read (20, fmt=100)(nm(ipan1,icell), ipan1=2, npan(icell)+1) read (20, fmt=110)(xrn(ir,icell), drn(ir,icell), ir=1, meshn(icell)) read (20, fmt=100) nfu(icell) nfun = nfu(icell) do ifun = 1, nfun read (20, fmt=100) lm if (lm<=(2*lpot+1)**2) then read (20, fmt=110)(thetasimp(n,ifun,icell), n=1, meshn(icell)) else read (20, fmt=110)(dummy, n=1, meshn(icell)) end if end do end do end if ! INS.EQ.1 do icell = 1, ncell if (ins/=0) then ipanimp(icell) = 1 + npan(icell) else ipanimp(icell) = 1 end if end do ! ------------------------------------------------------------------ ! read in impurity potential open (unit=21, file='potential_imp', form='FORMATTED') lmpot = (lpot+1)*(lpot+1) do ih = 1, ncell do ispin = 1, nspin i = nspin*(ih-1) + ispin ircutimp(0, ih) = 0 ! ---> read title of potential card read (21, fmt=120)(ititle(ia,i), ia=1, 20) ! --->read muffin-tin radius , lattice constant and new muffin radius ! READ (21,FMT=9030) RMT(IH),ALAT,RMTNEW(IH) read (21, fmt=*) rmt(ih), alat, rmtnew(ih) ! ---> read nuclear charge , lmax of the core states , ! wigner seitz radius , fermi energy and energy difference ! between electrostatic zero and muffin tin zero ! READ (21,FMT=9040) ZIMP(IH),RWS(IH),EFNEW,VBC(ISPIN) read (21, fmt=*) zimp(ih) read (21, fmt=*) rws(ih), efnew, vbc(ispin) ! ---> read : number of radial mesh points ! (in case of ws input-potential: last mesh point corresponds ! to ws-radius, in case of shape-corrected input-potential ! last mesh point of the exponential mesh corresponds to ! mt-radius/nevertheless this point is always in the array ! irws(ih)),number of points for the radial non-muffin-tin ! mesh needed for shape functions, the constants a and b ! for the radial exponential mesh : r(i) = b*(exp(a*(i-1))-1) ! the no. of different core states and some other stuff read (21, fmt=150) irwsimp(ih) ! READ (21,FMT=9051) A(IH),B(IH),NCORE(I),INEW read (21, fmt=*) a(ih), b(ih) read (21, fmt=*) ncore(i), inew nr = irwsimp(ih) ! ---> read the different core states : l and energy if (ncore(i)>=1) read (21, fmt=180)(lcore(icore,i), ecore(icore,i), icore=1, ncore(i)) if (ins<1) then ! ---> read radial mesh points, its derivative, the spherically ! averaged ! charge density and the input potential without the nuclear pot. if (inew==0) then read (21, fmt=170)(rimp(ir,ih), drdi(ir,ih), vm2zimp(ir,i), ir=1, nr) else read (21, fmt=*)(vm2zimp(ir,i), ir=1, nr) end if else ! (INS.LT.1) ! ---> read full potential - the non spherical contribution from ! irmin ! to irt - remember that the lm = 1 contribution is multiplied by ! 1/sqrt(4 pi) read (21, fmt=190) irt1p, irns1p, lmpotp, isave irminp = irt1p - irns1p irminm = max(irminp, irmd-irnsd) read (21, fmt=200)(vm2zimp(ir,i), ir=1, nr) if (lmpotp>1) then lm1 = 2 do lm = 2, lmpotp if (lm1/=1) then if (isave==1) then read (21, fmt=190) lm1 else lm1 = lm end if if (lm1>1) then read (21, fmt=200)(u(ir), ir=irminp, nr) if (lm1<=lmpot) then do ir = irminm, nr vinsimp(ir, lm1, i) = u(ir) end do end if end if end if end do end if end if ! (INS.LT.1) irws1 = irwsimp(ih) ! ---> redefine new mt-radius in case of shape corrections if (ins/=0) then rmtnew(ih) = scale(1)*alat*xrn(1, ih) imt1 = nint(log(rmtnew(ih)/b(ih)+1.0e0_dp)/a(ih)) + 1 ! ---> for proper core treatment imt must be odd ! shift potential by one mesh point if imt is even if (mod(imt1,2)==0) then imt1 = imt1 + 1 do ir = imt1, 2, -1 vm2zimp(ir, i) = vm2zimp(ir-1, i) end do end if imt(ih) = imt1 b(ih) = rmtnew(ih)/(exp(a(ih)*real(imt1-1,kind=dp))-1.0e0_dp) end if ! (INS.NE.0) ! ---> generate radial mesh - potential only is stored in potential card ! INEW = 1 ! p. zahn, jan. 99 a1 = a(ih) b1 = b(ih) rimp(1, ih) = 0.0e0_dp drdi(1, ih) = a1*b1 do ir = 2, irws1 ea = exp(a1*real(ir-1,kind=dp)) rimp(ir, ih) = b1*(ea-1.0e0_dp) drdi(ir, ih) = a1*b1*ea end do ! ---> fill cell-type depending mesh points in the non-muffin-tin-region if (ins/=0) then do iri = 1, meshn(ih) ir = iri + imt1 rimp(ir, ih) = scale(1)*alat*xrn(iri, ih) drdi(ir, ih) = scale(1)*alat*drn(iri, ih) end do end if rws(ih) = rimp(irws1, ih) ! ---> kshape.eq.0 : calculate new rmt adapted to exp. mesh call calrmt(ipf, ipfe, ipe, imt(ih), zimp(ih), rmt(ih), rws(ih), rmtnew(ih), alat, drdi(1,ih), a(ih), b(ih), irws1, rimp(1,ih), io, ins) if (ins>0) then ircutimp(1, ih) = imt(ih) isum = imt(ih) do ipan1 = 2, ipanimp(ih) isum = isum + nm(ipan1, ih) ircutimp(ipan1, ih) = isum end do nr = isum else ! INS.EQ.0 nr = irwsimp(ih) if (kws>=1) then ircutimp(1, ih) = irws1 else ircutimp(1, ih) = imt(ih) end if end if ! INS.GT.0 ! ---> fill array irmin in case of full potential if (ins/=0) irminimp(ih) = nr - irns1p ! ---> cut input potential at rmt if given only at exponential mesh if (ins>1) then imt1 = imt(ih) irc1 = ircutimp(ipanimp(ih), ih) call potcut(imt1, irc1, ins, lmpot, rimp(1,ih), vm2zimp(1,i), dummy2, vinsimp(irmd-irnsd,1,i), zimp(ih), irmd, irmd-irnsd) end if if (ins==0 .and. kws==0) then ! ---> in case of a mt calculation cut potential at mt radius imt1 = imt(ih) irws1 = irwsimp(ih) call potcut(imt1, irws1, ins, lmpot, rimp(1,ih), vm2zimp(1,i), dummy2, vinsimp(irmd-irnsd,1,i), zimp(ih), irmd, irmd-irnsd) end if ! INS.EQ.0 .AND. KWS.EQ.0 ! ---> maybe apply a magnetic field if (khfeld==1) then write (1337, *) 'ATOM', ih, 'SPIN', ispin, 'SHIFTED BY', -real(2*ispin-3, kind=dp)*hfield do j = 1, ircutimp(ipanimp(ih), ih) vm2zimp(j, i) = vm2zimp(j, i) - real(2*ispin-3, kind=dp)*hfield end do end if end do ! ISPIN = 1,NSPIN end do ! IH = 1,NCELL close (20) close (21) return 100 format (16i5) 110 format (4d20.12) 120 format (20a4) 130 format (3f12.8) 140 format (f10.5, /, f10.5, 2f15.10) 150 format (i4) 160 format (2d15.8, /, 2i2) 170 format (1p, 2d15.6, 1p, d15.8) 180 format (i5, 1p, d20.11) 190 format (10i5) 200 format (1p, 4d20.13) end subroutine readimppot end module mod_readimppot