26 use,
intrinsic :: iso_fortran_env
46 type(ps_psf_file_t),
private :: psf_file
47 type(ps_in_grid_t) :: ps_grid
49 type(valconf_t) :: conf
50 real(real64),
allocatable,
private :: eigen(:, :)
51 integer,
private :: ispin
57 subroutine ps_psf_init(pstm, ispin, filename, namespace)
58 type(ps_psf_t),
intent(inout) :: pstm
59 integer,
intent(in) :: ispin
60 character(len=*),
intent(in) :: filename
61 type(namespace_t),
intent(in) :: namespace
63 character(len=MAX_PATH_LEN) :: fullpath
65 logical :: found, ascii
76 assert(trim(filename) /=
'')
79 fullpath = trim(filename)
80 inquire(file = fullpath, exist = found)
83 message(1) =
"Pseudopotential file '" // trim(fullpath) //
" not found"
88 iunit =
io_open(fullpath, action=
'read', form=
'formatted', status=
'old')
90 iunit =
io_open(fullpath, action=
'read', form=
'unformatted', status=
'old')
96 call build_valconf(pstm%psf_file, ispin, pstm%conf, namespace)
99 if (mod(pstm%psf_file%nr, 2) == 0) pstm%psf_file%nr = pstm%psf_file%nr - 1
109 type(ps_psf_t),
intent(inout) :: ps_psf
113 safe_deallocate_a(ps_psf%eigen)
123 type(ps_psf_file_t),
intent(in) :: psf_file
124 integer,
intent(in) :: ispin
125 type(valconf_t),
intent(out) :: conf
126 type(namespace_t),
intent(in) :: namespace
128 character(len=1) :: char1(6), char2
129 character(len=256) :: r_fmt
134 conf%symbol = psf_file%namatm
135 conf%p = psf_file%npotd
136 write(char2,
'(i1)') conf%p
138 select case (psf_file%irel)
140 write(r_fmt,
'(3a)')
'(', char2,
'(i1,a1,f5.2,10x))'
141 read(psf_file%title, r_fmt) &
142 (conf%n(l), char1(l), conf%occ(l,1), l = 1, conf%p)
144 write(r_fmt,
'(3a)')
'(', char2,
'(i1,a1,f4.2,1x,f4.2,6x))'
145 read(psf_file%title, r_fmt) &
146 (conf%n(l), char1(l), conf%occ(l,1), conf%occ(l,2), l = 1, conf%p)
148 write(r_fmt,
'(3a)')
'(', char2,
'(i1,a1,f5.2,10x))'
149 read(psf_file%title, r_fmt) &
150 (conf%n(l), char1(l), conf%occ(l,1), l = 1, conf%p)
154 select case (char1(l))
164 message(1) =
'Error reading pseudopotential file.'
169 if (ispin == 2 .and. psf_file%irel /=
'isp')
then
187 logrid_psf, psf_file%a, psf_file%b, psf_file%nr, &
188 psf_file%npotd, psf_file%npotu)
190 nrval = ps_grid%g%nrval
192 ps_grid%zval = psf_file%zval
193 ps_grid%vps(1:nrval,:) = psf_file%vps(1:nrval,:)
194 ps_grid%chcore(1:nrval) = psf_file%chcore(1:nrval)
195 if (ps_grid%so_no_l_channels > 0)
then
196 ps_grid%so_vps(1:nrval,:) = psf_file%vso(1:nrval,:)
199 ps_grid%core_corrections = .
true.
200 if (trim(psf_file%icore) ==
'nc') ps_grid%core_corrections = .false.
208 type(
ps_psf_t),
intent(inout) :: ps_psf
210 integer,
intent(in) :: lmax, lloc
212 push_sub(psf_process)
215 safe_allocate(ps_psf%eigen(1:ps_psf%psf_file%npotd, 1:3))
217 ps_psf%conf, ps_psf%ispin, ps_psf%ps_grid%rphi, ps_psf%eigen)
229 call ghost_analysis(ps_psf%psf_file, ps_psf%ps_grid, ps_psf%ps_grid%g, namespace, ps_psf%eigen, lmax)
242 type(
ps_psf_t),
intent(in) :: ps_psf
243 real(real64),
intent(out) :: eigen(:,:)
249 do i = 1, ps_psf%conf%p
250 if (ps_psf%ispin == 1)
then
251 eigen(i, 1) = ps_psf%eigen(i, 1)
253 eigen(i, 1:2) = ps_psf%eigen(i, 2:3)
266 integer,
intent(in) :: ispin
267 real(real64),
intent(out) :: rphi(:,:,:), eigen(:,:)
270 character(len=3) :: functl
271 integer :: iter, ir, is, l, nnode, nprin, ierr
272 real(real64) :: vtot, diff, a2b4
273 real(real64),
allocatable :: ve(:, :), rho(:, :), prev(:, :)
277 real(real64) :: e, z, dr, rmax
278 real(real64),
allocatable :: s(:), hato(:), gg(:), y(:)
283 safe_allocate(s(1:g%nrval))
284 safe_allocate(hato(1:g%nrval))
285 safe_allocate(gg(1:g%nrval))
286 safe_allocate(y(1:g%nrval))
287 safe_allocate(ve(1:g%nrval, 1:ispin))
288 safe_allocate(rho(1:g%nrval, 1:ispin))
289 safe_allocate(prev(1:g%nrval, 1:ispin))
303 if ((psf_file%icore ==
'pche') .or. (psf_file%icore ==
'fche'))
then
304 call vhrtre(psf_file%chcore, ve(:, 1), g%rofi, g%drdi, g%s, g%nrval, g%a)
305 do l = 1, psf_file%npotd
306 psf_file%vps(:, l) = psf_file%vps(:, l) + ve(:, 1)
313 rho(1:g%nrval, 1) = psf_file%rho_val(1:g%nrval)
314 select case (psf_file%icorr)
321 call atomhxc(namespace, functl, g, 1, rho(:, 1:1), ve(:, 1:1), psf_file%chcore)
327 do l = 1, psf_file%npotd
329 vtot = psf_file%vps(ir, l) + ve(ir, 1) + real((l-1)*l, real64)/(g%r2ofi(ir))
330 hato(ir) = vtot*s(ir) + a2b4
336 e = -((psf_file%zval/real(nprin, real64) )**2)
339 rmax = g%rofi(g%nrval)
341 call egofv(namespace, hato, s, g%nrval, e, gg, y, l-1, z, &
342 real(g%a, real64) ,
real(g%b, real64) , rmax, nprin, nnode, dr, ierr)
345 write(
message(1),
'(a)')
'The algorithm that calculates atomic wavefunctions could not'
346 write(
message(2),
'(a)')
'do its job. The program will terminate, since the wavefunctions'
347 write(
message(3),
'(a)')
'are needed. Change the pseudopotential or improve the code.'
352 rphi(:, l, 1) = gg(:) *
sqrt(g%drdi(:))
357 rphi(:, :, 2) = rphi(:, :, 1)
360 spin_polarized:
if (ispin == 2)
then
370 spin:
do is = 1, ispin
371 ang:
do l = 1, psf_file%npotd
373 vtot = psf_file%vps(ir, l) + ve(ir, is) + real((l-1)*l, real64)/g%r2ofi(ir)
374 hato(ir) = vtot*s(ir) + a2b4
380 e = -((psf_file%zval/real(nprin, real64) )**2)
383 rmax = g%rofi(g%nrval)
385 call egofv(namespace, hato, s, g%nrval, e, gg, y, l-1, z, &
386 real(g%a, real64) ,
real(g%b, real64) , rmax, nprin, nnode, dr, ierr)
389 write(
message(1),
'(a)')
'The algorithm that calculates atomic wavefunctions could not'
390 write(
message(2),
'(a)')
'do its job. The program will terminate, since the wavefunctions'
391 write(
message(3),
'(a)')
'are needed. Change the pseudopotential or improve the code.'
396 rphi(:, l, 1 + is) = gg(:) *
sqrt(g%drdi(:))
402 do l = 1, psf_file%npotd
403 rho(:, is) = rho(:, is) + conf%occ(l, is)*rphi(:, l, 1 + is)**2
409 diff = diff +
sqrt(sum(g%drdi(:) * (rho(:, is) - prev(:, is))**2))
412 if (diff <
m_epsilon*1e2_real64)
exit self_consistent
418 call atomhxc(namespace, functl, g, 2, rho, ve, psf_file%chcore)
419 end do self_consistent
421 end if spin_polarized
425 safe_deallocate_a(hato)
426 safe_deallocate_a(gg)
428 safe_deallocate_a(ve)
429 safe_deallocate_a(rho)
430 safe_deallocate_a(prev)
437 subroutine ghost_analysis(psf_file, ps_grid, g, namespace, eigen, lmax)
442 real(real64),
intent(in) :: eigen(:,:)
443 integer,
intent(in) :: lmax
445 character(len=3) :: functl
446 integer :: ir, l, nnode, nprin, ighost, ierr
447 real(real64) :: vtot, a2b4
448 real(real64),
allocatable :: ve(:), elocal(:,:)
450 real(real64) :: z, e, dr, rmax
451 real(real64),
allocatable :: hato(:), s(:), gg(:), y(:)
455 safe_allocate(ve(1:g%nrval))
456 safe_allocate(s(1:g%nrval))
457 safe_allocate(hato(1:g%nrval))
458 safe_allocate(gg(1:g%nrval))
459 safe_allocate(y(1:g%nrval))
460 safe_allocate(elocal(1:2, 1:lmax+1))
462 select case (psf_file%icorr)
469 call atomhxc(namespace, functl, g, 1, psf_file%rho_val(:), ve(:), ps_grid%chcore(:))
477 vtot = ps_grid%vlocal(ir) + ve(ir) + real((l-1)*l, real64)/(g%r2ofi(ir))
478 hato(ir) = vtot*s(ir) + a2b4
484 e = -(ps_grid%zval/real(nprin, real64) )**2
487 rmax = g%rofi(g%nrval)
489 call egofv(namespace, hato, s, g%nrval, e, gg, y, l, z, &
490 real(g%a, real64) ,
real(g%b, real64) , rmax, nprin, nnode, dr, ierr)
500 if (ps_grid%dkbcos(l) >
m_zero)
then
501 if (eigen(l, 1) > elocal(2, l))
then
504 else if (ps_grid%dkbcos(l) <
m_zero)
then
505 if (eigen(l, 1) > elocal(1, l))
then
510 if (ighost >= 0)
then
511 write(
message(1),
'(a,i2)')
"Ghost state found for l = ", l
516 safe_deallocate_a(hato)
517 safe_deallocate_a(gg)
519 safe_deallocate_a(elocal)
521 safe_deallocate_a(ve)
double sqrt(double __x) __attribute__((__nothrow__
subroutine, public atomhxc(namespace, functl, g, nspin, dens, v, extra)
subroutine, public valconf_unpolarized_to_polarized(conf)
subroutine, public vhrtre(rho, v, r, drdi, srdrdi, nr, a)
VHRTRE CONSTRUCTS THE ELECTROSTATIC POTENTIAL DUE TO A SUPPLIED ! ELECTRON DENSITY....
subroutine, public egofv(namespace, h, s, n, e, g, y, l, z, a, b, rmax, nprin, nnode, dr, ierr)
egofv determines the eigenenergy and wavefunction corresponding ! to a particular l,...
real(real64), parameter, public m_zero
real(real64), parameter, public m_fourth
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_half
real(real64), parameter, public m_three
subroutine, public io_close(iunit, grp)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
integer, parameter, public logrid_psf
log grid used in Troullier-Martins code
subroutine, public messages_warning(no_lines, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public ps_in_grid_kb_projectors(ps)
KB-projectors kb = (vps - vlocal) |phi> * dknorm.
subroutine, public ps_in_grid_end(ps)
subroutine, public ps_in_grid_cutoff_radii(ps, lloc)
subroutine, public ps_in_grid_init(ps, flavor, a, b, nrval, no_l, so_no_l)
subroutine, public ps_in_grid_kb_cosines(ps, lloc)
KB-cosines and KB-norms: dkbcos stores the KB "cosines:" || (v_l - v_local) phi_l ||^2 / < (v_l - v_l...
subroutine, public ps_in_grid_vlocal(ps, l_loc, rcore, namespace)
real(real64) function, public first_point_extrapolate(x, y, high_order)
subroutine, public ps_in_grid_check_rphi(ps, namespace)
checks normalization of the pseudo wavefunctions
subroutine, public ps_psf_file_end(psf)
subroutine, public ps_psf_file_read(unit, ascii, psf, namespace)
subroutine, public ps_psf_init(pstm, ispin, filename, namespace)
subroutine, public ps_psf_process(ps_psf, namespace, lmax, lloc)
subroutine solve_schroedinger(psf_file, namespace, g, conf, ispin, rphi, eigen)
subroutine ghost_analysis(psf_file, ps_grid, g, namespace, eigen, lmax)
subroutine build_valconf(psf_file, ispin, conf, namespace)
subroutine, public ps_psf_get_eigen(ps_psf, eigen)
subroutine, public ps_psf_end(ps_psf)
subroutine file_to_grid(psf_file, ps_grid)