19 #include "../base/base_uses.f90"
25 REAL(KIND=
dp),
PARAMETER :: rsfac = 0.6203504908994000166680065_dp
26 REAL(KIND=
dp),
PARAMETER :: f13 = 1.0_dp/3.0_dp, &
30 REAL(KIND=
dp),
PARAMETER :: fxfac = 1.923661050931536319759455_dp
32 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xc_functionals_utilities'
34 PUBLIC ::
set_util, calc_rs, calc_fx, &
38 MODULE PROCEDURE calc_fx_array, calc_fx_single
42 MODULE PROCEDURE calc_rs_array, calc_rs_single
45 REAL(KIND=
dp),
SAVE :: eps_rho
55 REAL(kind=
dp) :: cutoff
66 ELEMENTAL SUBROUTINE calc_rs_single(rho, rs)
70 REAL(kind=
dp),
INTENT(IN) :: rho
71 REAL(kind=
dp),
INTENT(OUT) :: rs
73 IF (rho < eps_rho)
THEN
76 rs = rsfac*rho**(-f13)
79 END SUBROUTINE calc_rs_single
86 SUBROUTINE calc_rs_array(rho, rs)
90 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: rho
91 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: rs
95 IF (
SIZE(rs) <
SIZE(rho))
THEN
96 cpabort(
"Size of array rs too small.")
101 IF (rho(k) < eps_rho)
THEN
104 rs(k) = rsfac*rho(k)**(-f13)
108 END SUBROUTINE calc_rs_array
120 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho
121 REAL(kind=
dp),
DIMENSION(*),
INTENT(OUT) :: rs
122 INTEGER,
INTENT(IN) :: n
128 IF (rho(k) < eps_rho)
THEN
131 rs(k) = rsfac*rho(k)**(-f13)
148 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho
149 REAL(kind=
dp),
DIMENSION(*),
INTENT(OUT) :: x
150 INTEGER,
INTENT(in) :: n
174 CHARACTER(len=*),
INTENT(IN) :: tag
175 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, grho
176 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: s
184 fac = 1.0_dp/(2.0_dp*(3.0_dp*
pi*
pi)**f13)
185 IF (tag(1:1) ==
"u" .OR. tag(1:1) ==
"U")
fac =
fac*(2.0_dp)**f13
186 IF (tag(1:1) ==
"r" .OR. tag(1:1) ==
"R")
fac =
fac*(2.0_dp)**f13
196 IF (rho(ip) < eps_rho)
THEN
199 s(ip) =
fac*grho(ip)*rho(ip)**(-f43)
213 SUBROUTINE calc_fx_array(n, rhoa, rhob, fx, m)
223 INTEGER,
INTENT(IN) :: n
224 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, rhob
225 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: fx
226 INTEGER,
INTENT(IN) :: m
229 REAL(kind=
dp) :: rhoab, x
235 IF (m > 3) cpabort(
"Order too high.")
240 IF (
SIZE(fx, 1) < n) cpabort(
"SIZE(fx,1) too small")
241 IF (
SIZE(fx, 2) < m) cpabort(
"SIZE(fx,2) too small")
246 rhoab = rhoa(ip) + rhob(ip)
247 IF (rhoab < eps_rho)
THEN
250 x = (rhoa(ip) - rhob(ip))/rhoab
251 IF (x < -1.0_dp)
THEN
252 IF (m >= 0) fx(ip, 1) = 1.0_dp
253 IF (m >= 1) fx(ip, 2) = -f43*fxfac*2.0_dp**f13
254 IF (m >= 2) fx(ip, 3) = f13*f43*fxfac/2.0_dp**f23
255 IF (m >= 3) fx(ip, 4) = f23*f13*f43*fxfac/2.0_dp**f53
256 ELSE IF (x > 1.0_dp)
THEN
257 IF (m >= 0) fx(ip, 1) = 1.0_dp
258 IF (m >= 1) fx(ip, 2) = f43*fxfac*2.0_dp**f13
259 IF (m >= 2) fx(ip, 3) = f13*f43*fxfac/2.0_dp**f23
260 IF (m >= 3) fx(ip, 4) = -f23*f13*f43*fxfac/2.0_dp**f53
263 fx(ip, 1) = ((1.0_dp + x)**f43 + (1.0_dp - x)**f43 - 2.0_dp)*fxfac
265 fx(ip, 2) = ((1.0_dp + x)**f13 - (1.0_dp - x)**f13)*fxfac*f43
267 fx(ip, 3) = ((1.0_dp + x)**(-f23) + (1.0_dp - x)**(-f23))* &
270 fx(ip, 4) = ((1.0_dp + x)**(-f53) - (1.0_dp - x)**(-f53))* &
276 END SUBROUTINE calc_fx_array
285 PURE SUBROUTINE calc_fx_single(rhoa, rhob, fx, m)
295 REAL(kind=
dp),
INTENT(IN) :: rhoa, rhob
296 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: fx
297 INTEGER,
INTENT(IN) :: m
299 REAL(kind=
dp) :: rhoab, x
302 IF (rhoab < eps_rho)
THEN
305 x = (rhoa - rhob)/rhoab
306 IF (x < -1.0_dp)
THEN
307 IF (m >= 0) fx(1) = 1.0_dp
308 IF (m >= 1) fx(2) = -f43*fxfac*2.0_dp**f13
309 IF (m >= 2) fx(3) = f13*f43*fxfac/2.0_dp**f23
310 IF (m >= 3) fx(4) = f23*f13*f43*fxfac/2.0_dp**f53
311 ELSE IF (x > 1.0_dp)
THEN
312 IF (m >= 0) fx(1) = 1.0_dp
313 IF (m >= 1) fx(2) = f43*fxfac*2.0_dp**f13
314 IF (m >= 2) fx(3) = f13*f43*fxfac/2.0_dp**f23
315 IF (m >= 3) fx(4) = -f23*f13*f43*fxfac/2.0_dp**f53
318 fx(1) = ((1.0_dp + x)**f43 + (1.0_dp - x)**f43 - 2.0_dp)*fxfac
320 fx(2) = ((1.0_dp + x)**f13 - (1.0_dp - x)**f13)*fxfac*f43
322 fx(3) = ((1.0_dp + x)**(-f23) + (1.0_dp - x)**(-f23))* &
325 fx(4) = ((1.0_dp + x)**(-f53) - (1.0_dp - x)**(-f53))* &
330 END SUBROUTINE calc_fx_single
341 REAL(kind=
dp),
INTENT(IN) :: a, b
342 REAL(kind=
dp),
DIMENSION(0:, 0:),
INTENT(OUT) :: z
343 INTEGER,
INTENT(IN) :: order
345 REAL(kind=
dp) :: c, d
353 z(0, 1) = -2.0_dp*a/d
357 z(2, 0) = -4.0_dp*b/d
358 z(1, 1) = 2.0_dp*(a - b)/d
363 z(3, 0) = 12.0_dp*b/d
364 z(2, 1) = -4.0_dp*(a - 2.0_dp*b)/d
365 z(1, 2) = -4.0_dp*(2.0_dp*a - b)/d
366 z(0, 3) = -12.0_dp*a/d
static GRID_HOST_DEVICE double fac(const int i)
Factorial function, e.g. fac(5) = 5! = 120.
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
Utility routines for the functional calculations.
subroutine, public calc_rs_pw(rho, rs, n)
...
subroutine, public calc_wave_vector(tag, rho, grho, s)
...
subroutine, public set_util(cutoff)
...
pure subroutine, public calc_z(a, b, z, order)
...
subroutine, public calc_srs_pw(rho, x, n)
...