TABLE OF CONTENTS
ABINIT/m_psp9 [ Modules ]
NAME
m_psp9
FUNCTION
Initialize pspcod=9 (pseudopotentials from the PSML XML format):
COPYRIGHT
Copyright (C) 1999-2024 ABINIT group (JJ, MVer, YP) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt .
SOURCE
16 #if defined HAVE_CONFIG_H 17 #include "config.h" 18 #endif 19 20 #include "abi_common.h" 21 22 module m_psp9 23 24 use defs_basis 25 use m_splines 26 use m_errors 27 use m_abicore 28 #if defined HAVE_LIBPSML 29 use m_psml 30 #endif 31 32 use defs_datatypes, only : nctab_t 33 use m_pawrad, only : pawrad_type, pawrad_init, pawrad_free 34 use m_psps, only : nctab_eval_tvalespl 35 use m_psptk, only : psp8lo, psp8nl 36 37 implicit none 38 39 private
ABINIT/psp9cc [ Functions ]
NAME
psp9cc
FUNCTION
Compute the core charge density, for use in the XC core correction, following the function definition valid for format 9 of the pseudopotentials (PSML).
INPUTS
mmax=maximum number of points in real space grid in the psp file n1xccc=dimension of xccc1d ; 0 if no XC core correction is used
OUTPUT
rchrg=cut-off radius for the core density xccc1d(n1xccc,6)= 1D core charge function and its four first derivatives
NOTES
This routine will be built only if PSML support is enabled.
SOURCE
680 #if defined HAVE_LIBPSML 681 682 subroutine psp9cc(psxml,mmax,n1xccc,rad,rchrg,xccc1d) 683 684 !Arguments ------------------------------------ 685 !scalars 686 integer,intent(in) :: mmax,n1xccc 687 real(dp),intent(out) :: rchrg 688 type(ps_t),intent(in) :: psxml 689 !arrays 690 real(dp),intent(in) :: rad(mmax) 691 real(dp),intent(inout) :: xccc1d(n1xccc,6) !vz_i 692 693 !Local variables------------------------------- 694 !scalars 695 integer :: i1xccc,idum,irad,jj 696 real(dp) :: amesh,c1,c2,c3,c4,damesh,dri,pi4i,tff,xp,xpm1,xpm2,xpp1,xx,twelvth 697 character(len=500) :: message 698 !arrays 699 integer :: iwork(8) 700 real(dp) :: rscale(5),dpoly(6,6),vpoly(6) 701 real(dp),allocatable :: ff(:,:) 702 703 !********************************************************************** 704 705 !Check that rad grid is linear starting at zero 706 amesh=rad(2)-rad(1) 707 damesh=zero 708 do irad=2,mmax-1 709 damesh=max(damesh,abs(rad(irad)+amesh-rad(irad+1))) 710 end do 711 712 if(damesh>tol8 .or. rad(1)/=zero) then 713 write(message, '(5a)' )& 714 & 'Pseudopotential input file requires linear radial mesh',ch10,& 715 & 'starting at zero.',ch10,& 716 & 'Action: check your pseudopotential input file.' 717 ABI_ERROR(message) 718 end if 719 720 ABI_MALLOC(ff,(mmax,5)) 721 722 dri = one / amesh 723 pi4i = quarter / pi 724 twelvth = one / 12.0_dp 725 726 !Read from pp file the model core charge and calculate its first 4 derivatives 727 !assumed to be on a linear grid starting at zero. 728 !The input functions contain the 4pi factor, and must be rescaled. 729 730 !Store the value of the pseudo-core charge. 731 ff(:,:) = zero 732 do jj=1,mmax 733 ff(jj,1) = ps_CoreCharge_Value(psxml,rad(jj)) 734 end do 735 736 !Calculate 4 first derivatives with 5-point stencil, except borders 737 do irad=3,mmax-2 738 ff(irad,2) = (-ff(irad+2,1) + 8.0d0*ff(irad+1,1) - & 739 & 8.0d0*ff(irad-1,1) + ff(irad-2,1)) * twelvth * dri 740 ff(irad,3) = (-ff(irad+2,1) + 16.0d0*ff(irad+1,1) - 30.0d0*ff(irad,1) + & 741 & 16.0d0*ff(irad-1,1) - ff(irad-2,1)) * twelvth * dri * dri 742 ff(irad,4) = (ff(irad+2,1) - 2.0d0*ff(irad+1,1) + & 743 & 2.0d0*ff(irad-1,1) - ff(irad-2,1)) * half * dri * dri * dri 744 ff(irad,5) = (ff(irad+2,1) - 4.0d0*ff(irad+1,1) + 6.0d0*ff(irad,1) - & 745 & 4.0d0*ff(irad-1,1) + ff(irad-2,1)) * dri * dri * dri * dri 746 end do 747 748 !Add border near zero using polynomial fit 749 dpoly(:,:) = zero 750 dpoly(:,1) = one 751 vpoly(:) = zero 752 vpoly(1) = ff(1,1) 753 do irad=2,6 754 do jj=1,6 755 dpoly(irad,jj) = rad(irad)**(jj-1) 756 end do 757 vpoly(irad) = ff(irad,1) 758 end do 759 call dgesv(6,1,dpoly,6,iwork,vpoly,6,idum) 760 761 do irad=1,2 762 ff(irad,2) = & 763 & vpoly(2) + 2.0d0*vpoly(3)*rad(irad) + & 764 & 3.0d0*vpoly(4)*rad(irad)*rad(irad) + & 765 & 4.0d0*vpoly(5)*rad(irad)*rad(irad)*rad(irad) + & 766 & 5.0d0*vpoly(6)*rad(irad)*rad(irad)*rad(irad)*rad(irad) 767 ff(irad,3) = & 768 & 2.0d0*vpoly(3)*rad(irad) + & 769 & 6.0d0*vpoly(4)*rad(irad) + & 770 & 12.0d0*vpoly(5)*rad(irad)*rad(irad) + & 771 & 20.0d0*vpoly(6)*rad(irad)*rad(irad)*rad(irad) 772 ff(irad,4) = & 773 & 6.0d0*vpoly(4) + & 774 & 24.0d0*vpoly(5)*rad(irad) + & 775 & 60.0d0*vpoly(6)*rad(irad)*rad(irad) 776 ff(irad,5) = 24.0d0*vpoly(5) + & 777 & 120.0d0*vpoly(6)*rad(irad) 778 end do 779 780 !Make linear approximation for the tail near mmax 781 do irad=1,2 782 ff(mmax-2+irad,2) = ff(mmax-2,2) + irad * (ff(mmax-2,2) - ff(mmax-3,2)) 783 ff(mmax-2+irad,3) = ff(mmax-2,3) + irad * (ff(mmax-2,3) - ff(mmax-3,3)) 784 ff(mmax-2+irad,4) = ff(mmax-2,4) + irad * (ff(mmax-2,4) - ff(mmax-3,4)) 785 ff(mmax-2+irad,5) = ff(mmax-2,5) + irad * (ff(mmax-2,5) - ff(mmax-3,5)) 786 end do 787 788 !Renormalize core charge 789 ! ff(:,:) = ff(:,:) * pi4i 790 791 !determine xcccrc where the pseudocore becomes 0 792 !This is a difference with respect the Hamann's treatment of the core 793 !charge when reading PSP8. 794 !In Hamann's case (PSP8), xcccrc = rchrg, and this value is 795 !introduced in the pseudopotential input file. 796 !rchrg is not included in the PSML format 797 rchrg = zero 798 do jj=mmax,1,-1 799 if (ff(jj,1) > tol13) then 800 rchrg=rad(jj) 801 exit 802 end if 803 end do 804 805 !Check that input rchrg is consistent with last grid point 806 if(rchrg>rad(mmax)) then 807 write(message, '(5a)' )& 808 & 'Pseudopotential input file core charge mesh',ch10,& 809 & 'is inconsistent with rchrg in header.',ch10,& 810 & 'Action: check your pseudopotential input file.' 811 ABI_ERROR(message) 812 end if 813 814 !Factors for unit range scaling 815 do jj = 1, 5 816 rscale(jj)=rchrg**(jj-1) 817 end do 818 819 !Generate uniform mesh xx in the box cut by rchrg 820 !and interpolate the core charge and derivatives 821 !Cubic polynomial interpolation is used which is consistent 822 !with the original interpolation of these functions from 823 !a log grid to the input linear grid. 824 825 dri=1.d0/amesh 826 do i1xccc=1,n1xccc 827 xx=(i1xccc-1)* rchrg/dble(n1xccc-1) 828 829 ! index to find bracketing input mesh points 830 irad = int(dri * xx) + 1 831 irad = max(irad,2) 832 irad = min(irad,mmax-2) 833 ! interpolation coefficients 834 xp = dri * (xx - rad(irad)) 835 xpp1 = xp + one 836 xpm1 = xp - one 837 xpm2 = xp - two 838 c1 = -xp * xpm1 * xpm2 * sixth 839 c2 = xpp1 * xpm1 * xpm2 * half 840 c3 = - xp * xpp1 * xpm2 * half 841 c4 = xp * xpp1 * xpm1 * sixth 842 ! Now do the interpolation on all derivatives for this grid point 843 ! Include 1/4pi normalization and unit range scaling 844 do jj=1,5 845 tff = c1 * ff(irad - 1, jj) & 846 & + c2 * ff(irad , jj) & 847 & + c3 * ff(irad + 1, jj) & 848 & + c4 * ff(irad + 2, jj) 849 xccc1d(i1xccc,jj)=pi4i*rscale(jj)*tff 850 end do 851 end do 852 853 !5th derivative is apparently not in use, so set to zero 854 xccc1d(:,6)=zero 855 856 ABI_FREE(ff) 857 858 end subroutine psp9cc
ABINIT/psp9in [ Functions ]
NAME
psp9in
FUNCTION
Initialize pspcod=9 (pseudopotentials from the PSML XML format): continue to read the corresponding file, then compute the local and non-local potentials.
INPUTS
filpsp=filename of the PSML pseudopotential lloc=angular momentum choice of local pseudopotential lmax=value of lmax mentioned at the second line of the psp file lmnmax=if useylm=1, max number of (l,m,n) comp. over all type of psps =if useylm=0, max number of (l,n) comp. over all type of psps lnmax=max. number of (l,n) components over all type of psps mmax=maximum number of points in real space grid in the psp file angular momentum of nonlocal pseudopotential mpsang= 1+maximum angular momentum for nonlocal pseudopotentials mpssoang= 2*maximum angular momentum for nonlocal pseudopotentials - 1 mqgrid=dimension of q (or G) grid for arrays. mqgrid_vl=dimension of q (or G) grid for valence charge (array qgrid_vl) n1xccc=dimension of xccc1d ; 0 if no XC core correction is used qgrid(mqgrid)=values of q (or |G|) on grid from 0 to qmax qgrid_vl(psps%mqgrid_vl)=values of q on grid from 0 to qmax (bohr^-1) for valence charge pspso=spin-orbit characteristics, govern the content of ffspl and ekb if =0 : this input requires NO spin-orbit characteristics of the psp if =2 : this input requires HGH or psp8 characteristics of the psp if =3 : this input requires HFN characteristics of the psp useylm=governs the way the nonlocal operator is to be applied: 1=using Ylm, 0=using Legendre polynomials zion=nominal valence of atom as specified in psp file znucl=nuclear number of atom as specified in psp file
OUTPUT
ekb(lnmax)=Kleinman-Bylander energy, {{\ \begin{equation} \frac{\int_0^\infty [Rl(r)^2 (Vl(r)-Vloc(r))^2 dr]} {\int_0^\infty [Rl(r)^2 (Vl(r)-Vloc(r)) dr]} \end{equation} }} for each (l,n) epsatm=$ (4\pi)\int_0^\infty [r^2 (V(r)+\frac{Zv}{r} dr]$ (hartree) ffspl(mqgrid,2,lnmax)=Kleinman-Bylander form factor f_l(q) and second derivative from spline fit for each angular momentum and each projector indlmn(6,i)= array giving l,m,n,lm,ln,s for i=ln (if useylm=0) or i=lmn (if useylm=1) nproj(mpssoang)=number of projection functions for each angular momentum qchrg is not used, and could be suppressed later vlspl(mqgrid,2)=q^2 Vloc(q) and second derivatives from spline fit xcccrc=XC core correction cutoff radius (bohr) xccc1d(n1xccc,6)=1D core charge function and five derivatives, from psp file nctab<nctab_t>=NC tables %has_tvale=True if the pseudo contains the pseudo valence charge %tvalespl(mqgrid_vl,2)=the pseudo valence density and 2nd derivative in reciprocal space on a regular grid
SOURCE
106 subroutine psp9in(filpsp,ekb,epsatm,ffspl,indlmn,lloc,lmax,lmnmax,lnmax,& 107 & mmax,mpsang,mpssoang,mqgrid,mqgrid_vl,nproj,n1xccc,pspso,qchrg,qgrid,qgrid_vl,& 108 & useylm,vlspl,xcccrc,xccc1d,zion,znucl,nctab,maxrad) 109 110 !Arguments ------------------------------------ 111 !scalars 112 integer,intent(in) :: lloc,lmax,lmnmax,lnmax,mpsang,mpssoang,mqgrid,mqgrid_vl 113 integer,intent(in) :: pspso,n1xccc,useylm 114 integer,intent(out) :: mmax 115 real(dp),intent(in) :: zion,znucl 116 real(dp),intent(out) :: epsatm,qchrg,xcccrc,maxrad 117 type(nctab_t),intent(inout) :: nctab 118 character(len=fnlen),intent(in) :: filpsp 119 !arrays 120 integer,intent(out) :: indlmn(6,lmnmax),nproj(mpssoang) 121 real(dp),intent(in) :: qgrid(mqgrid),qgrid_vl(mqgrid_vl) 122 real(dp),intent(out) :: ekb(lnmax),ffspl(mqgrid,2,lnmax),vlspl(mqgrid,2) 123 real(dp),intent(inout) :: xccc1d(n1xccc,6) !vz_i 124 125 !Local variables------------------------------- 126 !scalars 127 #if defined HAVE_LIBPSML 128 integer :: iln,pspindex,ipsang,irad,kk,ll 129 integer :: mm,nn,nso,ii,ir,il 130 integer :: nshells 131 integer :: iproj,irelt,nders 132 integer :: np_dn, np_lj, np_nr, np_so, np_sr, np_up, val_l, val_n 133 real(dp) :: amesh,damesh,fchrg,rchrg,yp1,ypn,zval 134 real(dp) :: rmax,rmatch,z,chgvps 135 real(dp) :: val_occ 136 logical :: has_nlcc,has_spin 137 logical :: has_tvale,oncvpsp 138 character(len=500) :: message 139 character(len=30) :: creator 140 character(len=7), parameter :: oncvpsp_name = "ONCVPSP" 141 type(pawrad_type) :: mesh 142 #endif 143 !arrays 144 #if defined HAVE_LIBPSML 145 integer, allocatable :: idx_so(:),idx_sr(:) 146 real(dp),allocatable :: rad(:),vloc(:),vpspll(:,:),work_spl(:) 147 type(ps_t) :: psxml 148 #endif 149 150 ! *************************************************************************** 151 152 #if defined HAVE_LIBPSML 153 154 call ps_destroy(psxml) 155 call psml_reader(filpsp,psxml,debug=.true.) 156 157 !Identify the atomic code that generated the pseudopotential 158 call ps_Provenance_Get(psxml, 1, creator=creator) 159 !Check whether the pseudopotential has been created with ONCVPSP, 160 !Don Hamann's code 161 oncvpsp = (trim(creator(1:7)) .eq. trim(oncvpsp_name)) 162 !DEBUG 163 !write(std_out,*)' psp9in : creator : ', creator 164 !write(std_out,*)' psp9in : oncvpsp : ', oncvpsp 165 !ENDDEBUG 166 167 ! SIESTA's ATOM uses spherical harmonics, while ONCVPSP uses Legendre 168 ! polynomials, which means we have to check the consistency of input variables 169 ! wrt the pseudos 170 ! 171 ! Note: commented because NC pseudos do not have non-diagonal terms 172 ! 173 ! if ( oncvpsp ) then 174 ! if ( useylm /= 0 ) then 175 ! write(message,'(3a)') "ONCVPSP pseudos use Legendre polynomials but we use spherical harmonics", & 176 !& ch10, "ACTION: set useylm to 0 in your input file" 177 ! ABI_ERROR(message) 178 ! endif 179 ! else 180 ! if ( useylm == 0 ) then 181 ! write(message,'(3a)') "ATOM pseudos use spherical harmonics but we use Legendre polynomials", & 182 !& ch10, "ACTION: set useylm to 1 in your input file" 183 ! ABI_ERROR(message) 184 ! endif 185 ! endif 186 187 ! The atomic number is a real number instead of a simple integer 188 ! z (in Abinit), atomic-number in the header of the PSML file. 189 ! z = ps_AtomicNumber(psxml) 190 ! 191 ! The difference between the number of protons in the nucleus and the 192 ! sum of the populations of the core shells is the effective atomic number 193 ! of the pseudo-atom, Zval (in Abinit), z-pseudo in the header of the 194 ! PSML file. 195 ! zval = ps_Zpseudo(psxml) 196 197 call ps_PseudoAtomSpec_Get(psxml, & 198 & atomic_number=z, z_pseudo=zval, & 199 & spin_dft=has_spin, core_corrections=has_nlcc) 200 201 !--- 202 203 !Feb 2015: shifted to Hamann grid for convenience - libpsml interpolates anyway 204 ! 205 ! The following lines are taken from the oncvpsp.f90 subroutine of the oncvpsp 206 ! code implemented by D. Hamann 207 ! The atomic number of the element is read from the header of the XML file 208 ! Logarithmic grid defined by Hamann in oncvpsp code 209 ! z = psxml%header%z 210 ! amesh = 1.012d0 211 ! al = dlog(amesh) 212 ! rr1 = .0005d0/z 213 ! mmax = dlog(45.0d0 /rr1)/al 214 ! 215 ! ABI_MALLOC( rad,(mmax) ) 216 ! 217 ! do ir = 1, mmax 218 ! rad(ir) = rr1 * dexp(al*(ir-1)) 219 ! end do 220 221 !Determine the maximum number of points in the grid --- 222 rmax = 6.0_dp 223 amesh = 0.01_dp 224 mmax = int(rmax/amesh) 225 ! if(mod(mmax,2) .eq. 0) mmax = mmax + 1 226 227 !Print core charge info, for compatibility with psp8 228 rchrg = zero 229 fchrg = zero 230 if (has_nlcc) then 231 rchrg = amesh * (mmax - 2) 232 ! PSML does not store fchrg for now but we know we have core corrections, 233 ! then let's set it arbitrarily to 1.0 234 fchrg = one 235 else 236 write(message, '(a)' ) '- psp9in: No XC core correction.' 237 call wrtout(std_out,message,'COLL') 238 end if 239 write(message, '(3f20.14,t64,a)' ) rchrg,fchrg,zero,'rchrg,fchrg,qchrg' 240 call wrtout(ab_out,message,'COLL') 241 call wrtout(std_out,message,'COLL') 242 243 !Do we have a valence charge? 244 call ps_ValenceConfiguration_Get(psxml, nshells=nshells) 245 has_tvale = (nshells > 0) 246 247 ! Compute the valence charge of the reference configuration used to 248 ! generate the pseudopotential 249 chgvps = 0.0_dp 250 ! Loop on all the shells included in the valence 251 do il = 1, nshells 252 ! Sum the corresponding occupation of each shell 253 ! FIXME: What if there is spin? 254 call ps_ValenceShell_Get(psxml, il, n=val_n, l=val_l, occupation=val_occ) 255 chgvps = chgvps + val_occ 256 write(std_out,*)' psp9in : n, l, occupation = ', & 257 & val_n, val_l, val_occ 258 end do 259 260 !DEBUG 261 !write(std_out,*)' psp9in : atomic number' 262 !write(std_out,*)' psp9in : z = ', z 263 !write(std_out,*)' psp9in : valence charge of the reference configuration' 264 !write(std_out,*)' psp9in : chgvps = ', chgvps 265 !write(std_out,*)' psp9in : nominal valence charge' 266 !write(std_out,*)' psp9in : zval = ', zval 267 !write(std_out,*)' psp9in : mqgrid_vl = ', mqgrid_vl 268 !write(std_out,*)' psp9in : parameters to define the points of the grid' 269 !write(std_out,*)' psp9in : amesh = ', amesh 270 !write(std_out,*)' psp9in : rmax = ', rmax 271 !write(std_out,*)' psp9in : mmax = ', mmax 272 !ENDDEBUG 273 274 ! TODO: should be simple to average these and get difference for SREL+SOC, 275 ! but also the Ekb etc... 276 call ps_NonlocalProjectors_Filter(psxml, set=SET_DOWN, number=np_dn) 277 call ps_NonlocalProjectors_Filter(psxml, set=SET_LJ, number=np_lj) 278 call ps_NonlocalProjectors_Filter(psxml, set=SET_NONREL, number=np_nr) 279 call ps_NonlocalProjectors_Filter(psxml, set=SET_SO, number=np_so) 280 call ps_NonlocalProjectors_Filter(psxml, set=SET_SREL, number=np_sr) 281 call ps_NonlocalProjectors_Filter(psxml, set=SET_UP, number=np_up) 282 if (np_lj > 0) then 283 message = 'For the moment LJ format projectors are not supported; SREL + SO is the internal abinit format' 284 ABI_BUG(message) 285 end if 286 287 if (np_up > 0 .or. np_dn > 0) then 288 write (message,'(3a)') 'For the moment separate spin up and down format projectors are not supported;',ch10,& 289 & ' spin average is the internal abinit format' 290 ABI_BUG(message) 291 end if 292 293 !-------------------------------------------------------------------- 294 295 !Initialize array indlmn giving l,m,n,lm,ln,s for i=lmn 296 if(pspso==2) then 297 nso=2 298 else 299 nso=1 300 end if 301 302 !Find the number of projectors per angular momentum shell 303 nproj(:)=0 304 if (np_nr > 0) then 305 call ps_NonlocalProjectors_Filter(psxml, set=SET_NONREL, indexes=idx_sr) 306 do iproj = 1, np_nr 307 call ps_Projector_Get(psxml, idx_sr(iproj), l=il) 308 nproj(il+1) = nproj(il+1) + 1 309 end do 310 else 311 if (np_sr > 0) then 312 call ps_NonlocalProjectors_Filter(psxml, set=SET_SREL, indexes=idx_sr) 313 do iproj = 1, np_sr 314 call ps_Projector_Get(psxml, idx_sr(iproj), l=il) 315 nproj(il+1) = nproj(il+1) + 1 316 end do 317 else ! this should not happen 318 ABI_BUG('Your psml potential should have either scalar- or non- relativistic projectors') 319 end if 320 end if 321 322 write(message, '(a,5i6)' ) ' nproj',nproj(1:lmax+1) 323 call wrtout(ab_out,message,'COLL') 324 call wrtout(std_out, message,'COLL') 325 326 irelt = 0 327 if (nso == 2) then 328 call ps_NonlocalProjectors_Filter(psxml, set=SET_SO, indexes=idx_so) 329 do iproj = 1, np_so 330 call ps_Projector_Get(psxml, idx_so(iproj), l=il) 331 nproj(il+lmax+2) = nproj(il+lmax+2) + 1 332 irelt = 1 333 end do 334 end if 335 336 pspindex=0;iln=0;indlmn(:,:)=0 337 do nn=1,nso 338 do ipsang=1+(nn-1)*(lmax+1),nn*lmax+1 339 ll=ipsang-(nn-1)*lmax-1 340 if (nproj(ipsang)>0) then 341 do kk=1,nproj(ipsang) 342 iln=iln+1 343 do mm=1,2*ll*useylm+1 344 pspindex=pspindex+1 345 indlmn(1,pspindex)=ll ! l angular momentum channel 346 indlmn(2,pspindex)=mm-ll*useylm-1 ! hash of position in m 347 indlmn(3,pspindex)=kk ! index of projector 348 indlmn(4,pspindex)=ll*ll+(1-useylm)*ll+mm ! hash of position in l(l+1) array 349 indlmn(5,pspindex)=iln ! absolute index of l, n disregarding m values 350 indlmn(6,pspindex)=nn ! spin orbit index!!! NOT the n shell index 351 end do 352 end do 353 end if 354 end do 355 end do 356 357 ! Determine whether the atomic calculation to generate the pseudopotential 358 ! is relativistic or not 359 360 !DEBUG 361 !write(std_out,*)' psp9in : pseudopotential generation relativity ', ps_Relativity(psxml) 362 !write(std_out,*)' psp9in : SOC pseudopotential? (1=yes, 0 =no) ' 363 !write(std_out,*)' psp9in : irelt = ', irelt 364 !write(ab_out,*)' psp9in : irelt = ', irelt 365 !ENDDEBUG 366 367 !Can now allocate grids, potentials and projectors 368 ABI_MALLOC(rad,(mmax)) 369 ABI_MALLOC(vloc,(mmax)) 370 ABI_MALLOC(vpspll,(mmax,lnmax)) 371 372 !Feb 2015: shifted to Hamann grid for convenience - libpsml interpolates anyway 373 do ir=1,mmax 374 rad(ir) = amesh * (ir - 1) 375 end do 376 !! DEBUG 377 ! do ir = 2, mmax 378 ! write(std_out,'(i5,f20.12)')ir, rad(ir) 379 ! end do 380 !! ENDDEBUG 381 !--- 382 write(message, '(a,i5,es16.6,es16.6)')' psp9in : mmax, amesh, rad(mmax) = ', mmax, amesh, rad(mmax) 383 call wrtout(ab_out,message,'COLL') 384 call wrtout(std_out,message,'COLL') 385 386 !Check that rad grid is linear starting at zero 387 amesh=rad(2)-rad(1) 388 damesh=zero 389 do irad=2,mmax-1 390 damesh=max(damesh,abs(rad(irad)+amesh-rad(irad+1))) 391 end do 392 if(damesh>tol8 .or. rad(1)/=zero) then 393 write(message, '(5a)' )& 394 & 'Pseudopotential input file requires linear radial mesh',ch10,& 395 & 'starting at zero.',ch10,& 396 & 'Action: check your pseudopotential input file.' 397 ABI_ERROR(message) 398 end if 399 400 !Take care of the non-linear core corrections 401 !---------------------------------------------------------------------------- 402 ! xcccrc : XC core correction cutoff radius (bohr) 403 ! It is defined as the radius where the pseudo-core 404 ! charge density becomes zero 405 ! (here we have set up a tolerance of 1.d-12). 406 407 rmatch = zero 408 nders = 0 409 if (has_nlcc) then 410 411 ! In Abinit, at least for the Troullier-Martins pseudopotential, 412 ! the pseudocore charge density and its derivatives (xccc1d) 413 ! are introduced in a linear grid. 414 ! This grid is normalized, so the radial coordinates run between 415 ! from 0 and 1 (from 0 to xcccrc, where xcccrc is the radius 416 ! where the pseudo-core becomes zero). 417 418 call ps_CoreCharge_get(psxml, rc=rmatch, nderivs=nders) 419 write (message,'(1X,A,A,5X,A,1X,F8.3,A,5X,A,I8,A)') & 420 & "Reading pseudocore charge",ch10, & 421 & "- matching radius:",rmatch,ch10, & 422 & "- number of continuous derivatives",nders,ch10 423 call wrtout(std_out,message,'COLL') 424 425 !Get core charge function and derivatives, if needed 426 if(fchrg>1.0d-15)then 427 call psp9cc(psxml,mmax,n1xccc,rad,rchrg,xccc1d) 428 ! The core charge function for pspcod=9 429 ! becomes zero beyond rchrg. Thus xcccrc must be set 430 ! equal to rchrg. 431 xcccrc=rchrg 432 else 433 xccc1d(:,:) = zero 434 xcccrc = zero 435 fchrg = zero 436 qchrg = zero 437 end if 438 439 maxrad = rad(mmax) 440 441 end if ! has_nlcc 442 443 !! DEBUG 444 ! write(std_out,*)' xcccrc = ', xcccrc, rchrg 445 ! write(std_out,*) 446 ! write(std_out,*) '# psp8in NLCC data ', n1xccc, xcccrc 447 ! do ii = 1, n1xccc 448 ! write(std_out,'(7e20.8)')xcccrc*(ii-1.d0)/(n1xccc-1.d0),xccc1d(ii,1),& 449 ! & xccc1d(ii,2),xccc1d(ii,3),xccc1d(ii,4),xccc1d(ii,5),xccc1d(ii,6) 450 ! enddo 451 ! write(std_out,*) 452 ! stop 453 !! ENDDEBUG 454 455 456 !-------------------------------------------------------------------- 457 !Carry out calculations for local (lloc) pseudopotential. 458 !Obtain Fourier transform (1-d sine transform) 459 !to get q^2 V(q). 460 461 !Read and process vlocal: 462 !The local potential is given by a <radfunc> element under the <local-potential> 463 !element. 464 !After reading, this is a copy of the treatment to the 465 !local part carry out in psp8 466 !i.e. (as in Hamann pseudopotential) 467 ! 468 !Read the local component of the pseudopotential 469 vloc = zero 470 do ir = 1, mmax 471 vloc(ir) = ps_LocalPotential_Value(psxml, rad(ir)) 472 end do 473 474 call psp8lo(amesh,epsatm,mmax,mqgrid,qgrid,& 475 & vlspl(:,1),rad,vloc,yp1,ypn,zion) 476 477 !Fit spline to q^2 V(q) (Numerical Recipes subroutine) 478 ABI_MALLOC(work_spl,(mqgrid)) 479 call spline (qgrid,vlspl(:,1),mqgrid,yp1,ypn,work_spl) 480 vlspl(:,2)=work_spl(:) 481 ABI_FREE(work_spl) 482 483 !! DEBUG 484 ! write(std_out,*)'# Vlocal = ' 485 ! write(std_out,*)' amesh = ', amesh 486 ! write(std_out,*)' epsatm = ', epsatm 487 ! write(std_out,*)' mmax = ', mmax 488 ! write(std_out,*)' mqgrid = ', mqgrid 489 ! do ir = 1, mqgrid 490 ! write(std_out,*)' qgrid = ', ir, qgrid(ir) 491 ! enddo 492 ! do ir = 1, mqgrid 493 ! write(std_out,'(a,i5,2f20.12)')' iq, vlspl = ', ir, vlspl(ir,1), vlspl(ir,2) 494 ! enddo 495 ! write(std_out,*) 496 ! do ir = 1, mmax 497 ! write(std_out,*)' rad = ', rad(ir), vloc(ir) 498 ! enddo 499 ! write(std_out,*) 500 ! write(std_out,*)' yp1 = ', yp1 501 ! write(std_out,*)' ypn = ', ypn 502 ! write(std_out,*)' zion = ', zion 503 ! stop 504 !! ENDDEBUG 505 506 507 !-------------------------------------------------------------------- 508 !Take care of non-local part 509 510 !Zero out all Kleinman-Bylander energies to initialize 511 do ii = 1, lmnmax ! loop over all possible projectors 512 if (indlmn(6,ii) == 1) then 513 call ps_Projector_Get(psxml, idx_sr(indlmn(5,ii)), ekb=ekb(indlmn(5,ii))) 514 else if (indlmn(6,ii) == 2) then 515 call ps_Projector_Get(psxml, idx_so(indlmn(5,ii)), ekb=ekb(indlmn(5,ii))) 516 end if 517 end do 518 519 !Read the KB projectors from the PSML file 520 !Note than in the PSML file the radial part of the projector is stored, 521 !while Abinit expects the radial part times the radii. 522 !We have to multiply by r after reading it. 523 !Note than in Hamann's format (psp8), Abinit directly reads r * radial_part_KB 524 vpspll = zero 525 do ii = 1, lmnmax 526 if (indlmn(6,ii) == 1) then 527 do ir = 1, mmax 528 vpspll(ir, indlmn(5,ii)) = ps_Projector_Value(psxml, idx_sr(indlmn(5,ii)), rad(ir)) 529 vpspll(ir, indlmn(5,ii)) = rad(ir) * vpspll(ir, indlmn(5,ii)) 530 end do 531 else if (indlmn(6,ii) == 2) then 532 do ir = 1, mmax 533 vpspll(ir, indlmn(5,ii)) = ps_Projector_Value(psxml, idx_so(indlmn(5,ii)), rad(ir)) 534 vpspll(ir, indlmn(5,ii)) = rad(ir) * vpspll(ir, indlmn(5,ii)) 535 end do 536 end if 537 end do 538 539 !Allow for option of no nonlocal corrections (lloc=lmax=0) 540 if (lloc==0.and.lmax==0) then 541 write(message, '(a,f5.1)' ) ' Note: local psp for atom with Z=',znucl 542 call wrtout(ab_out,message,'COLL') 543 call wrtout(std_out,message,'COLL') 544 else 545 546 ! ---------------------------------------------------------------------- 547 ! Compute Vanderbilt-KB form factors and fit splines 548 549 call psp8nl(amesh,ffspl,indlmn,lmax,lmnmax,lnmax,mmax,& 550 & mqgrid,qgrid,rad,vpspll) 551 552 end if 553 554 !! DEBUG 555 ! write(std_out,*)'# KB Projectors = ' 556 ! write(std_out,*)' amesh = ', amesh 557 ! do ir = 1, mqgrid 558 ! do il = 1, lnmax 559 ! write(std_out,*)' iq, il, ffspl = ', ir, il, ffspl(ir,1,il), ffspl(ir,2,il) 560 ! enddo 561 ! enddo 562 ! do il = 1, lmnmax 563 ! write(std_out,*)' indlmn = ', il, indlmn(:,il) 564 ! enddo 565 ! write(std_out,*)' lmax = ', lmax 566 ! write(std_out,*)' lmnmax = ', lmnmax 567 ! write(std_out,*)' lnmax = ', lnmax 568 ! write(std_out,*)' mmax = ', mmax 569 ! write(std_out,*)' mqgrid = ', mqgrid 570 ! do ir = 1, mqgrid 571 ! write(std_out,*)' qgrid = ', ir, qgrid(ir) 572 ! enddo 573 ! do il = 1, lnmax 574 ! write(std_out,*) 575 ! write(std_out,*)'# il = ', il 576 ! do ir = 1, mmax 577 ! write(std_out,*)' rad = ', rad(ir), vpspll(ir,il) 578 ! enddo 579 ! enddo 580 ! stop 581 !! ENDDEBUG 582 583 ! Read pseudo valence charge in real space on the linear mesh 584 ! and transform it to reciprocal space on a regular grid. Use vloc as workspace. 585 vloc(:) = zero 586 if (has_tvale) then 587 do irad=1,mmax 588 vloc(irad) = ps_ValenceCharge_Value(psxml,rad(irad)) 589 vloc(irad) = vloc(irad) / four_pi 590 end do 591 592 !! DEBUG 593 ! do irad = 1, mmax 594 ! write(std_out,*)' Valence Charge = ', rad(irad), vloc(irad) 595 ! enddo 596 ! stop 597 !! ENDDEBUG 598 599 600 ! Check that rad grid is linear starting at zero 601 amesh=rad(2)-rad(1) 602 damesh=zero 603 do irad=2,mmax-1 604 damesh=max(damesh,abs(rad(irad)+amesh-rad(irad+1))) 605 end do 606 if(damesh>tol8 .or. rad(1)/=zero) then 607 write(message, '(5a)' )& 608 & 'Pseudopotential input file requires linear radial mesh',ch10,& 609 & 'starting at zero.',ch10,& 610 & 'Action: check your pseudopotential input file.' 611 ABI_ERROR(message) 612 end if 613 614 ! Evaluate spline-fit of the atomic pseudo valence charge in reciprocal space. 615 call pawrad_init(mesh,mesh_size=mmax,mesh_type=1,rstep=amesh) 616 call nctab_eval_tvalespl(nctab, zion, mesh, vloc, mqgrid_vl, qgrid_vl) 617 call pawrad_free(mesh) 618 end if 619 620 ABI_FREE(vpspll) 621 ABI_FREE(vloc) 622 ABI_FREE(rad) 623 if (allocated(idx_sr)) then 624 ABI_FREE_NOCOUNT(idx_sr) 625 end if 626 if (allocated(idx_so)) then 627 ABI_FREE_NOCOUNT(idx_so) 628 end if 629 630 call ps_destroy(psxml) 631 632 !-------------------------------------------------------------------- 633 634 #else 635 ABI_UNUSED(mpsang) 636 ABI_UNUSED(pspso) 637 ABI_UNUSED(qgrid_vl) 638 ABI_UNUSED(nctab%mqgrid_vl) 639 !Initialize some arguments, for portability at compile time 640 indlmn=0 ; mmax=0 ; nproj=0 641 ekb=zero ; epsatm=zero ; ffspl=zero ; qchrg=zero ; vlspl=zero ; xcccrc=zero ; xccc1d=zero 642 643 if(.false.)write(std_out,*)filpsp ! Just to keep filpsp when HAVE_LIBPSML is false 644 if(.false.)write(std_out,*)lloc ! Just to keep lloc when HAVE_LIBPSML is false 645 if(.false.)write(std_out,*)lmax ! Just to keep lmax when HAVE_LIBPSML is false 646 if(.false.)write(std_out,*)mpsang ! Just to keep mpsang when HAVE_LIBPSML is false 647 if(.false.)write(std_out,*)pspso ! Just to keep pspso when HAVE_LIBPSML is false 648 if(.false.)write(std_out,*)qgrid ! Just to keep qgrid when HAVE_LIBPSML is false 649 if(.false.)write(std_out,*)qgrid_vl ! Just to keep qgrid_vl when HAVE_LIBPSML is false 650 if(.false.)write(std_out,*)useylm ! Just to keep useylm when HAVE_LIBPSML is false 651 if(.false.)write(std_out,*)zion ! Just to keep zion when HAVE_LIBPSML is false 652 if(.false.)write(std_out,*)znucl ! Just to keep znucl when HAVE_LIBPSML is false 653 #endif 654 655 end subroutine psp9in