Branch data Line data Source code
1 : : !!****m* ABINIT/m_upf2abinit
2 : : !! NAME
3 : : !! m_upf2abinit
4 : : !!
5 : : !! FUNCTION
6 : : !! Procedures to read NC pseudos in UPF1/UPF2 format and convert data into
7 : : !! the internal ABINIT representation.
8 : : !!
9 : : !! COPYRIGHT
10 : : !! Copyright (C) 2009-2026 ABINIT group (MJV, MG, DRH)
11 : : !! This file is distributed under the terms of the
12 : : !! GNU General Public License, see ~abinit/COPYING
13 : : !! or http://www.gnu.org/copyleft/gpl.txt .
14 : : !!
15 : : !! SOURCE
16 : :
17 : : #if defined HAVE_CONFIG_H
18 : : #include "config.h"
19 : : #endif
20 : :
21 : : #include "abi_common.h"
22 : :
23 : : module m_upf2abinit
24 : :
25 : : use defs_basis
26 : : use m_abicore
27 : : use m_errors
28 : : use m_atomdata
29 : : use m_splines
30 : :
31 : : use defs_datatypes, only : pseudopotential_type
32 : : use m_io_tools, only : open_file
33 : : use m_numeric_tools, only : smooth, nderiv, ctrap
34 : : use m_copy, only : alloc_copy
35 : : use m_paw_numeric, only : jbessel => paw_jbessel
36 : : use m_pawpsp, only : pawpsp_nl
37 : : use m_pawrad, only : pawrad_type, pawrad_init, pawrad_free, simp_gen
38 : : use m_psptk, only : cc_derivatives, psp8lo, psp8nl
39 : :
40 : : implicit none
41 : :
42 : : private
43 : : !!***
44 : :
45 : : public :: upf1_to_abinit
46 : : public :: upf2_to_abinit
47 : : !!***
48 : :
49 : : contains
50 : : !!***
51 : :
52 : : !!****f* ABINIT/upf1_to_abinit
53 : : !! NAME
54 : : !! upf1_to_abinit
55 : : !!
56 : : !! FUNCTION
57 : : !! This routine wraps a call to a PWSCF module, which reads in
58 : : !! a UPF1 (PWSCF / Espresso) format pseudopotential, then transfers
59 : : !! data to abinit internal variables.
60 : : !! "UPF1 PWSCF format" (pspcod=11)
61 : : !!
62 : : !! INPUTS
63 : : !! filpsp = name of file with UPF data
64 : : !! psps = sturcture with global dimension data for pseudopotentials, header info ...
65 : : !! used contents:
66 : : !! psps%lmnmax
67 : : !! psps%mqgrid_ff
68 : : !! psps%mqgrid_vl
69 : : !! psps%dimekb
70 : : !! psps%n1xccc
71 : : !! psps%qgrid_ff
72 : : !! psps%qgrid_vl
73 : : !!
74 : : !! OUTPUT
75 : : !! pspxc = index of xc functional for this pseudo
76 : : !! lmax_ = maximal angular momentum
77 : : !! lloc = local component chosen for pseudopotential
78 : : !! mmax = maximum number of points in real space radial grid
79 : : !! znucl = charge of species nucleus
80 : : !! zion = valence charge
81 : : !! epsatm = integral of local potential - coulomb potential of zion
82 : : !! xcccrc = radius for non linear core correction
83 : : !! ekb(dimekb)= Kleinman Bylander energies, see pspatm.F90
84 : : !! epsatm=$ (4\pi)\int_0^\infty [r^2 (V(r)+\frac{Zv}{r}) dr]$(hartree)
85 : : !! indlmn(6,i)= array giving l,m,n,lm,ln,s for i=ln (if useylm=0)
86 : : !! or i=lmn (if useylm=1)
87 : : !! vlspl(mqgrid_vl,2)=q^2 Vloc(q) and second derivatives from spline fit
88 : : !! ffspl(mqgrid_ff,2,lnmax)=Kleinman-Bylander form factor f_l(q) and
89 : : !! second derivative from spline fit for each angular momentum and
90 : : !! each projector; if any, spin-orbit components begin at l=mpsang+1
91 : : !! nproj= number of projectors for each channel
92 : : !! xccc1d(n1xccc*(1-usepaw),6)=1D core charge function and five derivatives,
93 : : !! from psp file (used in NC only)
94 : : !!
95 : : !! SOURCE
96 : :
97 : 1 : subroutine upf1_to_abinit(filpsp, znucl, zion, pspxc, lmax_, lloc, mmax, &
98 : 1 : psps, epsatm, xcccrc, indlmn, ekb, ffspl, nproj_l, vlspl, xccc1d)
99 : :
100 : :
101 : : use pseudo_pwscf ! pwscf module with all data explicit!
102 : : use m_read_upf_pwscf, only : read_pseudo
103 : : use m_pspheads, only : upfxc2abi
104 : :
105 : : !Arguments -------------------------------
106 : : character(len=fnlen), intent(in) :: filpsp
107 : : type(pseudopotential_type),intent(in) :: psps
108 : : integer, intent(out) :: pspxc, lmax_, lloc, mmax
109 : : real(dp), intent(out) :: znucl, zion
110 : : real(dp), intent(out) :: epsatm, xcccrc
111 : : !arrays
112 : : integer, intent(out) :: indlmn(6,psps%lmnmax)
113 : : integer, intent(out) :: nproj_l(psps%mpssoang)
114 : : real(dp), intent(inout) :: ekb(psps%dimekb)
115 : : real(dp), intent(inout) :: ffspl(psps%mqgrid_ff,2,psps%lnmax)
116 : : real(dp), intent(out) :: vlspl(psps%mqgrid_vl,2)
117 : : real(dp), intent(inout) :: xccc1d(psps%n1xccc,6)
118 : :
119 : : !Local variables -------------------------
120 : : integer :: ir, iproj, ll, iunit
121 : : real(dp) :: yp1, ypn
122 : : character(len=500) :: msg
123 : : type(atomdata_t) :: atom
124 : 1 : logical, allocatable :: found_l(:)
125 : 1 : real(dp), allocatable :: work_spl(:), ff(:), ff1(:), ff2(:), rad_cc(:), proj(:,:)
126 : :
127 : : ! *********************************************************************
128 : :
129 : : ! ######### in module pseudo: ############
130 : : !
131 : : ! only npsx = 1 is used here
132 : : ! grids are allocated for much larger fixed length (ndm=2000)
133 : : ! number of species (6) and projectors (8) as well...
134 : : !
135 : : ! psd(npsx) = specied string
136 : : ! pseudotype = uspp / nc string
137 : : ! dft(npsx) = exchange correlation string (20 chars)
138 : : ! lmax(npsx) = maximum l channel
139 : : ! mesh(npsx) = number of points for local pot
140 : : ! nbeta(npsx) = number of projectors (beta functions for uspp)
141 : : ! nlcc(npsx) = flag for presence of NL core correction
142 : : ! zp(npsx) = valence ionic charge
143 : : ! r(ndm,npsx) = radial mesh
144 : : ! rab(ndm,npsx) = dr / di for radial mesh
145 : : ! rho_atc(ndm,npsx) = NLCC pseudocharge density
146 : : ! rho_at(ndm,npsx) = pseudocharge density
147 : : ! vloc0(ndm,npsx) = local pseudopotential
148 : : ! betar(ndm, nbrx, npsx) = projector functions in real space mesh
149 : : ! lll(nbrx,npsx) = angular momentum channel for each projector
150 : : ! ikk2(nbrx,npsx) = maximum index for each projector function
151 : : ! dion(nbrx,nbrx,npsx) = dij or Kleinman Bylander energies
152 : : !
153 : : ! ######## end description of pseudo module contents ##########
154 : :
155 [ - + ]: 1 : if (open_file (filpsp,msg,newunit=iunit,status='old',form='formatted') /= 0) then
156 : 0 : ABI_ERROR(msg)
157 : : end if
158 : :
159 : : ! read in psp data to static data in pseudo module, for ipsx == 1
160 : 1 : call read_pseudo(1,iunit)
161 : 1 : close (iunit)
162 : :
163 : : ! convert from Rydberg to Ha units
164 [ + + + + ]: 12007 : vloc0 = half * vloc0
165 [ + + + + : 439 : dion = half * dion
+ + ]
166 : :
167 : : ! if upf file is a USPP one, stop
168 [ - + ]: 1 : if (pseudotype == 'US') then
169 : 0 : ABI_ERROR('upf1_to_abinit: USPP UPF files not supported')
170 : : end if
171 : :
172 : : ! copy over to abinit internal arrays and vars
173 : : ! FIXME: The API is broken. It does not recognize PBEsol
174 : : ! should use upfdft_to_ixc
175 : 1 : call upfxc2abi(dft(1), pspxc)
176 : 1 : lmax_ = lmax(1)
177 : :
178 : : ! Check if the local component is one of the angular momentum channels
179 : : ! effectively if one of the ll is absent from the NL projectors
180 [ - + + - : 3 : ABI_MALLOC(found_l, (0:lmax_))
+ - + - -
+ - + ]
181 [ + + ]: 5 : found_l = .true.
182 [ + + ]: 5 : do ll = 0, lmax_
183 [ + + + + : 11 : if (any(lll(1:nbeta(1),1) == ll)) found_l(ll) = .false.
+ + ]
184 : : end do
185 : :
186 [ + + + + : 5 : if (count(found_l) /= 1) then
- + ]
187 : 0 : lloc = -1
188 : : else
189 [ + - ]: 3 : do ll = 0, lmax_
190 [ + + ]: 3 : if (found_l(ll)) then
191 : 1 : lloc = ll
192 : 1 : exit
193 : : end if
194 : : end do
195 : : end if
196 : :
197 [ - + ]: 1 : ABI_FREE(found_l)
198 : : !FIXME: do something about lloc == -1
199 : :
200 : 1 : call atomdata_from_symbol(atom,psd(1))
201 : 1 : znucl = atom%znucl
202 : 1 : zion = zp(1)
203 : 1 : mmax = mesh(1)
204 : :
205 : : call psp11lo(rab(1:mmax,1), epsatm, mmax, psps%mqgrid_vl, psps%qgrid_vl, &
206 : 1 : vlspl(:,1), r(1:mmax,1), vloc0(1:mmax,1), yp1, ypn, zion)
207 : :
208 : :
209 : : ! Fit spline to q^2 V(q) (Numerical Recipes subroutine)
210 [ - + + - : 3 : ABI_MALLOC(work_spl, (psps%mqgrid_vl))
+ - + - -
+ - + ]
211 : :
212 : 1 : call spline (psps%qgrid_vl,vlspl(:,1),psps%mqgrid_vl,yp1,ypn,work_spl)
213 : :
214 [ + + ]: 3002 : vlspl(:,2) = work_spl(:)
215 [ - + ]: 1 : ABI_FREE(work_spl)
216 : :
217 : : ! this has to do the FT of the projectors to reciprocal space
218 : : ! allocate proj to avoid temporary copy.
219 [ - + + - : 4 : ABI_MALLOC(proj, (mmax,1:nbeta(1)))
- + + - +
- + - - +
- + ]
220 [ - + + + : 1805 : proj = betar(1:mmax,1:nbeta(1), 1)
+ + ]
221 : :
222 : : call psp11nl(ffspl, indlmn, mmax, psps%lnmax, psps%lmnmax, psps%mqgrid_ff, &
223 : : nbeta(1), proj, lll(1:nbeta(1),1), ikk2(1:nbeta(1),1), &
224 : 1 : psps%qgrid_ff, r(1:mmax,1), rab(1:mmax,1), psps%useylm)
225 : :
226 [ - + ]: 1 : ABI_FREE(proj)
227 : :
228 [ + + ]: 5 : nproj_l = 0
229 [ + + ]: 4 : do iproj = 1, nbeta(1)
230 : 3 : ll = lll(iproj,1)
231 : 4 : nproj_l(ll+1) = nproj_l(ll+1) + 1
232 : : end do
233 : :
234 : : ! shape = dimekb vs. shape = n_proj
235 [ + + ]: 4 : do ll = 1, nbeta(1)
236 : 4 : ekb(ll) = dion(ll,ll,1)
237 : : end do
238 : :
239 [ + + + + ]: 15013 : xcccrc = zero; xccc1d = zero
240 : : ! if we find a core density, do something about it
241 : : ! rho_atc contains the nlcc density
242 : : ! rho_at contains the total density
243 [ + - ]: 1 : if (nlcc(1)) then
244 [ - + + - : 3 : ABI_MALLOC(ff, (mmax))
+ - + - -
+ - + ]
245 [ - + + - : 2 : ABI_MALLOC(ff1, (mmax))
- + - + ]
246 [ - + + - : 2 : ABI_MALLOC(ff2, (mmax))
- + - + ]
247 [ + + ]: 601 : ff(1:mmax) = rho_atc(1:mmax,1) ! model core charge without derivative factor
248 : :
249 [ + + ]: 601 : ff1 = zero
250 : 1 : call nderiv(one,ff,ff1,mmax,1) ! first derivative
251 [ + + ]: 601 : ff1(1:mmax) = ff1(1:mmax) / rab(1:mmax,1)
252 : 1 : call smooth(ff1, mmax, 15) ! run 15 iterations of smoothing
253 : :
254 [ + + ]: 601 : ff2 = zero
255 : 1 : call nderiv(one, ff1, ff2, mmax, 1) ! second derivative
256 [ + + ]: 601 : ff2(1:mmax) = ff2(1:mmax) / rab(1:mmax,1)
257 : 1 : call smooth(ff2, mmax, 15) ! run 15 iterations of smoothing?
258 : :
259 : : ! determine a good rchrg = xcccrc
260 [ + - ]: 147 : do ir = mmax, 1, -1
261 [ + + ]: 147 : if (abs(ff(ir)) > 1.e-6) then
262 : 1 : xcccrc = r(ir,1)
263 : 1 : exit
264 : : end if
265 : : end do
266 [ - + + - : 3 : ABI_MALLOC(rad_cc, (mmax))
+ - + - -
+ - + ]
267 [ - + + + ]: 602 : rad_cc = r(1:mmax,1)
268 : 1 : rad_cc(1) = zero ! force this so that the core charge covers whole spline interval.
269 : :
270 : 1 : call cc_derivatives(rad_cc,ff,ff1,ff2,mmax,psps%n1xccc,xcccrc,xccc1d)
271 : :
272 : 1 : ABI_FREE(rad_cc)
273 [ - + ]: 1 : ABI_FREE(ff)
274 [ - + ]: 1 : ABI_FREE(ff1)
275 [ - + ]: 1 : ABI_FREE(ff2)
276 : : end if ! nlcc present
277 : :
278 : 2 : end subroutine upf1_to_abinit
279 : : !!***
280 : :
281 : : !!****f* ABINIT/upf2_to_abinit
282 : : !! NAME
283 : : !! upf2_to_abinit
284 : : !!
285 : : !! FUNCTION
286 : : !! This routine wraps a call to a PWSCF module, which reads in
287 : : !! a UPF2 (PWSCF / Espresso) format pseudopotential, then transfers
288 : : !! data to abinit internal variables.
289 : : !! "UPF2 PWSCF format" (pspcod=12)
290 : : !!
291 : : !! INPUTS
292 : : !! filpsp = name of file with UPF2 data
293 : : !! vloc_rcut= Real-space cutoff for local part
294 : : !! psps = sturcture with global dimension data for pseudopotentials, header info ...
295 : : !! used contents:
296 : : !! psps%lmnmax
297 : : !! psps%mqgrid_ff
298 : : !! psps%mqgrid_vl
299 : : !! psps%dimekb
300 : : !! psps%n1xccc
301 : : !! psps%qgrid_ff
302 : : !! psps%qgrid_vl
303 : : !!
304 : : !! OUTPUT
305 : : !! pspxc = index of xc functional for this pseudo
306 : : !! lmax_ = maximal angular momentum
307 : : !! lloc = local component chosen for pseudopotential
308 : : !! mmax = maximum number of points in real space radial grid
309 : : !! znucl = charge of species nucleus
310 : : !! zion = valence charge
311 : : !! epsatm = integral of local potential - coulomb potential of zion
312 : : !! xcccrc = radius for non linear core correction
313 : : !! ekb(dimekb)= Kleinman Bylander energies, see pspatm.F90
314 : : !! epsatm=$ (4\pi)\int_0^\infty [r^2 (V(r)+\frac{Zv}{r}) dr]$(hartree)
315 : : !! indlmn(6,i)= array giving l,m,n,lm,ln,s for i=ln (if useylm=0)
316 : : !! or i=lmn (if useylm=1)
317 : : !! vlspl(mqgrid_vl,2)=q^2 Vloc(q) and second derivatives from spline fit
318 : : !! ffspl(mqgrid_ff,2,lnmax)=Kleinman-Bylander form factor f_l(q) and
319 : : !! second derivative from spline fit for each angular momentum and
320 : : !! each projector; if any, spin-orbit components begin at l=mpsang+1
321 : : !! nproj= number of projectors for each channel
322 : : !! xccc1d(n1xccc*(1-usepaw),6)=1D core charge function and five derivatives,
323 : : !! from psp file (used in NC only)
324 : : !! xcctau1d(n1xccc*(1-usepaw),6)=1D core charge kinetic energy density function and five derivatives,
325 : : !! from psp file (used in NC only)
326 : : !! nctab<nctab_t>=NC tables
327 : : !! %has_tvale=True if the pseudo contains the pseudo valence charge
328 : : !! %tvalespl(mqgrid_vl,2)=the pseudo valence density and 2nd derivative in reciprocal space on a regular grid
329 : : !!
330 : : !! SOURCE
331 : :
332 : 10 : subroutine upf2_to_abinit(ipsp, filpsp, vloc_rcut, znucl, zion, pspxc, lmax, lloc, mmax, &
333 : 10 : psps, epsatm, xcccrc, indlmn, ekb, ffspl, nproj_l, vlspl, xccc1d, xcctau1d, nctab, maxrad)
334 : :
335 : : use pseudo_types, only : pseudo_upf, deallocate_pseudo_upf !, pseudo_config
336 : : use read_upf_new_module, only : read_upf_new
337 : : use defs_datatypes, only : nctab_t
338 : : use m_psps, only : nctab_eval_tvalespl
339 : : use m_pspheads, only : upfdft_to_ixc, upf2_jl2srso
340 : :
341 : : !Arguments -------------------------------
342 : : integer,intent(in) :: ipsp
343 : : character(len=fnlen), intent(in) :: filpsp
344 : : real(dp),intent(in) :: vloc_rcut
345 : : type(pseudopotential_type),intent(in) :: psps
346 : : type(nctab_t),intent(inout) :: nctab
347 : : integer, intent(out) :: pspxc, lmax, lloc, mmax
348 : : real(dp), intent(out) :: znucl, zion, epsatm, xcccrc, maxrad
349 : : !arrays
350 : : integer, intent(out) :: indlmn(6,psps%lmnmax), nproj_l(psps%mpssoang)
351 : : real(dp), intent(inout) :: ekb(psps%dimekb)
352 : : real(dp), intent(inout) :: ffspl(psps%mqgrid_ff,2,psps%lnmax)
353 : : real(dp), intent(out) :: vlspl(psps%mqgrid_vl,2)
354 : : real(dp), intent(inout) :: xccc1d(psps%n1xccc,6)
355 : : real(dp), intent(inout) :: xcctau1d(psps%n1xccc,6)
356 : :
357 : : !Local variables -------------------------
358 : : integer :: ierr, ir, irad, iprj, il, ll, smooth_niter, nso, nn, iln, kk, mm, pspindex, iwfc !, iq
359 : : integer :: atmwfc_lmax, mmax_cut
360 : : !real(dp),parameter :: vloc_rcut = 10.0_dp ! QE Value
361 : : !real(dp),parameter :: vloc_rcut = 6.0_dp ! PseudoDojo value used to generate psp8 files
362 : : real(dp) :: yp1, ypn, amesh, damesh, intg
363 : : character(len=500) :: msg
364 : : logical :: linear_mesh, debug
365 : 10 : type(pseudo_upf) :: upf
366 : : type(atomdata_t) :: atom
367 : 10 : type(pawrad_type) :: mesh
368 : : integer :: my_nproj_l(0:3), my_nprojso_l(1:3), units(2)
369 : : !integer :: nproj_tmp(psps%mpssoang)
370 : 10 : integer,allocatable :: awfc_indlmn(:,:)
371 : 10 : logical,allocatable :: found_l(:)
372 : 10 : real(dp),allocatable :: work_spl(:), ff(:), ff1(:), ff2(:), rad_cc(:), proj(:,:), chi_tmp(:)
373 : 10 : real(dp),allocatable :: vsr(:,:,:), esr(:,:), vso(:,:,:), eso(:,:)
374 : :
375 : : ! *********************************************************************
376 : :
377 [ + + ]: 30 : units = [std_out, ab_out]
378 : :
379 : : ! See also https://github.com/QEF/qeschemas/blob/master/UPF/qe_pp-0.99.xsd
380 : : ! and https://github.com/QEF/qeschemas/files/9497267/pp.md
381 : 10 : call read_upf_new(filpsp, upf, ierr)
382 [ - + ]: 10 : ABI_CHECK(ierr == 0, sjoin("read_upf_new returned ierr:", itoa(ierr)))
383 : :
384 : 10 : call atomdata_from_symbol(atom, upf%psd)
385 : 10 : znucl = atom%znucl
386 : 10 : zion = upf%zp
387 : 10 : mmax = upf%mesh
388 : 10 : maxrad = upf%rmax
389 : :
390 [ - + ]: 10 : ABI_CHECK(upfdft_to_ixc(upf%dft, pspxc, msg) == 0, msg)
391 : 10 : lmax = upf%lmax
392 : :
393 : : ! Write some description of file
394 : 10 : write(msg, '(3(a,1x))' ) '-',trim(upf%psd), trim(upf%generated)
395 : 10 : call wrtout(units, msg)
396 : 10 : write(msg,'(a,f9.5,f10.5,2x,a,t47,a)')'-',znucl,zion,trim(upf%date),'znucl, zion, pspdat'
397 : 10 : call wrtout(units, msg)
398 : 10 : write(msg, '(5(i0,1x),t47,a)' ) 12, pspxc, lmax, upf%lloc, mmax,'pspcod,pspxc,lmax,lloc,mmax'
399 : 10 : call wrtout(units, msg)
400 : :
401 : : ! Check that rad grid is linear starting at zero
402 : 10 : linear_mesh = .True.
403 : 10 : amesh = upf%r(2) - upf%r(1); damesh = zero
404 [ + + ]: 14456 : do irad=2,mmax-1
405 : 14456 : damesh = max(damesh, abs(upf%r(irad)+amesh-upf%r(irad+1)))
406 : : end do
407 : 10 : linear_mesh = damesh < tol8
408 : :
409 [ + - - + ]: 10 : if (.not. linear_mesh .or. abs(upf%r(1)) > tol16) then
410 : : write(msg,'(3a)')&
411 : 0 : 'Assuming pseudized valence charge given on linear radial mesh starting at zero.',ch10,&
412 : 0 : 'Action: check your pseudopotential file.'
413 : 0 : ABI_ERROR(msg)
414 : : end if
415 : :
416 : : ! Check if the local component is one of the angular momentum channels
417 : : ! effectively if one of the ll is absent from the NL projectors
418 [ - + + - : 30 : ABI_MALLOC(found_l, (0:lmax))
+ - + - -
+ - + ]
419 [ + + ]: 40 : found_l = .true.
420 [ + + ]: 40 : do ll=0,lmax
421 [ + - + + : 108 : if (any(upf%lll(1:upf%nbeta) == ll)) found_l(ll) = .false.
+ - ]
422 : : end do
423 : :
424 [ + + - + : 40 : if (count(found_l) /= 1) then
+ - ]
425 : 10 : lloc = -1
426 : : else
427 [ # # ]: 0 : do ll=0,lmax
428 [ # # ]: 0 : if (found_l(ll)) then
429 : 0 : lloc = ll
430 : 0 : exit
431 : : end if
432 : : end do
433 : : end if
434 [ - + ]: 10 : ABI_FREE(found_l)
435 : : !FIXME: do something about lloc == -1
436 : :
437 : : ! convert vloc from Rydberg to Ha
438 [ + + ]: 14476 : upf%vloc = half * upf%vloc
439 : :
440 : : ! =================================================
441 : : ! This comment is from q-e/Modules/read_pseudo.F90
442 : : ! =================================================
443 : :
444 : : ! the radial grid is defined up to r(mesh) but we introduce
445 : : ! an auxiliary variable msh to limit the grid up to rcut=10 a.u.
446 : : ! This is used to cut off the numerical noise arising from the
447 : : ! large-r tail in cases like the integration of V_loc-Z/r
448 : : !
449 : : ! NB: In QE, the default value for vloc_rcut is 10 Bohr.
450 : 10 : call wrtout(std_out, sjoin(" Cutting radial-mesh for vloc using vloc_rcut:", ftoa(vloc_rcut), "(Bohr)"))
451 : 10 : mmax_cut = mmax
452 [ + + ]: 8508 : do ir=1,upf%mesh
453 [ + + ]: 8508 : if (upf%r(ir) > vloc_rcut) then
454 : : mmax_cut = ir
455 : : ! msh is forced to be odd for simpson integration (maybe obsolete?)
456 : 6 : mmax_cut = 2 * ( (mmax_cut + 1) / 2) - 1
457 : 6 : exit
458 : : end if
459 : : end do
460 : :
461 : : !write(std_out,*)" UPF file with mmax: ", mmax, " with r_max:", upf%r(mmax)
462 : : !write(std_out,*)" Using mmax_cut: ", mmax_cut, " with r_cut:", upf%r(mmax_cut)
463 : :
464 : : ! Note mmax_cut here.
465 [ + - ]: 10 : if (linear_mesh) then
466 : : call psp8lo(amesh, epsatm, mmax_cut, psps%mqgrid_vl, psps%qgrid_vl, &
467 : 10 : vlspl(:,1), upf%r, upf%vloc, yp1, ypn, zion)
468 : : else
469 : : call psp11lo(upf%rab, epsatm, mmax_cut, psps%mqgrid_vl, psps%qgrid_vl,&
470 : 0 : vlspl(:,1), upf%r, upf%vloc, yp1, ypn, zion)
471 : : end if
472 : :
473 : : ! Fit spline to q^2 V(q) (Numerical Recipes subroutine)
474 [ - + + - : 30 : ABI_MALLOC(work_spl, (psps%mqgrid_vl))
+ - + - -
+ - + ]
475 : :
476 : 10 : call spline(psps%qgrid_vl, vlspl(:,1), psps%mqgrid_vl, yp1, ypn, work_spl)
477 : :
478 [ + + ]: 30020 : vlspl(:,2) = work_spl(:)
479 [ - + ]: 10 : ABI_FREE(work_spl)
480 : :
481 : 10 : debug = .False.!; debug = .True.
482 : : if (debug) then
483 : : write(std_out,*)'# Vlocal upf = '
484 : : write(std_out,*)' amesh = ', amesh
485 : : write(std_out,*)' epsatm = ', epsatm
486 : : write(std_out,*)' mmax = ', mmax
487 : : write(std_out,*)' mqgrid = ', psps%mqgrid_vl
488 : : do ir = 1, psps%mqgrid_vl
489 : : write(std_out,*)' qgrid = ', ir, psps%qgrid_vl(ir)
490 : : enddo
491 : : do ir = 1, psps%mqgrid_vl
492 : : write(std_out,'(a,i5,2f20.12)')' iq, vlspl = ', ir, vlspl(ir,1), vlspl(ir,2)
493 : : enddo
494 : : write(std_out,*)
495 : : do ir = 1, mmax
496 : : write(std_out,*)' rad = ', upf%r(ir), upf%vloc(ir)
497 : : enddo
498 : : write(std_out,*)
499 : : write(std_out,*)' yp1 = ', yp1
500 : : write(std_out,*)' ypn = ', ypn
501 : : write(std_out,*)' zion = ', zion
502 : : !stop
503 : : end if
504 : :
505 [ + + ]: 48 : nproj_l = 0
506 : :
507 [ + + ]: 10 : if (.not. upf%has_so) then
508 [ + + ]: 40 : do iprj=1,upf%nbeta
509 : 34 : ll = upf%lll(iprj)
510 : 40 : nproj_l(ll+1) = nproj_l(ll+1) + 1
511 : : end do
512 : 6 : write(msg, '(a,*(i6))' ) ' nproj',nproj_l
513 : 6 : call wrtout(units, msg)
514 : :
515 : : ! shape = dimekb vs. shape = n_proj
516 : : ! convert from Rydberg to Ha
517 [ + + ]: 40 : do ll=1,upf%nbeta
518 : 40 : ekb(ll) = upf%dion(ll,ll) * half
519 : : end do
520 : :
521 : : ! this has to do the FT of the projectors to reciprocal space
522 : : ! allocate proj to avoid temporary copy.
523 [ - + + - : 24 : ABI_MALLOC(proj, (mmax,1:upf%nbeta))
- + + - +
- + - - +
- + ]
524 [ - + + + : 45562 : proj = upf%beta(1:mmax,1:upf%nbeta)
+ + ]
525 : :
526 : : call psp11nl(ffspl, indlmn, mmax, psps%lnmax, psps%lmnmax, psps%mqgrid_ff, &
527 : : upf%nbeta, proj, upf%lll(1:upf%nbeta), upf%kbeta(1:upf%nbeta), &
528 : 6 : psps%qgrid_ff, upf%r(1:mmax), upf%rab(1:mmax), psps%useylm)
529 : :
530 : : ! This to reproduce psp8in version with linear meshes.
531 : : ! Compute Vanderbilt-KB form factors and fit splines
532 : : call psp8nl(amesh, ffspl, indlmn, lmax, psps%lmnmax, psps%lnmax, mmax, &
533 : 6 : psps%mqgrid_ff, psps%qgrid_ff, upf%r, proj)
534 : :
535 [ - + ]: 6 : ABI_FREE(proj)
536 : :
537 : : else
538 : 4 : call upf2_jl2srso(upf, my_nproj_l, my_nprojso_l, vsr, esr, vso, eso)
539 : :
540 : 4 : write(msg, '(a,*(i6))' ) ' nproj',my_nproj_l
541 : 4 : call wrtout(units, msg)
542 : 4 : write(msg, '(5x,a)' ) "spin-orbit psp"
543 : 4 : call wrtout(units, msg)
544 : 4 : write(msg, '(5x,a,*(i6))' ) ' nprojso',my_nprojso_l
545 : 4 : call wrtout(units, msg)
546 : :
547 [ - + + - : 98596 : ABI_CALLOC(proj, (mmax, psps%lnmax))
- + + - +
- + - - +
- + + + +
+ ]
548 [ + + + + ]: 424 : pspindex = 0; iln=0; indlmn(:,:)=0
549 : 4 : nso = 2
550 : :
551 [ + + ]: 4 : if (psps%pspso(ipsp) == 0) then
552 : 2 : write (msg, '(3a)') 'You are reading a pseudopotential file with spin orbit projectors',ch10,&
553 : 4 : ' but internal variable pspso is 0'
554 : 2 : ABI_COMMENT(msg)
555 : 2 : nso = 1
556 : : end if
557 : :
558 [ + + ]: 10 : do nn=1,nso
559 : : !do ipsang=1+(nn-1)*(lmax+1),nn*lmax+1
560 : : ! ll = ipsang-(nn-1)*lmax-1
561 [ + + ]: 28 : do il=1,lmax+1
562 : 18 : ll = il - 1
563 [ + + ]: 24 : if (nn == 1) then
564 : : ! SR part
565 [ + + ]: 42 : do iprj=1,my_nproj_l(ll)
566 : 30 : iln = iln + 1
567 : 30 : ekb(iln) = esr(iprj, il)
568 [ + + ]: 48722 : proj(:,iln) = vsr(:, iprj, il)
569 : 30 : nproj_l(il) = my_nproj_l(ll)
570 : 30 : kk = iprj
571 [ + + ]: 72 : do mm=1,2*ll*psps%useylm+1
572 : 30 : pspindex = pspindex + 1
573 : 30 : indlmn(1,pspindex) = ll
574 : 30 : indlmn(2,pspindex) = mm-ll*psps%useylm-1
575 : 30 : indlmn(3,pspindex) = kk
576 : 30 : indlmn(4,pspindex) = ll*ll+(1-psps%useylm)*ll+mm
577 : 30 : indlmn(5,pspindex) = iln
578 : 60 : indlmn(6,pspindex) = nn
579 : : !print *, "indlmn:", indlmn(:,pspindex), "pspindex:", pspindex
580 : : end do
581 : : end do
582 : :
583 : : else
584 : : ! SOC part
585 [ + + ]: 6 : if (ll == 0) cycle
586 [ + + ]: 18 : do iprj=1,my_nprojso_l(ll)
587 : 14 : iln = iln + 1
588 : 14 : ekb(iln) = eso(iprj, il)
589 [ + + ]: 23002 : proj(:,iln) = vso(:,iprj,il)
590 : : ! Note ll in nproj_l i.e. the s channel in the SOC part is not included in nproj.
591 : 14 : nproj_l(ll + psps%mpsang) = my_nprojso_l(ll)
592 : 14 : kk = iprj !+ my_nproj_l(ll)
593 [ + + ]: 34 : do mm=1,2*ll*psps%useylm+1
594 : 14 : pspindex = pspindex + 1
595 : 14 : indlmn(1,pspindex) = ll
596 : 14 : indlmn(2,pspindex) = mm-ll*psps%useylm-1
597 : 14 : indlmn(3,pspindex) = kk
598 : 14 : indlmn(4,pspindex) = ll*ll+(1-psps%useylm)*ll+mm
599 : 14 : indlmn(5,pspindex) = iln
600 : 28 : indlmn(6,pspindex) = nn
601 : : !print *, "indlmn:", indlmn(:,pspindex), "pspindex:", pspindex
602 : : end do
603 : : end do
604 : : end if
605 : :
606 : : end do ! il
607 : : end do ! nn
608 : :
609 : : ! This to reproduce psp8in version with linear meshes.
610 : : ! Compute Vanderbilt-KB form factors and fit splines
611 : : call psp8nl(amesh, ffspl, indlmn, lmax, psps%lmnmax, psps%lnmax, mmax, &
612 : 4 : psps%mqgrid_ff, psps%qgrid_ff, upf%r, proj)
613 : :
614 [ - + ]: 4 : ABI_FREE(proj)
615 [ - + ]: 4 : ABI_FREE(vsr)
616 [ - + ]: 4 : ABI_FREE(esr)
617 [ - + ]: 4 : ABI_FREE(vso)
618 [ - + ]: 4 : ABI_FREE(eso)
619 : : !ABI_WARNING("upf2_to_abinit: UPF2 with SOC")
620 : : end if
621 : :
622 : : ! In Abinit, at least for the Troullier-Martins pseudopotential,
623 : : ! the pseudocore charge density and its derivatives (xccc1d)
624 : : ! are introduced in a linear grid.
625 : : ! This grid is normalized, so the radial coordinates run between
626 : : ! from 0 and 1 (from 0 to xcccrc, where xcccrc is the radius
627 : : ! where the pseudo-core becomes zero).
628 : :
629 [ + + + + : 300250 : xcccrc = zero; xccc1d = zero; xcctau1d = zero
+ + + + ]
630 : :
631 [ + - ]: 10 : if (upf%nlcc) then
632 [ - + + - : 30 : ABI_MALLOC(ff, (mmax))
+ - + - -
+ - + ]
633 [ - + + - : 20 : ABI_MALLOC(ff1, (mmax))
- + - + ]
634 [ - + + - : 20 : ABI_MALLOC(ff2, (mmax))
- + - + ]
635 : : ! model core charge without derivative factor
636 [ + + ]: 14476 : ff(1:mmax) = upf%rho_atc(1:mmax)
637 : : !smooth_niter = 15 ! run 15 iterations of smoothing?
638 : 10 : smooth_niter = 0 ! Don't smooth core charges to be consistent with the treatment done in psp8in
639 : :
640 [ + + ]: 14476 : ff1 = zero
641 : 10 : call nderiv(one, ff, ff1, mmax, 1) ! first derivative
642 [ + + ]: 14476 : ff1(1:mmax) = ff1(1:mmax) / upf%rab(1:mmax)
643 : 10 : call smooth(ff1, mmax, smooth_niter)
644 : :
645 [ + + ]: 14476 : ff2 = zero
646 : 10 : call nderiv(one, ff1, ff2, mmax, 1) ! second derivative
647 [ + + ]: 14476 : ff2(1:mmax) = ff2(1:mmax) / upf%rab(1:mmax)
648 : 10 : call smooth(ff2, mmax, smooth_niter)
649 : :
650 : : ! determine a good rchrg = xcccrc
651 [ + - ]: 10728 : do ir = mmax, 1, -1
652 : : !if (abs(ff(ir)) > tol6) then
653 [ + + ]: 10728 : if (abs(ff(ir)) > tol20) then
654 : 10 : xcccrc = upf%r(ir); exit
655 : : end if
656 : : end do
657 : : !xcccrc = upf%r(mmax)
658 : :
659 [ - + + - : 30 : ABI_MALLOC(rad_cc, (mmax))
+ - + - -
+ - + ]
660 [ - + + + ]: 14486 : rad_cc = upf%r(1:mmax)
661 : 10 : rad_cc(1) = zero ! force this so that the core charge covers whole spline interval.
662 : :
663 : 10 : call cc_derivatives(rad_cc, ff, ff1, ff2, mmax, psps%n1xccc, xcccrc, xccc1d)
664 : : !call psp8cc(mmax, psps%n1xccc, xcccrc, xccc1d)
665 : :
666 [ - + ]: 10 : ABI_FREE(ff)
667 [ - + ]: 10 : ABI_FREE(ff1)
668 [ - + ]: 10 : ABI_FREE(ff2)
669 : :
670 : : ! Add corresponding splines for tau_mod, and flag to test for its presence before calculation
671 : : ! NB: there are no r**2 or 4 pi factors in the tau quantities from Don Hamann in oncvpsp metagga
672 [ - + + - : 30 : ABI_MALLOC(ff, (mmax))
+ - + - -
+ - + ]
673 [ - + + - : 20 : ABI_MALLOC(ff1, (mmax))
- + - + ]
674 [ - + + - : 20 : ABI_MALLOC(ff2, (mmax))
- + - + ]
675 [ + + ]: 14476 : ff(1:mmax) = upf%tau_mod(1:mmax) ! model core charge without derivative factor
676 : : !smooth_niter = 15 ! run 15 iterations of smoothing?
677 : : smooth_niter = 0 ! Don't smooth core charges to be consistent with the treatment done in psp8in
678 : :
679 [ + + ]: 14476 : ff1 = zero
680 : 10 : call nderiv(one, ff, ff1, mmax, 1) ! first derivative
681 [ + + ]: 14476 : ff1(1:mmax) = ff1(1:mmax) / upf%rab(1:mmax)
682 : 10 : call smooth(ff1, mmax, smooth_niter)
683 : :
684 [ + + ]: 14476 : ff2 = zero
685 : 10 : call nderiv(one, ff1, ff2, mmax, 1) ! second derivative
686 [ + + ]: 14476 : ff2(1:mmax) = ff2(1:mmax) / upf%rab(1:mmax)
687 : 10 : call smooth(ff2, mmax, smooth_niter)
688 : :
689 : : ! use same xcccrc and rad_cc as for density above ??
690 : :
691 : 10 : call cc_derivatives(rad_cc, ff, ff1, ff2, mmax, psps%n1xccc, xcccrc, xcctau1d)
692 : :
693 [ - + ]: 10 : ABI_FREE(ff)
694 [ - + ]: 10 : ABI_FREE(ff1)
695 [ - + ]: 10 : ABI_FREE(ff2)
696 : :
697 : 10 : ABI_FREE(rad_cc)
698 : :
699 : : end if ! nlcc present
700 : :
701 : : ! Read pseudo valence charge in real space on the linear mesh
702 : : ! and transform it to reciprocal space on a regular grid
703 : : ! TODO: Spline input data on linear mesh if not linear
704 [ - + + - : 30 : ABI_MALLOC(ff, (mmax))
+ - + - -
+ - + ]
705 [ - + + + ]: 14486 : ff = upf%rho_at(1:mmax) / four_pi
706 [ + + + + : 43408 : where (abs(upf%r) > tol16)
+ + + + +
+ ]
707 : : ff = ff / upf%r(1:mmax) ** 2
708 : : else where
709 : : ff = zero
710 : : end where
711 : :
712 : : ! TODO: use the tau_at pseudo atomic kinetic energy density as well, in upf%tau_at
713 : : ! would also need to be splined as below for the atomic pseudo charge
714 : : ! NB: there are no r**2 or 4 pi factors in the tau quantities from Don Hamann in oncvpsp metagga
715 : : ! TODO: as well, nctab contents with the form factors of xccc1d and xcctau1d could be calculated here instead of in m_pspini
716 : :
717 : : ! Evaluate spline-fit of the atomic pseudo valence charge in reciprocal space.
718 : 10 : call pawrad_init(mesh, mesh_size=mmax, mesh_type=1, rstep=amesh)
719 : 10 : call nctab_eval_tvalespl(nctab, zion, mesh, ff, psps%mqgrid_vl, psps%qgrid_vl)
720 : :
721 : 10 : nctab%num_tphi = upf%nwfc
722 [ + - ]: 10 : if (upf%nwfc > 0) then
723 : : ! Store atomic wavefunctions and metadata in nctab, then compute form factors for spline.
724 : : ! NB: lchi is the radial part of the KS equation, multiplied by r.
725 [ - + + - : 30 : ABI_MALLOC(awfc_indlmn, (6, upf%nwfc))
+ - - + -
+ ]
726 [ + + + + ]: 248 : awfc_indlmn = huge(1)
727 : 10 : atmwfc_lmax = -1
728 [ - + + - : 30 : ABI_MALLOC(chi_tmp, (upf%mesh))
+ - + - -
+ - + ]
729 : :
730 [ + + ]: 44 : do iwfc=1, upf%nwfc
731 : : !print *, "label: ", upf%els(iwfc); print *, "n", upf%nchi(iwfc)
732 : : !print *, "nn", upf%nn(iwfc); print *, "j", upf%jchi(iwfc)
733 : : !print *, "l", upf%lchi(iwfc); print *, "occ:", upf%oc(iwfc)
734 : 34 : atmwfc_lmax = max(atmwfc_lmax, upf%lchi(iwfc))
735 [ + - - + : 51736 : chi_tmp = upf%chi(:, iwfc) ** 2; call simp_gen(intg, chi_tmp, mesh)
- - + + ]
736 : : !write(std_out, *)" wavefunction (before rescaling) integrates to: ",intg
737 [ + + ]: 51702 : upf%chi(:, iwfc) = upf%chi(:, iwfc) / sqrt(intg)
738 [ + - - + : 51736 : chi_tmp = upf%chi(:, iwfc) ** 2; call simp_gen(intg, chi_tmp, mesh)
- - + + ]
739 : : !write(std_out, *)" wavefunction (after rescaling) integrates to: ",intg
740 : :
741 : : ! NB: we only need ll (1), and iln (5) in psp8nl
742 : 34 : awfc_indlmn(1, iwfc) = upf%lchi(iwfc)
743 : 78 : awfc_indlmn(5, iwfc) = iwfc
744 : : end do
745 [ - + ]: 10 : ABI_FREE(chi_tmp)
746 : :
747 : : ! All this sfree/remalloc stuff is for handling memory in multi dataset mode!
748 [ + + - + : 40 : ABI_REMALLOC(nctab%tphi_qspl, (psps%mqgrid_ff, 2, upf%nwfc))
+ - - + +
- + - + -
- + - + -
+ ]
749 [ + + ]: 10 : ABI_SFREE(nctab%tphi_n)
750 [ + + ]: 10 : ABI_SFREE(nctab%tphi_l)
751 [ + + ]: 10 : ABI_SFREE(nctab%tphi_occ)
752 [ + + ]: 10 : ABI_SFREE(nctab%tphi_jtot)
753 [ - + ]: 10 : call alloc_copy(upf%nchi, nctab%tphi_n)
754 [ - + ]: 10 : call alloc_copy(upf%lchi, nctab%tphi_l)
755 [ - + ]: 10 : call alloc_copy(upf%oc, nctab%tphi_occ)
756 : 10 : nctab%has_jtot = upf%has_so
757 [ + + - + ]: 10 : if (upf%has_so) call alloc_copy(upf%jchi, nctab%tphi_jtot)
758 : :
759 : : !call psp8nl(amesh, nctab%tphi_qspl, awfc_indlmn, atmwfc_lmax, upf%nwfc, upf%nwfc, mmax, &
760 : : ! psps%mqgrid_ff, psps%qgrid_ff, upf%r, upf%chi)
761 : :
762 : : !do iwfc=1, upf%nwfc
763 : : ! do iq=1,psps%mqgrid_ff
764 : : ! write(555, *) nctab%tphi_qspl(iq,:,iwfc)
765 : : ! end do
766 : : !end do
767 : :
768 : : !do iwfc=1, upf%nwfc
769 : : ! where (abs(upf%r) > tol16)
770 : : ! upf%chi(:,iwfc) = upf%chi(:,iwfc) / upf%r
771 : : ! else where
772 : : ! upf%chi(:,iwfc) = zero
773 : : ! end where
774 : : !end do
775 : :
776 : 10 : call pawpsp_nl(nctab%tphi_qspl, awfc_indlmn, upf%nwfc, upf%nwfc, psps%mqgrid_ff, psps%qgrid_ff, mesh, upf%chi)
777 : :
778 : : !do iwfc=1, upf%nwfc
779 : : ! do iq=1,psps%mqgrid_ff
780 : : ! write(666, *) nctab%tphi_qspl(iq,:,iwfc)
781 : : ! end do
782 : : !end do
783 : :
784 [ - + ]: 10 : ABI_FREE(awfc_indlmn)
785 : : !stop "nwfc"
786 : : end if ! upf%nwfc > 0
787 : :
788 [ - + ]: 10 : ABI_FREE(ff)
789 : 10 : call pawrad_free(mesh)
790 : 10 : call deallocate_pseudo_upf(upf)
791 : :
792 [ - + - + : 30 : end subroutine upf2_to_abinit
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + ]
793 : : !!***
794 : :
795 : : !!****f* m_upf2abinit/psp11nl
796 : : !! NAME
797 : : !! psp11nl
798 : : !!
799 : : !! FUNCTION
800 : : !! Fourier transform the real space UPF projector functions to reciprocal space
801 : : !!
802 : : !! INPUTS
803 : : !! lmax=maximum ang momentum for which nonlocal form factor is desired.
804 : : !! Usually lmax=1, sometimes = 0 (e.g. for oxygen); lmax <= 2 allowed.
805 : : !! mmax=number of radial grid points for atomic grid
806 : : !! lnmax= maximum index for all l channel projectors, dimension of ffspl
807 : : !! lmnmax= maximum index for all projectors, dimension of indlmn
808 : : !! mqgrid=number of grid points for q grid
809 : : !! n_proj = total number of NL projectors read in
810 : : !! proj = projector functions times r, on a real space grid
811 : : !! proj_l = angular momentum channel for each projector
812 : : !! proj_nr = max number of r-points used for each projector
813 : : !! qgrid(mqgrid)=q-values at which form factors are returned
814 : : !! r(mmax)=radial grid values
815 : : !! drdi=derivative of grid point wrt index
816 : : !! useylm = input to use m dependency of NL part, or only Legendre polynomials
817 : : !!
818 : : !! OUTPUT
819 : : !! ffspl(mqgrid,2,mpsang)=Kleinman-Bylander form factor f_l(q) and
820 : : !! second derivative from spline fit for each angular momentum
821 : : !! indlmn = indexing of each projector, for n, l, m, s, ln, lmn (see pspatm.F90)
822 : : !!
823 : : !! SOURCE
824 : :
825 : 7 : subroutine psp11nl(ffspl,indlmn, mmax, lnmax, lmnmax, mqgrid, n_proj, &
826 : 7 : proj, proj_l, proj_nr, qgrid, r, drdi, useylm)
827 : :
828 : : !Arguments ------------------------------------
829 : : !scalars
830 : : integer,intent(in) :: mmax, lnmax, lmnmax, mqgrid, useylm, n_proj
831 : : !arrays
832 : : integer, intent(in) :: proj_l(n_proj)
833 : : integer, intent(in) :: proj_nr(n_proj)
834 : : integer, intent(out) :: indlmn(6,lmnmax)
835 : : real(dp),intent(in) :: r(mmax)
836 : : real(dp),intent(in) :: drdi(mmax)
837 : : real(dp),intent(in) :: proj(mmax,n_proj)
838 : : real(dp),intent(in) :: qgrid(mqgrid)
839 : : real(dp),intent(inout) :: ffspl(mqgrid,2,lnmax) !vz_i
840 : :
841 : : !Local variables-------------------------------
842 : : !scalars
843 : : integer,parameter :: bessorder0 = 0 ! never calculate derivatives of bessel functions
844 : : integer :: iproj, nr, ll, llold, ipsang, i_indlmn
845 : : integer :: iproj_1l, ir, iq, mm
846 : : real(dp) :: res, arg, besfact, dummy, dummy2
847 : 7 : real(dp), allocatable :: work(:)
848 : : character(len=500) :: msg
849 : :
850 : : !*************************************************************************
851 : :
852 [ + + + + : 240662 : ffspl = zero; indlmn = 0; i_indlmn = 0
+ + + + +
+ ]
853 : : llold = -1; iproj_1l = 1
854 : :
855 : : ! loop over all projectors
856 [ + + ]: 44 : do iproj=1,n_proj
857 [ - + ]: 37 : if (iproj > lmnmax) then
858 : 0 : write(msg,'(a,2i0)') ' Too many projectors found. n_proj, lmnmax = ',n_proj, lmnmax
859 : 0 : ABI_ERROR(msg)
860 : : end if
861 : :
862 : 37 : nr = proj_nr(iproj)
863 [ - + + - : 111 : ABI_MALLOC(work, (nr))
+ - + - -
+ - + ]
864 : 37 : ll = proj_l(iproj)
865 [ - + ]: 37 : if (ll < llold) then
866 : 0 : ABI_ERROR('UPF projectors are not in order of increasing ll')
867 [ + + ]: 37 : else if (ll == llold) then
868 : 16 : iproj_1l = iproj_1l + 1
869 : : else
870 : : iproj_1l = 1
871 : : llold = ll
872 : : end if
873 : :
874 : : ! determine indlmn for this projector (keep in UPF order and enforce that they are in increasing ll)
875 : : ! indlmn(6,lmnmax,ntypat)
876 : : ! For each type of psp,
877 : : ! array giving l,m,n,lm,ln,spin for i=ln (if useylm=0)
878 : : ! or i=lmn (if useylm=1)
879 : : ! NB: spin is used for NC pseudos with SOC term: 1 if scalar term (spin diagonal), 2 if SOC term.
880 [ + + ]: 94 : do mm=1,2*ll*useylm+1
881 : 57 : i_indlmn = i_indlmn + 1
882 : 57 : indlmn(1, i_indlmn) = ll
883 : 57 : indlmn(2, i_indlmn) = mm-ll*useylm-1
884 : 57 : indlmn(3, i_indlmn) = iproj_1l
885 : 57 : indlmn(4, i_indlmn) = ll*ll+(1-useylm)*ll+mm
886 : 57 : indlmn(5, i_indlmn) = iproj
887 : 94 : indlmn(6, i_indlmn) = 1 !spin? FIXME: to get j for relativistic cases
888 : : end do
889 : :
890 : : ! FT projectors to reciprocal space q
891 [ + + ]: 111074 : do iq=1,mqgrid
892 : 111037 : arg = two_pi * qgrid(iq)
893 : :
894 : : ! FIXME: add semianalytic form for integral from 0 to first point
895 [ + + ]: 24551181 : do ir=1,nr
896 : 24440144 : call jbessel(besfact, dummy, dummy2, ll, bessorder0, arg*r(ir))
897 : 24551181 : work(ir) = drdi(ir) * besfact * proj(ir, iproj) * r(ir) !* r(ir)
898 : : end do
899 : 111037 : call ctrap (nr, work, one, res)
900 : 111074 : ffspl(iq, 1, iproj) = res
901 : : end do
902 [ - + ]: 44 : ABI_FREE(work)
903 : : end do ! iproj
904 : :
905 : : ! add derivative of ffspl(:,1,:) for spline interpolation later
906 [ - + + - : 21 : ABI_MALLOC(work, (mqgrid))
+ - + - -
+ + - ]
907 [ + + ]: 47 : do ipsang=1,lnmax
908 : 47 : call spline(qgrid,ffspl(:,1,ipsang),mqgrid,zero,zero,ffspl(:,2,ipsang))
909 : : end do
910 [ - + ]: 7 : ABI_FREE(work)
911 : :
912 : 10 : end subroutine psp11nl
913 : : !!***
914 : :
915 : : !!****f* ABINIT/psp11lo
916 : : !! NAME
917 : : !! psp11lo
918 : : !!
919 : : !! FUNCTION
920 : : !! Compute sine transform to transform from V(r) to q^2 V(q).
921 : : !! Computes integrals on logarithmic grid using related uniform
922 : : !! grid in exponent and corrected trapezoidal integration.
923 : : !! Generalized from psp5lo for non-log grids using dr/di weights.
924 : : !!
925 : : !! INPUTS
926 : : !! drdi=derivative of radial grid wrt index
927 : : !! mmax=number of radial r grid points
928 : : !! mqgrid=number of grid points in q from 0 to qmax.
929 : : !! qgrid(mqgrid)=q grid values (bohr**-1).
930 : : !! rad(mmax)=r grid values (bohr).
931 : : !! vloc(mmax)=V(r) on radial grid.
932 : : !! zion=nominal valence charge of atom.
933 : : !!
934 : : !! OUTPUT
935 : : !! epsatm=$ 4\pi\int[r^2 (V(r)+\frac{Zv}{r}dr]$.
936 : : !!{{\\ \begin{equation}
937 : : !! q2vq(mqgrid)
938 : : !! =q^2 V(q)
939 : : !! = -\frac{Zv}{\pi}
940 : : !! + q^2 4\pi\int[(\frac{\sin(2\pi q r)}{2\pi q r})(r^2 V(r)+r Zv)dr].
941 : : !!\end{equation} }}
942 : : !! yp1,ypn=derivative of q^2 V(q) wrt q at q=0 and q=qmax (needed for spline fitter).
943 : : !!
944 : : !! SOURCE
945 : :
946 : 1 : subroutine psp11lo(drdi,epsatm,mmax,mqgrid,qgrid,q2vq,rad,vloc,yp1,ypn,zion)
947 : :
948 : : !Arguments----------------------------------------------------------
949 : : !scalars
950 : : integer,intent(in) :: mmax,mqgrid
951 : : real(dp),intent(in) :: zion
952 : : real(dp),intent(out) :: epsatm,yp1,ypn
953 : : !arrays
954 : : real(dp),intent(in) :: drdi(mmax)
955 : : real(dp),intent(in) :: qgrid(mqgrid),rad(mmax),vloc(mmax)
956 : : real(dp),intent(out) :: q2vq(mqgrid)
957 : :
958 : : !Local variables-------------------------------
959 : : !scalars
960 : : integer :: iq,ir
961 : : real(dp),parameter :: scale=10.0d0
962 : : real(dp) :: arg,result_ctrap,test,ztor1
963 : : !arrays
964 : 1 : real(dp),allocatable :: work(:)
965 : :
966 : : ! *************************************************************************
967 : :
968 [ - + + - : 3 : ABI_MALLOC(work,(mmax))
+ - + - -
+ - + ]
969 : :
970 : : ! Do q=0 separately (compute epsatm)
971 : : ! Do integral from 0 to r1
972 : 1 : ztor1=(zion/2.0d0+rad(1)*vloc(1)/3.d0)*rad(1)**2
973 : :
974 : : ! Set up integrand for q=0: $ \int[r^2 (V(r)+\frac{Zv}{r}) dr]$
975 : : ! with extra factor of drdi to convert to uniform grid
976 [ + + ]: 601 : do ir = 1, mmax
977 : : ! First handle tail region
978 : 600 : test=vloc(ir)+zion/rad(ir)
979 : : ! Ignore small contributions, or impose a cut-off in the case
980 : : ! the pseudopotential data are in single precision.
981 : : ! (it is indeed expected that vloc is very close to zero beyond 20,
982 : : ! so a value larger than 2.0d-8 is considered anomalous)
983 [ + - + + : 600 : if (abs(test)<1.0d-20 .or. (rad(ir)>20.0d0 .and. abs(test)>2.0d-8) ) then
+ - ]
984 : 70 : work(ir)=zero
985 : : else
986 : 530 : work(ir)=rad(ir)*(rad(ir)*vloc(ir)+zion)
987 : : end if
988 : 601 : work(ir)=work(ir)*drdi(ir)
989 : : end do
990 : :
991 : : ! Do integral from r(1) to r(max)
992 : 1 : call ctrap(mmax,work,one,result_ctrap)
993 : 1 : epsatm=4.d0*pi*(result_ctrap+ztor1)
994 : :
995 : 1 : q2vq(1)=-zion/pi
996 : :
997 : : ! Loop over q values
998 [ + + ]: 3001 : do iq=2,mqgrid
999 : 3000 : arg=2.d0*pi*qgrid(iq)
1000 : : ! ztor1=$ -Zv/\pi + 2q \int_0^{r1}[\sin(2\pi q r)(rV(r)+Zv) dr]$
1001 : 3000 : ztor1=(vloc(1)*sin(arg*rad(1))/arg-(rad(1)*vloc(1)+zion) * cos(arg*rad(1)) )/pi
1002 : :
1003 : : ! set up integrand
1004 [ + + ]: 1803000 : do ir=1,mmax
1005 : : !test=vloc(ir)+zion/rad(ir)
1006 : : !Ignore contributions within decade of machine precision (suppressed ...)
1007 : : !if ((scale+abs(test)).eq.scale) then
1008 : : !work(ir)=zero
1009 : : !else
1010 : 1800000 : work(ir)=sin(arg*rad(ir))*(rad(ir)*vloc(ir)+zion)
1011 : : !end if
1012 : 1803000 : work(ir)=work(ir)*drdi(ir)
1013 : : end do
1014 : : ! do integral from r(1) to r(mmax)
1015 : 3000 : call ctrap(mmax,work,one,result_ctrap)
1016 : :
1017 : : ! store q^2 v(q)
1018 : : ! FIXME: I only see one factor q, not q^2, but the same is done in other pspXlo.F90
1019 : 3001 : q2vq(iq)=ztor1+2.d0*qgrid(iq)*result_ctrap
1020 : :
1021 : : end do
1022 : :
1023 : : ! Compute derivatives of q^2 v(q) at ends of interval
1024 : 1 : yp1=0.0d0
1025 : : !ypn=$ 2\int_0^\infty[(\sin(2\pi qmax r)+(2\pi qmax r)*\cos(2\pi qmax r)(r V(r)+Z) dr]$
1026 : : !integral from 0 to r1
1027 : 1 : arg=2.0d0*pi*qgrid(mqgrid)
1028 : 1 : ztor1=zion*rad(1)*sin(arg*rad(1))
1029 : 1 : ztor1=ztor1+ 3.d0*rad(1)*vloc(1)*cos(arg*rad(1))/arg + (rad(1)**2-1.0d0/arg**2)*vloc(1)*sin(arg*rad(1))
1030 : : !integral from r(mmax) to infinity is overkill; ignore
1031 : : !set up integrand
1032 [ + + ]: 601 : do ir=1,mmax
1033 : : !test=vloc(ir)+zion/rad(ir)
1034 : : !Ignore contributions within decade of machine precision (supressed ...)
1035 : : !if ((scale+abs(test)).eq.scale) then
1036 : : !work(ir)=0.0d0
1037 : : !else
1038 : 600 : work(ir)=(sin(arg*rad(ir))+arg*rad(ir)*cos(arg*rad(ir))) * (rad(ir)*vloc(ir)+zion)
1039 : : !end if
1040 : 601 : work(ir)=work(ir)*drdi(ir)
1041 : : end do
1042 : :
1043 : 1 : call ctrap(mmax,work,one,result_ctrap)
1044 : 1 : ypn=2.0d0 * (ztor1 + result_ctrap)
1045 [ - + ]: 1 : ABI_FREE(work)
1046 : :
1047 : 1 : end subroutine psp11lo
1048 : : !!***
1049 : :
1050 : : end module m_upf2abinit
1051 : : !!***
|