/atomic/read_pseudo_ncpp.f90

http://github.com/NNemec/quantum-espresso · Fortran Modern · 218 lines · 145 code · 17 blank · 56 comment · 24 complexity · f9480f605d1bd07bb198af027856de89 MD5 · raw file

  1. !
  2. ! Copyright (C) 2004 PWSCF group
  3. ! This file is distributed under the terms of the
  4. ! GNU General Public License. See the file `License'
  5. ! in the root directory of the present distribution,
  6. ! or http://www.gnu.org/copyleft/gpl.txt .
  7. !
  8. !-----------------------------------------------------------------------
  9. subroutine read_pseudo_ncpp (file_pseudo,zed,grid,ndmx,&
  10. dft,lmax,lloc,zval,nlcc,rhoc,vnl,vpsloc,rel)
  11. !-----------------------------------------------------------------------
  12. !
  13. use kinds, only : DP
  14. use constants, only : fpi
  15. use radial_grids, only: radial_grid_type, do_mesh
  16. implicit none
  17. !
  18. ! I/O variables
  19. !
  20. type (radial_grid_type), intent(out):: grid
  21. !
  22. integer :: &
  23. ndmx, & ! input: the mesh dimensions
  24. rel, & ! input: rel=2 for spin-orbit pseudopotential
  25. mesh,& ! output: the number of mesh points
  26. lmax,& ! output: the maximum angular momentum
  27. lloc ! output: the local potential
  28. real(DP) :: &
  29. zed, & ! input: the atomic charge
  30. zval, & ! output: the valence charge
  31. ! xmin,dx, & ! output: the mesh
  32. ! rmax, & ! output: the maximum mesh value
  33. ! r(ndmx),r2(ndmx), & ! output: the mesh
  34. ! rab(ndmx), & ! output: derivative of the mesh
  35. ! sqr(ndmx), & ! output: the square root of the mesh
  36. vnl(ndmx,0:3,2), & ! output: the potential in numerical form
  37. vpsloc(ndmx), & ! output: the local pseudopotential
  38. rhoc(ndmx) ! output: the core charge
  39. real(DP) :: xmin, dx, rmax ! auxiliary mesh data
  40. logical :: &
  41. nlcc ! output: if true the pseudopotential has nlcc
  42. character :: &
  43. file_pseudo*20, & ! input: the file with the pseudopotential
  44. dft*20 ! output: the type of xc
  45. integer :: &
  46. ios, i, l, k, ir, iunps, nbeta,nlc,nnl
  47. real(DP) :: &
  48. vnloc, a_core, b_core, alfa_core, &
  49. cc(2),alpc(2),alc(6,0:3),alps(3,0:3)
  50. real(DP), external :: qe_erf
  51. logical :: &
  52. bhstype, numeric
  53. character(len=3) cdum
  54. iunps=2
  55. open(unit=iunps,file=file_pseudo,status='old',form='formatted', &
  56. err=100, iostat=ios)
  57. 100 call errore('read_pseudo_ncpp','open error on file '//file_pseudo,ios)
  58. !
  59. ! reads the starting lines
  60. !
  61. read( iunps, '(a)', end=300, err=300, iostat=ios ) dft
  62. if (dft(1:2).eq.'**') dft='LDA'
  63. if (dft(1:17).eq.'slater-pz-ggx-ggc') dft='PW'
  64. read ( iunps, *, err=300, iostat=ios ) cdum, &
  65. zval, lmax, nlc, nnl, nlcc, &
  66. lloc, bhstype
  67. if ( nlc.gt.2 .or. nnl.gt.3) &
  68. call errore( 'read_pseudo_ncpp','Wrong nlc or nnl', 1)
  69. if ( nlc .lt.0 .or. nnl .lt. 0 ) &
  70. call errore( 'read_pseudo_ncpp','nlc or nnl < 0 ? ', 1 )
  71. if ( zval.le.0.0_dp ) &
  72. call errore( 'read_pseudo_ncpp','Wrong zval ', 1 )
  73. !
  74. ! In numeric pseudopotentials both nlc and nnl are zero.
  75. !
  76. numeric = nlc.le.0 .and. nnl.le.0
  77. if (lloc.eq.-1000) lloc=lmax
  78. if (.not.numeric) then
  79. read( iunps, *, err=300, iostat=ios ) &
  80. ( alpc(i), i=1, 2 ), ( cc(i), i=1,2 )
  81. if ( abs(cc(1)+cc(2)-1.0_dp).gt.1.0e-6_dp) call errore &
  82. ('read_pseudo_ncpp','wrong pseudopotential coefficients',1)
  83. do l = 0, lmax
  84. read ( iunps, *, err=300, iostat=ios ) &
  85. ( alps(i,l),i=1,3 ), (alc(i,l),i=1,6)
  86. enddo
  87. if (nlcc) then
  88. read( iunps, *, err=300, iostat=ios ) a_core, &
  89. b_core, alfa_core
  90. if (alfa_core.le.0.0_dp) &
  91. call errore('readin','nlcc but alfa=0',1)
  92. endif
  93. if (cc(2).ne.0.0_dp.and.alpc(2).ne.0.0_dp.and.bhstype) then
  94. call bachel(alps,alc,1,lmax)
  95. endif
  96. endif
  97. !
  98. ! read the mesh parameters
  99. !
  100. read( iunps, *, err=300, iostat=ios ) zed, xmin, dx, mesh, nbeta
  101. rmax=exp( (mesh-1)*dx+xmin )/zed
  102. !
  103. ! and generate the mesh: this overwrites the mesh defined in the
  104. ! input parameters
  105. !
  106. call do_mesh(rmax,zed,xmin,dx,0,grid)
  107. if (mesh.ne.grid%mesh) &
  108. call errore('read_pseudo_ncpp','something wrong in mesh',1)
  109. !
  110. ! outside this routine all pseudo are numeric: construct vnl and
  111. ! core charge
  112. !
  113. if (.not.numeric) then
  114. !
  115. ! obsolescent format with analytical coefficients
  116. !
  117. read( iunps, '(a)', err=300, iostat=ios ) cdum
  118. if (nlcc) then
  119. do ir=1, mesh
  120. rhoc(ir)=(a_core+b_core*grid%r2(ir))*exp(-alfa_core*grid%r2(ir)) &
  121. *grid%r2(ir)*fpi
  122. enddo
  123. else
  124. rhoc=0.0_dp
  125. endif
  126. do l=0,lmax
  127. do ir=1,mesh
  128. vnloc = 0.0_dp
  129. do k=1,3
  130. vnloc = vnloc + exp(-alps(k,l)*grid%r2(ir))* &
  131. ( alc(k,l) + grid%r2(ir)*alc(k+3,l) )
  132. enddo
  133. !
  134. ! NB: the factor 2 converts from hartree to rydberg
  135. ! spin-orbit not implemented for analytical PP
  136. !
  137. vnl(ir,l,1) = 2.0_dp*vnloc
  138. enddo
  139. enddo
  140. do ir=1,mesh
  141. vpsloc(ir) = -2.0_dp*zval/grid%r(ir)* &
  142. ( cc(1)*qe_erf(grid%r(ir)*sqrt(alpc(1))) &
  143. + cc(2)*qe_erf(grid%r(ir)*sqrt(alpc(2))) )
  144. end do
  145. endif
  146. if (numeric) then
  147. !
  148. ! pseudopotentials in numerical form
  149. !
  150. do l = 0, lmax
  151. read( iunps, '(a)', err=300, iostat=ios ) cdum
  152. read( iunps, *, err=300, iostat=ios ) &
  153. (vnl(ir,l,1),ir=1,mesh)
  154. if (rel ==2 .and. l > 0) then
  155. !
  156. read( iunps, '(a)', err=300, iostat=ios ) cdum
  157. read( iunps, *, err=300, iostat=ios ) &
  158. (vnl(ir,l,2),ir=1,mesh)
  159. endif
  160. enddo
  161. !
  162. ! the local part is subtracted from the non-local part
  163. ! and stored in vpsloc - just for consistency
  164. !
  165. if (lloc == -1) then
  166. read( iunps, '(a)', err=300, iostat=ios )
  167. read( iunps, *, err=300, iostat=ios ) &
  168. (vpsloc(ir),ir=1,mesh)
  169. else if (rel < 2) then
  170. vpsloc(1:mesh) = vnl(1:mesh,lloc,1)
  171. else
  172. vpsloc(1:mesh) = (l*vnl(1:mesh,lloc,1)+(l+1)*vnl(1:mesh,lloc,2)) / &
  173. (2*l+1)
  174. end if
  175. do l=0,lmax
  176. vnl(1:mesh,l,1) = vnl(1:mesh,l,1) - vpsloc(1:mesh)
  177. if (rel == 2) vnl(1:mesh,l,2) = vnl(1:mesh,l,2) - vpsloc(1:mesh)
  178. end do
  179. !
  180. if(nlcc) then
  181. read( iunps, *, err=300, iostat=ios ) &
  182. ( rhoc(ir), ir=1,mesh )
  183. do ir=1, mesh
  184. rhoc(ir)=rhoc(ir)*grid%r2(ir)*fpi
  185. enddo
  186. else
  187. rhoc=0.0_dp
  188. endif
  189. endif
  190. 300 call errore('read_pseudo_ncpp','reading pseudofile',abs(ios))
  191. !
  192. ! all the components of the nonlocal potential beyond lmax are taken
  193. ! equal to the local part
  194. !
  195. do l=lmax+1,3
  196. vnl(1:mesh,l,1)=vpsloc(1:mesh)
  197. if (rel ==2 .and. l > 0) vnl(1:mesh,l,2)=vpsloc(1:mesh)
  198. enddo
  199. close(iunps)
  200. return
  201. end subroutine read_pseudo_ncpp