537
537
if (use_psml_vlocal) then
538
538
call get_psml_vlocal_chlocal(basp%psml_handle,is,
539
$ rofi,drdi,nrval,a,b,Zval,vlocal,
539
$ rofi,drdi,nrval,Zval,vlocal,
540
540
$ chlocal,nchloc)
542
542
if (write_ion_plot_files) then
2440
2440
end subroutine read_vps
2442
subroutine get_psml_vlocal_chlocal(ps,is,rofi,drdi,nrval,a,b,
2442
subroutine get_psml_vlocal_chlocal(ps,is,rofi,drdi,nrval,
2443
2443
$ Zval,vlocal,chlocal,nchloc)
2445
use m_hamann, only: derivs, dpnint
2445
2447
!! Extracts Vlocal from PSML file and computes Chlocal
2446
2448
!! by computing its Laplacian
2452
2454
real(dp), intent(in) :: rofi(:)
2453
2455
real(dp), intent(in) :: drdi(:)
2454
2456
integer, intent(in) :: nrval
2455
real(dp), intent(in) :: a, b ! r(i) = b*(exp(a(i-1))-1)
2456
2457
real(dp), intent(in) :: Zval
2457
2458
real(dp), intent(out) :: vlocal(:)
2458
2459
real(dp), intent(out) :: chlocal(:)
2459
2460
integer, intent(out) :: nchloc
2462
integer :: ir, i, mmax, n0, npts, nrange
2462
2463
integer :: nchloc_charge, nchloc_vlocal
2464
integer :: poly_order_rlin, poly_order_rofi
2463
2465
character(len=40) :: vlocal_type
2465
real(dp) :: qtot, r, g2, charge
2466
real(dp) :: rcut_chloc
2467
real(dp), dimension(:), allocatable :: vlp, vlpp, vllap
2467
real(dp) :: qtot, r, g2, charge, al, rr1, delta, Z
2468
real(dp) :: rcut_chloc, exp_al, r0
2469
real(dp), dimension(:), allocatable :: vl, vlp, vlpp, vllap
2470
real(dp), dimension(:), allocatable :: rr, ch, rlin, chlocal_rlin
2468
2471
real(dp), parameter :: pi = 3.141592653589793_dp
2470
2473
real(dp), parameter :: eps_vlocal=1.0e-5_dp
2494
2495
! Extraction of chlocal
2496
allocate(vlp(nrval),vlpp(nrval),vllap(nrval))
2497
! Set up reference grid in the manner of Don Hamann
2498
! so that we can use his 'derivs' routine below
2500
Z = ps_AtomicNumber(ps)
2502
! al = log(1.012_dp) ! spacing factor
2503
!rr1 = 0.0005_dp / Z ! first point (r(1))
2505
rr1 = fdf_get("psml.chlocal.build.rr1",0.001_dp)
2506
exp_al = fdf_get("psml.chlocal.build.exp_al",1.04_dp)
2507
al = log(exp_al) ! spacing factor
2508
mmax = log(rofi(nrval)/rr1)/al ! range of points
2510
! First point to keep
2511
r0 = fdf_get("psml.chlocal.build.r0",0.004_dp)
2512
if (r0 <= rr1) call die("psml: chlocal build: r0 < rr1")
2514
allocate(rr(mmax),vl(mmax))
2516
rr(i) = rr1 * exp(al*(i-1))
2517
vl(i) = 2.0_dp * ps_LocalPotential_Value(ps,rr(i))
2520
allocate(vlp(mmax),vlpp(mmax),vllap(mmax))
2498
2523
! Compute laplacian by finite differences
2499
call derivs(nrval,vlocal,a,b,rofi,vlp,vlpp,vllap)
2500
chlocal(:) = - vllap(:) / (8.0_dp*pi) ! Rydberg units
2524
call derivs(mmax,vl,al,0.0_dp,rr,vlp,vlpp,vllap)
2525
ch(:) = - vllap(:) / (8.0_dp*pi) ! Rydberg units
2527
call file_out(mmax,rr,ch,
2528
. trim(global_label)//".Chlocal_rr_psml")
2531
! Now interpolate into linear grid, using
2532
! the points from r0 onwards
2533
delta = fdf_get("psml.chlocal.build.delta",0.01_dp)
2534
n0 = log(r0/rr1)/al ! range of points
2535
npts= 2 + rofi(nrval)/delta ! overkill. will have to reduce range
2536
allocate(rlin(npts))
2538
rlin(i) = delta*(i-1)
2541
allocate(chlocal_rlin(npts))
2542
chlocal_rlin(:) = 0.0_dp
2543
! to avoid out-of-range errors in interp routine
2544
nrange = log(rr(mmax)/rr1)/al - 2
2546
$ fdf_get("psml.chlocal.build.poly_order_rlin",7)
2547
call dpnint(rr(n0),ch(n0),mmax-n0+1,rlin,chlocal_rlin,
2548
$ nrange,poly_order=poly_order_rlin)
2549
call file_out(npts,rlin,chlocal_rlin,
2550
. trim(global_label)//".Chlocal_rlin_psml")
2552
! Now interpolate into Siesta's grid
2555
$ fdf_get("psml.chlocal.build.poly_order_rofi",7)
2556
call dpnint(rlin,chlocal_rlin,npts,rofi,chlocal,
2557
$ nrval-20,poly_order=poly_order_rofi)
2559
call file_out(nrval,rofi,chlocal,
2560
. trim(global_label)//".Chlocal_psml")
2562
deallocate(rlin, chlocal_rlin)
2563
deallocate(rr, vl, ch, vlp, vlpp, vllap)
2502
2565
! Compute chlocal cutoff
2503
2566
! This section tries to keep compatibility with Siesta's behavior
2504
2567
! for its own vlocal/chlocal