25 use,
intrinsic :: iso_fortran_env
33#ifdef HAVE_LIBXC_FUNCS
55 integer,
parameter :: VALCONF_STRING_LENGTH = 80
60 character(len=3) :: symbol =
""
65 real(real64) :: occ(15,2) =
m_zero
66 real(real64) :: j(15) =
m_zero
74 type(valconf_t),
intent(out) :: cout
75 type(valconf_t),
intent(in) :: cin
80 cout%symbol = cin%symbol
92 type(valconf_t),
intent(inout) :: c
93 integer,
intent(in) :: lmax
96 integer,
allocatable :: order(:)
97 type(valconf_t) :: tmp_c
104 safe_allocate(order(1:lmax+1))
105 call sort(c%l(1:lmax+1), order)
107 c%occ(ll+1, 1:2) = tmp_c%occ(order(ll+1), 1:2)
108 c%n(ll+1) = tmp_c%n(order(ll+1))
109 c%j(ll+1) = tmp_c%j(order(ll+1))
111 safe_deallocate_a(order)
118 type(valconf_t),
intent(inout) :: conf
128 conf%occ(ii, 1) = min(xx, real(2*ll+1, real64) )
129 conf%occ(ii, 2) = xx - conf%occ(ii,1)
137 subroutine atomhxc(namespace, functl, g, nspin, dens, v, extra)
138 type(namespace_t),
intent(in) :: namespace
139 character(len=*),
intent(in) :: functl
140 type(logrid_t),
intent(in) :: g
141 integer,
intent(in) :: nspin
142 real(real64),
intent(in) :: dens(g%nrval, nspin)
143 real(real64),
intent(out) :: v(g%nrval, nspin)
144 real(real64),
intent(in),
optional :: extra(g%nrval)
146 character(len=5) :: xcfunc, xcauth
148 real(real64),
allocatable :: xc(:, :), ve(:, :), rho(:, :)
149 real(real64) :: r2, ex, ec, dx, dc
153 safe_allocate( ve(1:g%nrval, 1:nspin))
154 safe_allocate( xc(1:g%nrval, 1:nspin))
155 safe_allocate(rho(1:g%nrval, 1:nspin))
162 rho(:, 1) = rho(:, 1) + dens(:, is)
166 call vhrtre(rho(:, 1), ve(:, is), g%rofi, g%drdi, g%s, g%nrval, g%a)
168 ve(1, 1:nspin) = ve(2, 1:nspin)
178 message(1) =
'Internal Error in atomhxc: unknown functl'
182 rho(:, :) = dens(:, :)
184 if (
present(extra)) rho(:, is) = rho(:, is) + extra(:)/nspin
185 rho(2:g%nrval, is) = rho(2:g%nrval, is)/(
m_four*
m_pi*g%r2ofi(2:g%nrval))
187 r2 = g%rofi(2)/(g%rofi(3)-g%rofi(2))
188 rho(1, 1:nspin) = rho(2, 1:nspin) - (rho(3, 1:nspin)-rho(2, 1:nspin))*r2
196 call atomxc(namespace, xcfunc, xcauth, g%nrval, g%nrval, g%rofi, nspin, rho, ex, ec, dx, dc, xc)
199 safe_deallocate_a(ve)
200 safe_deallocate_a(xc)
201 safe_deallocate_a(rho)
246 subroutine atomxc(namespace, FUNCTL, AUTHOR, NR, MAXR, RMESH, NSPIN, DENS, EX, EC, DX, DC, V_XC)
248 character(len=*),
intent(in) :: functl, author
249 integer,
intent(in) :: nr, maxr
250 real(real64),
intent(in) :: rmesh(maxr)
251 integer,
intent(in) :: nspin
252 real(real64),
intent(in) :: dens(maxr,nspin)
253 real(real64),
intent(out) :: dc, dx, ec, ex, v_xc(maxr,nspin)
261 integer,
parameter :: nn = 5
269 real(real64),
parameter :: eunit =
m_half
275 real(real64),
parameter :: dvmin = 1.0e-12_real64
282 integer :: in, in1, in2, ir, is, jn
283 real(real64) :: aux(maxr), dgdm(-nn:nn), dgidfj(-nn:nn), drdm, dvol, f1, f2, gd(3,nspin), &
284 dexdgd(3,nspin), decdgd(3,nspin)
285 real(real64),
target :: d(nspin), sigma(3), vxsigma(3), vcsigma(3), &
286 epsx(1), epsc(1), dexdd(nspin), decdd(nspin)
287 type(xc_f03_func_t) :: x_conf, c_conf
289 logical :: xc_on_host
290 type(
accel_mem_t) :: d_buff, decdd_buff, dexdd_buff, sigma_buff, vxsigma_buff, vcsigma_buff, epsx_buff, epsc_buff
291 real(c_double),
pointer :: p_d(:), p_sigma(:), p_epsx(:), p_epsc(:), p_dexdd(:), p_decdd(:), p_vxsigma(:), p_vcsigma(:)
299 assert(nspin == 1 .or. nspin == 2)
302 if (functl .eq.
'LDA' .or. functl .eq.
'lda' .or. &
303 functl .eq.
'LSD' .or. functl .eq.
'lsd')
then
305 else if (functl .eq.
'GGA' .or. functl .eq.
'gga')
then
309 write(
message(1),
'(a,a)')
'atomxc: Unknown functional ', functl
319 if (author .eq.
'CA' .or. author .eq.
'ca' .or. &
320 author .eq.
'PZ' .or. author .eq.
'pz')
then
322 else if (author .eq.
'PW92' .or. author .eq.
'pw92')
then
325 write(
message(1),
'(a,a)')
'LDAXC: Unknown author ', author
330 if (.not. xc_on_host)
then
365 in1 = max( 1, ir-nn ) - ir
366 in2 = min( nr, ir+nn ) - ir
374 if (jn /= 0) dgdm(in) = dgdm(in) +
m_one / (0 - jn)
380 if (jn /= in .and. jn /= 0) f1 = f1 * (0 - jn)
381 if (jn /= in) f2 = f2 * (in - jn)
390 drdm = drdm + rmesh(ir+in) * dgdm(in)
394 dvol = 4 *
m_pi * rmesh(ir)**2 * drdm
397 dvol = safe_tol(dvol, dvmin)
398 if (ir == 1 .or. ir == nr) dvol = dvol / 2
399 if (gga) aux(ir) = dvol
405 dgidfj(in) = dgdm(in) / drdm
417 gd(3,is) = gd(3,is) + dgidfj(in) * dens(ir+in,is)
426 sigma(1) = gd(3, 1)*gd(3, 1)
428 sigma(2) = gd(3, 1) * gd(3, 2)
429 sigma(3) = gd(3, 2) * gd(3, 2)
432 if (.not. xc_on_host)
then
461 call xc_f03_gga_exc_vxc(x_conf, int(1, c_size_t), p_d, p_sigma, p_epsx, p_dexdd, p_vxsigma)
462 call xc_f03_gga_exc_vxc(c_conf, int(1, c_size_t), p_d, p_sigma, p_epsc, p_decdd, p_vcsigma)
464 call xc_f03_lda_exc_vxc(x_conf, int(1, c_size_t), p_d, p_epsx, p_dexdd)
465 call xc_f03_lda_exc_vxc(c_conf, int(1, c_size_t), p_d, p_epsc, p_decdd)
468 if (.not. xc_on_host)
then
484 dexdgd(:, 1) =
m_two * vxsigma(1) * gd(:, 1)
485 decdgd(:, 1) =
m_two * vcsigma(1) * gd(:, 1)
487 dexdgd(:, 1) = dexdgd(:, 1) + vxsigma(2)*gd(:, 2)
488 dexdgd(:, 2) =
m_two * vxsigma(3) * gd(:, 2) + vxsigma(2) * gd(:, 1)
489 decdgd(:, 1) = decdgd(:, 1) + vcsigma(2)*gd(:, 2)
490 decdgd(:, 2) =
m_two * vcsigma(3) * gd(:, 2) + vcsigma(2) * gd(:, 1)
497 ex = ex + dvol * d(is) * epsx(1)
498 ec = ec + dvol * d(is) * epsc(1)
499 dx = dx + dvol * d(is) * (epsx(1) - dexdd(is))
500 dc = dc + dvol * d(is) * (epsc(1) - decdd(is))
502 v_xc(ir,is) = v_xc(ir,is) + dvol * (dexdd(is) + decdd(is))
504 dx = dx - dvol * dens(ir+in,is) * dexdgd(3,is) * dgidfj(in)
505 dc = dc - dvol * dens(ir+in,is) * decdgd(3,is) * dgidfj(in)
506 v_xc(ir+in,is) = v_xc(ir+in,is) + dvol * &
507 (dexdgd(3,is) + decdgd(3,is)) * dgidfj(in)
510 v_xc(ir,is) = dexdd(is) + decdd(is)
516 if(.not. xc_on_host)
then
538 v_xc(ir,is) = v_xc(ir,is) / dvol
553 v_xc(ir,is) = v_xc(ir,is) / eunit
557 call xc_f03_func_end(x_conf)
558 call xc_f03_func_end(c_conf)
585 subroutine vhrtre(rho, v, r, drdi, srdrdi, nr, a)
586 real(real64),
intent(in) :: rho(:)
587 real(real64),
intent(out) :: v(:)
588 real(real64),
intent(in) :: r(:), drdi(:), srdrdi(:)
589 integer,
intent(in) :: nr
590 real(real64),
intent(in) :: a
592 real(real64) :: x,y,q,a2by4,ybyq,qbyy,qpartc,v0,qt,dz,t,beta,dv
593 integer :: nrm1,nrm2,ir
600 ybyq =
m_one - a*a/48.0_real64
615 dz = drdi(ir)*rho(ir)
621 dz = drdi(ir)*rho(ir)
625 dz = drdi(nr)*rho(nr)
627 qt = (qt + qt + dz)*
m_half
628 v0 = (v0 + v0 + dz/r(nr))
639 beta = drdi(ir)*t*rho(ir)
657 q = (y - beta / 12.0_real64) * qbyy
658 v(ir) =
m_two * t * q
665 x = x + a2by4 * q - beta
667 t = srdrdi(ir) / r(ir)
668 beta = t * drdi(ir) * rho(ir)
669 q = (y - beta / 12.0_real64) * qbyy
670 v(ir) =
m_two * t * q
682 qpartc = r(nr)*v(nr)/
m_two
723 subroutine egofv(namespace, h, s, n, e, g, y, l, z, a, b, rmax, nprin, nnode, dr, ierr)
725 real(real64),
intent(in) :: h(:), s(:)
726 integer,
intent(in) :: n
727 real(real64),
intent(inout) :: e
728 real(real64),
intent(out) :: g(:), y(:)
729 integer,
intent(in) :: l
730 real(real64),
intent(in) :: z, a, b, rmax
731 integer,
intent(in) :: nprin, nnode
732 real(real64),
intent(in) :: dr
733 integer,
intent(out) :: ierr
735 integer :: i,ncor,n1,n2,niter,nt
736 real(real64) :: e1, e2, del, de, et, t
737 real(real64),
parameter :: tol = 1.0e-5_real64
785 if (.not. (et <= e1 .or. et >= e2 .or. nt < nnode-1 .or. nt > nnode))
then
787 if (abs(de) < tol)
then
792 call yofe(e,de,dr,rmax,h,s,y,n,l,ncor,nt,z,a,b)
815 if (n2 >= nnode) cycle
835 if (n1 < nnode) cycle
854 g(i) = y(i) / (
m_one - t / 12._real64)
856 call nrmlzg(namespace, g, s, n)
863 subroutine yofe(e,de,dr,rmax,h,s,y,nmax,l,ncor,nnode,z,a,b)
884 real(real64),
intent(inout) :: e
885 real(real64),
intent(out) :: de
886 real(real64),
intent(in) :: dr, rmax
887 real(real64),
intent(in) :: h(:), s(:)
888 real(real64),
intent(out) :: y(:)
889 integer,
intent(in) :: nmax, l
890 integer,
intent(in) :: ncor
891 integer,
intent(out) :: nnode
892 real(real64),
intent(in) :: z, a, b
894 real(real64) :: y2, g, gsg, x, gin, gsgin, xin
895 integer :: n,knk,nndin,i
896 real(real64) :: zdr, yn, ratio, t
903 if (h(n)-e*s(n) <
m_one)
then
910 call bcorgn(e,h,s,l,zdr,y2)
919 call numout(e,h,s,y,ncor,knk,nnode,y2,g,gsg,x)
933 if (.not. (n < nmax .or. abs(dr) > 1.e3_real64))
then
934 call bcrmax(e,dr,rmax,h,s,n,yn,a,b)
948 call numin(e,h,s,y,n,nndin,yn,gin,gsgin,xin,knk)
962 gsg = gsg + gsgin * ratio * ratio
963 t = h(knk) - e * s(knk)
964 de = g * (x + xin + t * g) / gsg
965 nnode = nnode + nndin
966 if (de <
m_zero) nnode = nnode + 1
975 subroutine nrmlzg(namespace, g, s, n)
998 real(real64),
intent(inout) :: g(:)
999 real(real64),
intent(in) :: s(:)
1000 integer,
intent(in) :: n
1002 integer :: nm1,nm2,i
1003 real(real64) :: norm, srnrm
1012 if (mod(n,2) /= 1)
then
1013 write(
message(1),
'(a,i6)')
' nrmlzg: n should be odd. n =', n
1020 norm=norm + g(i)*s(i)*g(i)
1025 norm=norm + g(i)*s(i)*g(i)
1030 norm = norm + g(i) * s(i) * g(i)
1042 subroutine bcorgn(e,h,s,l,zdr,y2)
1043 real(real64),
intent(in) :: e
1044 real(real64),
intent(in) :: h(:), s(:)
1045 integer,
intent(in) :: l
1046 real(real64),
intent(in) :: zdr
1047 real(real64),
intent(out) :: y2
1049 real(real64) :: t2, t3, d2, c0, c1, c2
1058 t2 = h(2) - e * s(2)
1059 d2 = -((24._real64 + 10.0_real64 * t2) / (12._real64 - t2))
1075 c0=c0/(
m_one-0.75_real64*zdr)
1081 c1=c0*(12._real64+13._real64*t2)/(12._real64-t2)
1083 c2=(-
m_half)*c0*(24._real64-t3)/(12._real64-t3)
1084 d2=(d2-c1)/(
m_one-c2)
1092 c0=c0/(
m_one-0.75_real64*zdr)
1097 c1=c0*(12._real64+13._real64*t2)/(12._real64-t2)
1099 c2=(-
m_half)*c0*(24._real64-t3)/(12._real64-t3)
1100 d2=(d2-c1)/(
m_one-c2)
1110 subroutine bcrmax(e, dr, rmax, h, s, n, yn, a, b)
1111 real(real64),
intent(in) :: e, dr, rmax
1112 real(real64),
intent(in) :: h(:), s(:)
1113 integer,
intent(in) :: n
1114 real(real64),
intent(out) :: yn
1115 real(real64),
intent(in) :: a, b
1117 real(real64) :: tnm1, tn, tnp1, beta, dg, c1, c2, c3, dn
1121 tnm1=h(n-1)-e*s(n-1)
1123 tnp1=h(n+1)-e*s(n+1)
1127 c2=24._real64*dg/(12._real64-tn)
1128 dn=-((24._real64+10._real64*tn)/(12._real64-tn))
1130 c1= (
m_one-tnm1/6.0_real64)/(
m_one-tnm1/12._real64)
1131 c3=-((
m_one-tnp1/6.0_real64)/(
m_one-tnp1/12._real64))
1132 yn=-((
m_one-c1/c3)/(dn-c2/c3))
1138 subroutine numin(e,h,s,y,n,nnode,yn,g,gsg,x,knk)
1139 real(real64),
intent(in) :: e, h(:), s(:)
1140 real(real64),
intent(inout) :: y(:)
1141 integer,
intent(in) :: n
1142 integer,
intent(out) :: nnode
1143 real(real64),
intent(in) :: yn
1144 real(real64),
intent(out) :: g, gsg, x
1145 integer,
intent(in) :: knk
1154 g=y(n)/(
m_one-t/12._real64)
1159 g=y(i)/(
m_one-t/12._real64)
1173 do i = n - 2, knk, -1
1180 g = y(i) / (
m_one - t / 12._real64)
1181 gsg = gsg + g * s(i) * g
1195 end subroutine numin
1198 subroutine numout(e, h, s, y, ncor, knk, nnode, y2, g, gsg, x)
1199 real(real64),
intent(in) :: e, h(:), s(:)
1200 real(real64),
intent(inout) :: y(:)
1201 integer,
intent(in) :: ncor
1202 integer,
intent(inout) :: knk
1203 integer,
intent(out) :: nnode
1204 real(real64),
intent(in) :: y2
1205 real(real64),
intent(out) :: g, gsg, x
1208 real(real64) :: t, xl
1215 g=y(2)/(
m_one-t/12._real64)
1219 g=y(3)/(
m_one-t/12._real64)
1240 g = y(i) / (
m_one - t / 12._real64)
1241 gsg = gsg + g * s(i) * g
1242 if (.not. (nnode < ncor .or. xl*x >
m_zero))
then
This is the common interface to a sorting routine. It performs the shell algorithm,...
double sqrt(double __x) __attribute__((__nothrow__
subroutine, public accel_free_buffer(this, async)
subroutine, public accel_finish()
integer, parameter, public accel_mem_read_write
subroutine bcrmax(e, dr, rmax, h, s, n, yn, a, b)
subroutine, public atomhxc(namespace, functl, g, nspin, dens, v, extra)
subroutine nrmlzg(namespace, g, s, n)
subroutine yofe(e, de, dr, rmax, h, s, y, nmax, l, ncor, nnode, z, a, b)
subroutine, public atomxc(namespace, FUNCTL, AUTHOR, NR, MAXR, RMESH, NSPIN, DENS, EX, EC, DX, DC, V_XC)
Finds total exchange-correlation energy and potential for a ! spherical electron density distribution...
subroutine, public valconf_unpolarized_to_polarized(conf)
integer, parameter, public valconf_string_length
Following stuff is for the "val_conf_t" data type, made to handle atomic configurations.
subroutine, public valconf_copy(cout, cin)
subroutine, public valconf_sort_by_l(c, lmax)
subroutine numin(e, h, s, y, n, nnode, yn, g, gsg, x, knk)
subroutine numout(e, h, s, y, ncor, knk, nnode, y2, g, gsg, x)
subroutine bcorgn(e, h, s, l, zdr, y2)
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_two
real(real64), parameter, public m_zero
real(real64), parameter, public m_four
real(real64), parameter, public m_pi
some mathematical constants
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_half
real(real64), parameter, public m_one
real(real64), parameter, public m_three
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 profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
This module is intended to contain "only mathematical" functions and procedures.
type(type_t), parameter, public type_float
subroutine, public xc_functional_init_func(conf, func_id, nspin, on_cpu)
logical function, public xc_is_using_device(namespace)
Check if XC will run on device (parses config and checks availability)