24 use,
intrinsic :: iso_fortran_env
31#ifdef HAVE_LIBXC_FUNCS
53 character(len=1),
parameter :: &
54 spec_notation(0:3) = (/
's',
'p',
'd',
'f' /)
56 integer,
parameter :: VALCONF_STRING_LENGTH = 80
61 character(len=3) :: symbol =
""
66 real(real64) :: occ(15,2) =
m_zero
67 real(real64) :: j(15) =
m_zero
75 type(valconf_t),
intent(out) :: cout
76 type(valconf_t),
intent(in) :: cin
81 cout%symbol = cin%symbol
93 type(valconf_t),
intent(inout) :: c
94 integer,
intent(in) :: lmax
97 integer,
allocatable :: order(:)
98 type(valconf_t) :: tmp_c
105 safe_allocate(order(1:lmax+1))
106 call sort(c%l(1:lmax+1), order)
108 c%occ(ll+1, 1:2) = tmp_c%occ(order(ll+1), 1:2)
109 c%n(ll+1) = tmp_c%n(order(ll+1))
110 c%j(ll+1) = tmp_c%j(order(ll+1))
112 safe_deallocate_a(order)
119 type(valconf_t),
intent(in) :: c
120 character(len=VALCONF_STRING_LENGTH),
intent(out) :: s
126 write(s,
'(i2,1x,a2,i1,1x,i1,a1,6(i1,a1,f6.3,a1))') c%z, c%symbol, c%type, c%p,
':',&
127 (c%n(j),spec_notation(c%l(j)),c%occ(j,1),
',',j=1,c%p)
135 type(namespace_t),
intent(in) :: namespace
136 character(len=VALCONF_STRING_LENGTH),
intent(in) :: s
137 type(valconf_t),
intent(out) :: c
140 character(len=1) :: lvalues(1:6)
144 read (s,
'(i2,1x,a2,i1,1x,i1,1x,6(i1,a1,f6.3,1x))') c%z, c%symbol, c%type, c%p,&
145 (c%n(j),lvalues(j),c%occ(j,1),j=1,c%p)
147 select case (lvalues(j))
179 conf%occ(ii, 1) = min(xx, real(2*ll+1, real64) )
180 conf%occ(ii, 2) = xx -
conf%occ(ii,1)
188 subroutine atomhxc(namespace, functl, g, nspin, dens, v, extra)
190 character(len=*),
intent(in) :: functl
192 integer,
intent(in) :: nspin
193 real(real64),
intent(in) :: dens(g%nrval, nspin)
194 real(real64),
intent(out) :: v(g%nrval, nspin)
195 real(real64),
intent(in),
optional :: extra(g%nrval)
197 character(len=5) :: xcfunc, xcauth
199 real(real64),
allocatable :: xc(:, :), ve(:, :), rho(:, :)
200 real(real64) :: r2, ex, ec, dx, dc
204 safe_allocate( ve(1:g%nrval, 1:nspin))
205 safe_allocate( xc(1:g%nrval, 1:nspin))
206 safe_allocate(rho(1:g%nrval, 1:nspin))
213 rho(:, 1) = rho(:, 1) + dens(:, is)
217 call vhrtre(rho(:, 1), ve(:, is), g%rofi, g%drdi, g%s, g%nrval, g%a)
219 ve(1, 1:nspin) = ve(2, 1:nspin)
229 message(1) =
'Internal Error in atomhxc: unknown functl'
233 rho(:, :) = dens(:, :)
235 if (
present(extra)) rho(:, is) = rho(:, is) + extra(:)/nspin
236 rho(2:g%nrval, is) = rho(2:g%nrval, is)/(
m_four*
m_pi*g%r2ofi(2:g%nrval))
238 r2 = g%rofi(2)/(g%rofi(3)-g%rofi(2))
239 rho(1, 1:nspin) = rho(2, 1:nspin) - (rho(3, 1:nspin)-rho(2, 1:nspin))*r2
247 call atomxc(namespace, xcfunc, xcauth, g%nrval, g%nrval, g%rofi, nspin, rho, ex, ec, dx, dc, xc)
250 safe_deallocate_a(ve)
251 safe_deallocate_a(xc)
252 safe_deallocate_a(rho)
297 subroutine atomxc(namespace, FUNCTL, AUTHOR, NR, MAXR, RMESH, NSPIN, DENS, EX, EC, DX, DC, V_XC)
299 character(len=*),
intent(in) :: functl, author
300 integer,
intent(in) :: nr, maxr
301 real(real64),
intent(in) :: rmesh(maxr)
302 integer,
intent(in) :: nspin
303 real(real64),
intent(in) :: dens(maxr,nspin)
304 real(real64),
intent(out) :: dc, dx, ec, ex, v_xc(maxr,nspin)
312 integer,
parameter :: nn = 5
320 real(real64),
parameter :: eunit =
m_half
326 real(real64),
parameter :: dvmin = 1.0e-12_real64
333 integer :: in, in1, in2, ir, is, jn
334 real(real64) :: aux(maxr), d(nspin), &
335 dgdm(-nn:nn), dgidfj(-nn:nn), drdm, dvol, &
336 f1, f2, gd(3,nspin), sigma(3), vxsigma(3), vcsigma(3), &
338 dexdd(nspin), dexdgd(3,nspin), decdd(nspin), decdgd(3,nspin)
339 type(xc_f03_func_t) :: x_conf, c_conf
344 assert(nspin == 1 .or. nspin == 2)
347 if (functl .eq.
'LDA' .or. functl .eq.
'lda' .or. &
348 functl .eq.
'LSD' .or. functl .eq.
'lsd')
then
350 else if (functl .eq.
'GGA' .or. functl .eq.
'gga')
then
354 write(
message(1),
'(a,a)')
'atomxc: Unknown functional ', functl
360 call xc_f03_func_init(x_conf, xc_gga_x_pbe, nspin)
361 call xc_f03_func_init(c_conf, xc_gga_c_pbe, nspin)
363 call xc_f03_func_init(x_conf, xc_lda_x, nspin)
364 if (author .eq.
'CA' .or. author .eq.
'ca' .or. &
365 author .eq.
'PZ' .or. author .eq.
'pz')
then
366 call xc_f03_func_init(c_conf, xc_lda_c_pz, nspin)
367 else if (author .eq.
'PW92' .or. author .eq.
'pw92')
then
368 call xc_f03_func_init(c_conf, xc_lda_c_pw, nspin)
370 write(
message(1),
'(a,a)')
'LDAXC: Unknown author ', author
396 in1 = max( 1, ir-nn ) - ir
397 in2 = min( nr, ir+nn ) - ir
405 if (jn /= 0) dgdm(in) = dgdm(in) +
m_one / (0 - jn)
411 if (jn /= in .and. jn /= 0) f1 = f1 * (0 - jn)
412 if (jn /= in) f2 = f2 * (in - jn)
421 drdm = drdm + rmesh(ir+in) * dgdm(in)
425 dvol = 4 *
m_pi * rmesh(ir)**2 * drdm
428 dvol = safe_tol(dvol, dvmin)
429 if (ir == 1 .or. ir == nr) dvol = dvol / 2
430 if (gga) aux(ir) = dvol
436 dgidfj(in) = dgdm(in) / drdm
448 gd(3,is) = gd(3,is) + dgidfj(in) * dens(ir+in,is)
457 sigma(1) = gd(3, 1)*gd(3, 1)
459 sigma(2) = gd(3, 1) * gd(3, 2)
460 sigma(3) = gd(3, 2) * gd(3, 2)
466 call xc_f03_gga_exc_vxc(x_conf, int(1, c_size_t), d, sigma, epsx, dexdd, vxsigma)
467 call xc_f03_gga_exc_vxc(c_conf, int(1, c_size_t), d, sigma, epsc, decdd, vcsigma)
469 call xc_f03_lda_exc_vxc(x_conf, int(1, c_size_t), d, epsx, dexdd)
470 call xc_f03_lda_exc_vxc(c_conf, int(1, c_size_t), d, epsc, decdd)
477 dexdgd(:, 1) =
m_two * vxsigma(1) * gd(:, 1)
478 decdgd(:, 1) =
m_two * vcsigma(1) * gd(:, 1)
480 dexdgd(:, 1) = dexdgd(:, 1) + vxsigma(2)*gd(:, 2)
481 dexdgd(:, 2) =
m_two * vxsigma(3) * gd(:, 2) + vxsigma(2) * gd(:, 1)
482 decdgd(:, 1) = decdgd(:, 1) + vcsigma(2)*gd(:, 2)
483 decdgd(:, 2) =
m_two * vcsigma(3) * gd(:, 2) + vcsigma(2) * gd(:, 1)
490 ex = ex + dvol * d(is) * epsx(1)
491 ec = ec + dvol * d(is) * epsc(1)
492 dx = dx + dvol * d(is) * (epsx(1) - dexdd(is))
493 dc = dc + dvol * d(is) * (epsc(1) - decdd(is))
495 v_xc(ir,is) = v_xc(ir,is) + dvol * (dexdd(is) + decdd(is))
497 dx = dx - dvol * dens(ir+in,is) * dexdgd(3,is) * dgidfj(in)
498 dc = dc - dvol * dens(ir+in,is) * decdgd(3,is) * dgidfj(in)
499 v_xc(ir+in,is) = v_xc(ir+in,is) + dvol * &
500 (dexdgd(3,is) + decdgd(3,is)) * dgidfj(in)
503 v_xc(ir,is) = dexdd(is) + decdd(is)
517 v_xc(ir,is) = v_xc(ir,is) / dvol
532 v_xc(ir,is) = v_xc(ir,is) / eunit
536 call xc_f03_func_end(x_conf)
537 call xc_f03_func_end(c_conf)
562 subroutine vhrtre(rho, v, r, drdi, srdrdi, nr, a)
563 real(real64),
intent(in) :: rho(:)
564 real(real64),
intent(out) :: v(:)
565 real(real64),
intent(in) :: r(:), drdi(:), srdrdi(:)
566 integer,
intent(in) :: nr
567 real(real64),
intent(in) :: a
569 real(real64) :: x,y,q,a2by4,ybyq,qbyy,qpartc,v0,qt,dz,t,beta,dv
570 integer :: nrm1,nrm2,ir
577 ybyq =
m_one - a*a/48.0_real64
592 dz = drdi(ir)*rho(ir)
598 dz = drdi(ir)*rho(ir)
602 dz = drdi(nr)*rho(nr)
604 qt = (qt + qt + dz)*
m_half
605 v0 = (v0 + v0 + dz/r(nr))
616 beta = drdi(ir)*t*rho(ir)
634 q = (y - beta / 12.0_real64) * qbyy
635 v(ir) =
m_two * t * q
642 x = x + a2by4 * q - beta
644 t = srdrdi(ir) / r(ir)
645 beta = t * drdi(ir) * rho(ir)
646 q = (y - beta / 12.0_real64) * qbyy
647 v(ir) =
m_two * t * q
659 qpartc = r(nr)*v(nr)/
m_two
700 subroutine egofv(namespace, h, s, n, e, g, y, l, z, a, b, rmax, nprin, nnode, dr, ierr)
702 real(real64),
intent(in) :: h(:), s(:)
703 integer,
intent(in) :: n
704 real(real64),
intent(inout) :: e
705 real(real64),
intent(out) :: g(:), y(:)
706 integer,
intent(in) :: l
707 real(real64),
intent(in) :: z, a, b, rmax
708 integer,
intent(in) :: nprin, nnode
709 real(real64),
intent(in) :: dr
710 integer,
intent(out) :: ierr
712 integer :: i,ncor,n1,n2,niter,nt
713 real(real64) :: e1, e2, del, de, et, t
714 real(real64),
parameter :: tol = 1.0e-5_real64
762 if (.not. (et <= e1 .or. et >= e2 .or. nt < nnode-1 .or. nt > nnode))
then
764 if (abs(de) < tol)
then
769 call yofe(e,de,dr,rmax,h,s,y,n,l,ncor,nt,z,a,b)
792 if (n2 >= nnode) cycle
812 if (n1 < nnode) cycle
831 g(i) = y(i) / (
m_one - t / 12._real64)
833 call nrmlzg(namespace, g, s, n)
840 subroutine yofe(e,de,dr,rmax,h,s,y,nmax,l,ncor,nnode,z,a,b)
861 real(real64),
intent(inout) :: e
862 real(real64),
intent(out) :: de
863 real(real64),
intent(in) :: dr, rmax
864 real(real64),
intent(in) :: h(:), s(:)
865 real(real64),
intent(out) :: y(:)
866 integer,
intent(in) :: nmax, l
867 integer,
intent(in) :: ncor
868 integer,
intent(out) :: nnode
869 real(real64),
intent(in) :: z, a, b
871 real(real64) :: y2, g, gsg, x, gin, gsgin, xin
872 integer :: n,knk,nndin,i
873 real(real64) :: zdr, yn, ratio, t
880 if (h(n)-e*s(n) <
m_one)
then
887 call bcorgn(e,h,s,l,zdr,y2)
896 call numout(e,h,s,y,ncor,knk,nnode,y2,g,gsg,x)
910 if (.not. (n < nmax .or. abs(dr) > 1.e3_real64))
then
911 call bcrmax(e,dr,rmax,h,s,n,yn,a,b)
925 call numin(e,h,s,y,n,nndin,yn,gin,gsgin,xin,knk)
939 gsg = gsg + gsgin * ratio * ratio
940 t = h(knk) - e * s(knk)
941 de = g * (x + xin + t * g) / gsg
942 nnode = nnode + nndin
943 if (de <
m_zero) nnode = nnode + 1
952 subroutine nrmlzg(namespace, g, s, n)
975 real(real64),
intent(inout) :: g(:)
976 real(real64),
intent(in) :: s(:)
977 integer,
intent(in) :: n
980 real(real64) :: norm, srnrm
989 if (mod(n,2) /= 1)
then
990 write(
message(1),
'(a,i6)')
' nrmlzg: n should be odd. n =', n
997 norm=norm + g(i)*s(i)*g(i)
1002 norm=norm + g(i)*s(i)*g(i)
1007 norm = norm + g(i) * s(i) * g(i)
1019 subroutine bcorgn(e,h,s,l,zdr,y2)
1020 real(real64),
intent(in) :: e
1021 real(real64),
intent(in) :: h(:), s(:)
1022 integer,
intent(in) :: l
1023 real(real64),
intent(in) :: zdr
1024 real(real64),
intent(out) :: y2
1026 real(real64) :: t2, t3, d2, c0, c1, c2
1035 t2 = h(2) - e * s(2)
1036 d2 = -((24._real64 + 10.0_real64 * t2) / (12._real64 - t2))
1052 c0=c0/(
m_one-0.75_real64*zdr)
1058 c1=c0*(12._real64+13._real64*t2)/(12._real64-t2)
1060 c2=(-
m_half)*c0*(24._real64-t3)/(12._real64-t3)
1061 d2=(d2-c1)/(
m_one-c2)
1068 c0=c0/(
m_one-0.75_real64*zdr)
1073 c1=c0*(12._real64+13._real64*t2)/(12._real64-t2)
1075 c2=(-
m_half)*c0*(24._real64-t3)/(12._real64-t3)
1076 d2=(d2-c1)/(
m_one-c2)
1086 subroutine bcrmax(e, dr, rmax, h, s, n, yn, a, b)
1087 real(real64),
intent(in) :: e, dr, rmax
1088 real(real64),
intent(in) :: h(:), s(:)
1089 integer,
intent(in) :: n
1090 real(real64),
intent(out) :: yn
1091 real(real64),
intent(in) :: a, b
1093 real(real64) :: tnm1, tn, tnp1, beta, dg, c1, c2, c3, dn
1097 tnm1=h(n-1)-e*s(n-1)
1099 tnp1=h(n+1)-e*s(n+1)
1103 c2=24._real64*dg/(12._real64-tn)
1104 dn=-((24._real64+10._real64*tn)/(12._real64-tn))
1106 c1= (
m_one-tnm1/6.0_real64)/(
m_one-tnm1/12._real64)
1107 c3=-((
m_one-tnp1/6.0_real64)/(
m_one-tnp1/12._real64))
1108 yn=-((
m_one-c1/c3)/(dn-c2/c3))
1114 subroutine numin(e,h,s,y,n,nnode,yn,g,gsg,x,knk)
1115 real(real64),
intent(in) :: e, h(:), s(:)
1116 real(real64),
intent(inout) :: y(:)
1117 integer,
intent(in) :: n
1118 integer,
intent(out) :: nnode
1119 real(real64),
intent(in) :: yn
1120 real(real64),
intent(out) :: g, gsg, x
1121 integer,
intent(in) :: knk
1130 g=y(n)/(
m_one-t/12._real64)
1135 g=y(i)/(
m_one-t/12._real64)
1149 do i = n - 2, knk, -1
1156 g = y(i) / (
m_one - t / 12._real64)
1157 gsg = gsg + g * s(i) * g
1171 end subroutine numin
1174 subroutine numout(e, h, s, y, ncor, knk, nnode, y2, g, gsg, x)
1175 real(real64),
intent(in) :: e, h(:), s(:)
1176 real(real64),
intent(inout) :: y(:)
1177 integer,
intent(in) :: ncor
1178 integer,
intent(inout) :: knk
1179 integer,
intent(out) :: nnode
1180 real(real64),
intent(in) :: y2
1181 real(real64),
intent(out) :: g, gsg, x
1184 real(real64) :: t, xl
1191 g=y(2)/(
m_one-t/12._real64)
1195 g=y(3)/(
m_one-t/12._real64)
1216 g = y(i) / (
m_one - t / 12._real64)
1217 gsg = gsg + g * s(i) * g
1218 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 bcrmax(e, dr, rmax, h, s, n, yn, a, b)
subroutine, public atomhxc(namespace, functl, g, nspin, dens, v, extra)
subroutine, public write_valconf(c, s)
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
subroutine, public valconf_copy(cout, cin)
subroutine, public valconf_sort_by_l(c, lmax)
subroutine, public read_valconf(namespace, s, c)
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
type(conf_t), public conf
Global instance of Octopus configuration.
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)
This module is intended to contain "only mathematical" functions and procedures.