MODULE ExchangeCorrelations
INTEGER, PARAMETER :: perdew_zunger=0, von_barth_hedin=1, gunnarsson_lundqvist=2, perdew_wang=3
CONTAINS
FUNCTION uxc (r, s, ispin, ixc)
IMPLICIT doubleprecision (a - h, o - z)
DATA gp, bp1, bp2, gf, bf1, bf2 / - .1423d0, 1.0529d0, .3334d0, &
- .0843d0, 1.3981d0, .2611d0 /
DATA ap, bp, cp, dp, af, bf, cf, df / .0311d0, - .048d0, .002d0, &
- .0116d0, .01555d0, - .0269d0, .0007d0, - .0048d0 /
IF (r.lt.1.d-35) goto 100
IF (ixc.eq.3) then
uxc = uxcpw (r, s, ispin)
RETURN
ENDIF
IF (ixc.eq.2) then
uxc = uxcgun (r)
RETURN
ENDIF
IF ( (ixc.lt.0) .or. (ixc.gt.3) ) then
WRITE (6, * ) 'Error in exc: ixc = ', ixc
STOP 1
RETURN
ENDIF
pi = 4.d0 * datan (1.d0)
sinv = (4.d0 * pi * r / 3.d0) ** (1.d0 / 3.d0)
rs = 1.d0 / sinv
IF (ixc.eq.1) goto 200
IF (rs.lt.1.d0) goto 10
srs = sqrt (rs)
excp = gp / (1.d0 + bp1 * srs + bp2 * rs)
excf = gf / (1.d0 + bf1 * srs + bf2 * rs)
uxcp = excp * (1.d0 + 7.d0 / 6.d0 * bp1 * srs + 4.d0 / 3.d0 * bp2 &
* rs) / (1.d0 + bp1 * srs + bp2 * rs)
uxcf = excf * (1.d0 + 7.d0 / 6.d0 * bf1 * srs + 4.d0 / 3.d0 * bf2 &
* rs) / (1.d0 + bf1 * srs + bf2 * rs)
GOTO 20
10 aa = log (rs)
excp = ap * aa + bp + cp * rs * aa + dp * rs
excf = af * aa + bf + cf * rs * aa + df * rs
uxcp = ap * aa + (bp - ap / 3.d0) + 2.d0 / 3.d0 * cp * rs * aa + &
(2.d0 * dp - cp) * rs / 3.d0
uxcf = af * aa + (bf - af / 3.d0) + 2.d0 / 3.d0 * cf * rs * aa + &
(2.d0 * df - cf) * rs / 3.d0
20 f = ( (1.d0 + s) ** (4.d0 / 3.d0) + (1.d0 - s) ** (4.d0 / 3.d0) &
- 2.d0) / (2.d0** (4.d0 / 3.d0) - 2.d0)
ddf = 4.d0 / 3.d0 * ( (1.d0 + s) ** (1.d0 / 3.d0) - (1.d0 - s) ** &
(1.d0 / 3.d0) ) / (2.d0** (4.d0 / 3.d0) - 2.d0)
uxc = uxcp + f * (uxcf - uxcp) + (excf - excp) * (3.d0 - 2.d0 * &
ispin - s) * ddf - .6108871d0 / rs * (1.d0 + (3.d0 - 2.d0 * ispin)&
* s) ** (1.d0 / 3.d0)
RETURN
100 uxc = 0.d0
RETURN
200 x = s / 2.d0 + 0.5d0
xx = 0.5d0 - s / 2.d0
rsf = rs / 75.d0
rsf2 = rsf * rsf
rsf3 = rsf2 * rsf
rsp = rs / 30.d0
rsp2 = rsp * rsp
rsp3 = rsp2 * rsp
fcf = (1.d0 + rsf3) * log (1.d0 + 1.d0 / rsf) + 0.5d0 * rsf - &
rsf2 - 1.d0 / 3.d0
fcp = (1.d0 + rsp3) * log (1.d0 + 1.d0 / rsp) + 0.5d0 * rsp - &
rsp2 - 1.d0 / 3.d0
epscp = - .0504d0 * fcp
epscf = - .0254d0 * fcf
cny = 5.1297628d0 * (epscf - epscp)
IF (x.lt..000001d0) x = .000001d0
IF (xx.lt..000001d0) xx = .000001d0
IF (x.gt..999999d0) x = .999999d0
IF (xx.gt..999999d0) xx = .999999d0
ars = - 1.22177412d0 / rs + cny
brs = - 0.0504d0 * log (1.d0 + 30.d0 / rs) - cny
trx1 = (2.d0 * x) ** (1.d0 / 3.d0)
trx2 = (2.d0 * xx) ** (1.d0 / 3.d0)
IF (ispin.eq.1) vxc = ars * trx1 + brs
IF (ispin.eq.2) vxc = ars * trx2 + brs
uxc = vxc / 2.d0
RETURN
END FUNCTION uxc
FUNCTION uxcgun (x)
IMPLICIT none
REAL(8) uxcgun, uxctim, frs, x, pi
FRS (X) = (3.d0 / (4.d0 * PI * X) ) ** (1.d0 / 3.d0)
UXCtim (X) = - 0.61088d0 / FRS (X) * (1.d0 + 0.0545d0 * FRS (X) &
* dLOG (1.d0 + 11.4d0 / FRS (X) ) )
pi = 4.d0 * datan (1.d0)
uxcgun = uxctim (x)
RETURN
END FUNCTION uxcgun
FUNCTION uxcpw (n, s, ispin)
Implicit None
Double Precision n, s, uxcpw
Integer ispin
Double Precision pi, rs, help
Double Precision exc0, exc1, alpha, e0Q0, e0Q1, e0Q1p, e1Q0, e1Q1, &
e1Q1p, aQ0, aQ1, aQ1p, dexc0, dexc1, dalpha, dexcrs, dexcs, exrsp,&
exrsf, ux0, ux1, uexcha
Double Precision e0p, e0A, e0a1, e0b1, e0b2, e0b3, e0b4
Data e0p, e0A, e0a1, e0b1, e0b2, e0b3, e0b4 / 1.d0, 0.031091d0, &
0.21370d0, 7.5957d0, 3.5876d0, 1.6382d0, 0.49294d0 /
Double Precision e1p, e1A, e1a1, e1b1, e1b2, e1b3, e1b4
Data e1p, e1A, e1a1, e1b1, e1b2, e1b3, e1b4 / 1.d0, 0.015545d0, &
0.20548d0, 14.1189d0, 6.1977d0, 3.3662d0, 0.62517d0 /
Double Precision ap, aA, aa1, ab1, ab2, ab3, ab4
Data ap, aA, aa1, ab1, ab2, ab3, ab4 / 1.d0, 0.016887d0, 0.11125d0,&
10.357d0, 3.6231d0, 0.88026d0, 0.49671d0 /
Double Precision fpp0
Parameter (fpp0 = 1.709921d0)
Double Precision f, fprime
f (s) = ( (1.d0 + s) ** (4.d0 / 3.d0) + (1.d0 - s) ** (4.d0 / &
3.d0) - 2.d0) / (2.d0** (4.d0 / 3.d0) - 2)
fprime (s) = (4.d0 / 3.d0) * ( (1.d0 + s) ** (1.d0 / 3.d0) &
- (1.d0 - s) ** (1.d0 / 3.d0) ) / (2.d0** (4.d0 / 3.d0) - 2.d0)
pi = 4.d0 * datan (1.d0)
help = - 3.d0 / (8 * pi) * (9.d0 * pi / 4.d0) ** (1.d0 / 3.d0)
rs = 1.d0 / ( (4.d0 * pi * n / 3.d0) ) ** (1.d0 / 3.d0)
exrsp = - 3.d0 / (4 * pi * rs) * (9.d0 * pi / 4.d0) ** (1.d0 / &
3.d0)
exrsf = - 0.5772521d0 / rs
ux0 = (4.d0 / 3.d0) * exrsp
ux1 = (4.d0 / 3.d0) * exrsf
exc0 = - 2.d0 * e0A * (1.d0 + e0a1 * rs) * dlog (1.d0 + 1.d0 / &
(2.d0 * e0A * (e0b1 * sqrt (rs) + e0b2 * rs + e0b3 * rs * sqrt ( &
rs) + e0b4 * rs** (e0p + 1.d0) ) ) )
exc1 = - 2.d0 * e1A * (1.d0 + e1a1 * rs) * dlog (1.d0 + 1.d0 / &
(2.d0 * e1A * (e1b1 * sqrt (rs) + e1b2 * rs + e1b3 * rs * sqrt ( &
rs) + e1b4 * rs** (e1p + 1.d0) ) ) )
alpha = 2.d0 * aA * (1.d0 + aa1 * rs) * dlog (1.d0 + 1.d0 / &
(2.d0 * aA * (ab1 * sqrt (rs) + ab2 * rs + ab3 * rs * sqrt (rs) &
+ ab4 * rs** (ap + 1.d0) ) ) )
e0Q0 = - 2.d0 * e0A * (1.d0 + e0a1 * rs)
e1Q0 = - 2.d0 * e1A * (1.d0 + e1a1 * rs)
aQ0 = - 2.d0 * aA * (1.d0 + aa1 * rs)
e0Q1 = 2.d0 * e0A * (e0b1 * sqrt (rs) + e0b2 * rs + e0b3 * rs** ( &
3.d0 / 2.d0) + e0b4 * rs** (e0p + 1.d0) )
e1Q1 = 2.d0 * e1A * (e1b1 * sqrt (rs) + e1b2 * rs + e1b3 * rs** ( &
3.d0 / 2.d0) + e1b4 * rs** (e1p + 1.d0) )
aQ1 = 2.d0 * aA * (ab1 * sqrt (rs) + ab2 * rs + ab3 * rs** (3.d0 /&
2.d0) + ab4 * rs** (ap + 1.d0) )
e0Q1p = e0A * (e0b1 * rs** ( - 1.d0 / 2.d0) + 2.d0 * e0b2 + 3.d0 *&
e0b3 * sqrt (rs) + 2.d0 * (e0p + 1.d0) * e0b4 * rs**e0p)
e1Q1p = e1A * (e1b1 * rs** ( - 1.d0 / 2.d0) + 2.d0 * e1b2 + 3.d0 *&
e1b3 * sqrt (rs) + 2.d0 * (e1p + 1.d0) * e1b4 * rs**e1p)
aQ1p = aA * (ab1 * rs** ( - 1.d0 / 2.d0) + 2.d0 * ab2 + 3.d0 * &
ab3 * sqrt (rs) + 2.d0 * (ap + 1.d0) * ab4 * rs**ap)
dexc0 = - 2.d0 * e0A * e0a1 * dlog (1.d0 + 1.d0 / e0Q1) - (e0Q0 * &
e0Q1p) / (e0Q1**2 + e0Q1)
dexc1 = - 2.d0 * e1A * e1a1 * dlog (1.d0 + 1.d0 / e1Q1) - (e1Q0 * &
e1Q1p) / (e1Q1**2 + e1Q1)
dalpha = 2.d0 * aA * aa1 * dlog (1.d0 + 1.d0 / aQ1) + (aQ0 * aQ1p)&
/ (aQ1**2 + aQ1)
dexcrs = dexc0 * (1.d0 - f (s) * s**4) + dexc1 * f (s) * s**4 + &
dalpha * (1.d0 - s**4) * f (s) / fpp0
dexcs = 4.d0 * s**3 * f (s) * (exc1 - exc0 - alpha / fpp0) &
+ fprime (s) * (s**4 * exc1 - s**4 * exc0 + (1.d0 - s**4) * alpha &
/ fpp0)
uxcpw = excpw (n, s) - (rs / 3.d0) * dexcrs - dexcs * (dble (sign &
(1, (2 * ispin - 3) ) ) + s)
uexcha = ux0 + f (s) * (ux1 - ux0) - (exrsf - exrsp) * (dble ( &
sign (1, (2 * ispin - 3) ) ) + s) * fprime (s) - f (s) * (exrsf - &
exrsp) - exrsp
uxcpw = uxcpw + uexcha
Return
END FUNCTION uxcpw
FUNCTION exc (r, s, ixc)
IMPLICIT REAL (8)(a - h, o - z)
DATA gp, bp1, bp2, gf, bf1, bf2 / - .1423d0, 1.0529d0, .3334d0, &
- .0843d0, 1.3981d0, .2611d0 /
DATA ap, bp, cp, dp, af, bf, cf, df / .0311d0, - .048d0, .002d0, &
- .0116d0, .01555d0, - .0269d0, .0007d0, - .0048d0 /
IF (r.lt.1.d-25) GOTO 100
IF (s.gt.0.99999999d0) s = 0.99999999d0
IF (s.lt. - 0.99999999d0) s = - 0.99999999d0
IF (ixc.eq.3) THEN
exc = excpw (r, s)
RETURN
ENDIF
IF (ixc.eq.2) THEN
exc = excgun (r)
RETURN
ENDIF
IF ( (ixc.lt.0) .or. (ixc.gt.3) ) THEN
WRITE (6, * ) 'Error in exc: ixc = ', ixc
STOP 1
RETURN
ENDIF
IF (r.lt.1.d-25) GOTO 100
pi = 4.d0 * datan (1.d0)
sinv = (4.d0 * pi * r / 3.d0) ** (1.d0 / 3.d0)
rs = 1.d0 / sinv
IF (ixc.eq.1) GOTO 200
IF (rs.lt.1.d0) GOTO 10
srs = SQRT (rs)
excp = gp / (1.d0 + bp1 * srs + bp2 * rs)
excf = gf / (1.d0 + bf1 * srs + bf2 * rs)
GOTO 20
10 aa = LOG (rs)
excp = ap * aa + bp + cp * rs * aa + dp * rs
excf = af * aa + bf + cf * rs * aa + df * rs
20 f = ( (1.d0 + s) ** (4.d0 / 3.d0) + (1.d0 - s) ** (4.d0 / 3.d0) &
- 2.d0) / (2.d0** (4.d0 / 3.d0) - 2.d0)
excf = excf - .5772521d0 / rs
excp = excp - .4581653d0 / rs
exc = excp + f * (excf - excp)
RETURN
100 exc = 0.d0
RETURN
200 x = s / 2.d0 + 0.5d0
d43 = 4.d0 / 3.d0
rsf = rs / 75.d0
rsf2 = rsf * rsf
rsf3 = rsf2 * rsf
rsp = rs / 30.d0
rsp2 = rsp * rsp
rsp3 = rsp2 * rsp
fcf = (1.d0 + rsf3) * LOG (1.d0 + 1.d0 / rsf) + 0.5d0 * rsf - &
rsf2 - 1.d0 / 3.d0
fcp = (1.d0 + rsp3) * LOG (1.d0 + 1.d0 / rsp) + 0.5d0 * rsp - &
rsp2 - 1.d0 / 3.d0
epscp = - .0504d0 * fcp
epscf = - .0254d0 * fcf
epsxp = - .91633059d0 / rs
cny = 5.1297628d0 * (epscf - epscp)
aa = .5d0** (1.d0 / 3.d0)
IF (x.lt..000001d0) x = .000001d0
IF (x.gt..999999d0) x = .999999d0
fx = (x**d43 + (1.d0 - x) **d43 - aa) / (1.d0 - aa)
exc = epsxp + epscp + fx * (cny + 4.d0 / 3.d0 * epsxp) / &
5.1297628d0
exc = exc / 2.d0
RETURN
END FUNCTION exc
FUNCTION excpw (n, s)
IMPLICIT NONE
DOUBLE PRECISION n, s, excpw
DOUBLE PRECISION exrsp, exrsf, rs, pi, exc0, exc1, alpha
DOUBLE PRECISION e0p, e0A, e0a1, e0b1, e0b2, e0b3, e0b4
DATA e0p, e0A, e0a1, e0b1, e0b2, e0b3, e0b4 / 1.d0, 0.031091d0, &
0.21370d0, 7.5957d0, 3.5876d0, 1.6382d0, 0.49294d0 /
DOUBLE PRECISION e1p, e1A, e1a1, e1b1, e1b2, e1b3, e1b4
DATA e1p, e1A, e1a1, e1b1, e1b2, e1b3, e1b4 / 1.d0, 0.015545d0, &
0.20548d0, 14.1189d0, 6.1977d0, 3.3662d0, 0.62517d0 /
DOUBLE PRECISION ap, aA, aa1, ab1, ab2, ab3, ab4
DATA ap, aA, aa1, ab1, ab2, ab3, ab4 / 1.d0, 0.016887d0, 0.11125d0,&
10.357d0, 3.6231d0, 0.88026d0, 0.49671d0 /
DOUBLE PRECISION fpp0
PARAMETER (fpp0 = 1.709921d0)
DOUBLE PRECISION f
f (s) = ( (1.d0 + s) ** (4.d0 / 3.d0) + (1.d0 - s) ** (4.d0 / &
3.d0) - 2.d0) / (2.d0** (4.d0 / 3.d0) - 2)
pi = 4.d0 * datan (1.d0)
rs = 1.d0 / ( (4.d0 * pi * n / 3.d0) ) ** (1.d0 / 3.d0)
exrsp = - 3.d0 / (4 * pi * rs) * (9.d0 * pi / 4.d0) ** (1.d0 / &
3.d0)
exrsf = - 0.5772521d0 / rs
exc0 = - 2.d0 * e0A * (1.d0 + e0a1 * rs) * dlog (1.d0 + 1.d0 / &
(2.d0 * e0A * (e0b1 * SQRT (rs) + e0b2 * rs + e0b3 * rs** (3.d0 / &
2.d0) + e0b4 * rs** (e0p + 1.d0) ) ) )
exc1 = - 2.d0 * e1A * (1.d0 + e1a1 * rs) * dlog (1.d0 + 1.d0 / &
(2.d0 * e1A * (e1b1 * SQRT (rs) + e1b2 * rs + e1b3 * rs** (3.d0 / &
2.d0) + e1b4 * rs** (e1p + 1.d0) ) ) )
alpha = 2.d0 * aA * (1.d0 + aa1 * rs) * dlog (1.d0 + 1.d0 / &
(2.d0 * aA * (ab1 * SQRT (rs) + ab2 * rs + ab3 * rs** (3.d0 / &
2.d0) + ab4 * rs** (ap + 1.d0) ) ) )
excpw = exc0 + alpha * (1.d0 - s**4) * f (s) / fpp0 + (exc1 - &
exc0) * f (s) * s**4
excpw = excpw + exrsp + f (s) * (exrsf - exrsp)
RETURN
END FUNCTION excpw
FUNCTION excgun (x)
IMPLICIT NONE
REAL(8) excgun, exctim, frs, x, pi
FRS (X) = (3.d0 / (4.d0 * PI * X) ) ** (1.d0 / 3.d0)
EXCtim (X) = ( - 0.458d0 / FRS (X) - 0.0333d0 * ( (1. + (FRS (X) &
/ 11.4d0) **3) * dLOG (1.d0 + 11.4d0 / FRS (X) ) + FRS (X) &
/ 22.8d0 - (FRS (X) / 11.4d0) **2 - 1.d0 / 3.d0) )
pi = 4.d0 * datan (1.d0)
excgun = exctim (x)
RETURN
END FUNCTION excgun
END MODULE ExchangeCorrelations