32 #include "../base/base_uses.f90"
40 REAL(KIND=
dp),
PARAMETER :: pi = 3.14159265358979323846264338_dp
41 REAL(KIND=
dp),
PARAMETER :: f13 = 1.0_dp/3.0_dp, &
45 f76 = 7.0_dp/6.0_dp, &
46 frs = 1.6119919540164696407_dp, &
47 fpe = 0.19199566167376364_dp
51 REAL(KIND=
dp) :: eps_rho
54 REAL(KIND=
dp),
PARAMETER :: a = 0.023266_dp, &
61 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xc_perdew86'
70 SUBROUTINE p86_init(cutoff, debug)
72 REAL(KIND=
dp),
INTENT(IN) :: cutoff
73 LOGICAL,
INTENT(IN),
OPTIONAL :: debug
78 IF (
PRESENT(debug))
THEN
84 END SUBROUTINE p86_init
94 CHARACTER(LEN=*),
INTENT(OUT),
OPTIONAL :: reference, shortform
95 TYPE(xc_rho_cflags_type),
INTENT(inout),
OPTIONAL :: needs
96 INTEGER,
INTENT(out),
OPTIONAL :: max_deriv
98 IF (
PRESENT(reference))
THEN
99 reference =
"J. P. Perdew, Phys. Rev. B, 33, 8822 (1986) {LDA version}"
101 IF (
PRESENT(shortform))
THEN
102 shortform =
"Perdew 1986 correlation energy functional {LDA}"
104 IF (
PRESENT(needs))
THEN
106 needs%norm_drho = .true.
108 IF (
PRESENT(max_deriv)) max_deriv = 3
121 TYPE(xc_rho_set_type),
INTENT(IN) :: rho_set
122 TYPE(xc_derivative_set_type),
INTENT(IN) :: deriv_set
123 INTEGER,
INTENT(IN) :: order
124 TYPE(section_vals_type),
POINTER :: p86_params
126 CHARACTER(len=*),
PARAMETER :: routinen =
'p86_lda_eval'
128 INTEGER :: handle, m, npoints
129 INTEGER,
DIMENSION(2, 3) :: bo
130 REAL(kind=
dp) :: drho_cutoff, rho_cutoff
131 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: rs
132 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :),
POINTER :: e_0, e_ndrho, e_ndrho_ndrho, &
133 e_ndrho_ndrho_ndrho, e_rho, e_rho_ndrho, e_rho_ndrho_ndrho, e_rho_rho, e_rho_rho_ndrho, &
134 e_rho_rho_rho, grho, rho
135 TYPE(xc_derivative_type),
POINTER :: deriv
137 CALL timeset(routinen, handle)
138 NULLIFY (rho, e_0, e_rho, e_ndrho, &
139 e_rho_rho, e_rho_ndrho, e_ndrho_ndrho, &
140 e_rho_rho_rho, e_rho_rho_ndrho, e_rho_ndrho_ndrho, e_ndrho_ndrho_ndrho)
146 norm_drho=grho, local_bounds=bo, rho_cutoff=rho_cutoff, &
147 drho_cutoff=drho_cutoff)
148 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
149 CALL p86_init(rho_cutoff)
152 ALLOCATE (rs(npoints))
157 allocate_deriv=.true.)
160 CALL p86_u_0(rho, rs, grho, e_0, npoints)
162 IF (order >= 1 .OR. order == -1)
THEN
164 allocate_deriv=.true.)
167 allocate_deriv=.true.)
170 CALL p86_u_1(rho, grho, rs, e_rho, &
173 IF (order >= 2 .OR. order == -2)
THEN
175 allocate_deriv=.true.)
178 allocate_deriv=.true.)
184 CALL p86_u_2(rho, grho, rs, e_rho_rho, &
185 e_rho_ndrho, e_ndrho_ndrho, npoints)
187 IF (order >= 3 .OR. order == -3)
THEN
189 allocate_deriv=.true.)
201 CALL p86_u_3(rho, grho, rs, e_rho_rho_rho, &
202 e_rho_rho_ndrho, e_rho_ndrho_ndrho, e_ndrho_ndrho_ndrho, &
205 IF (order > 3 .OR. order < -3)
THEN
206 cpabort(
"derivatives bigger than 3 not implemented")
209 CALL timestop(handle)
221 SUBROUTINE p86_u_0(rho, rs, grho, e_0, npoints)
223 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, rs, grho
224 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_0
225 INTEGER,
INTENT(in) :: npoints
228 REAL(kind=
dp) :: cr, ep, g, or, phi, r, x
234 IF (rho(ip) > eps_rho)
THEN
239 cr = pc1 + (pc2 + a*r + b*r*r)/(1.0_dp + c*r + d*r*r + 1.e4_dp*b*r*r*r)
240 phi = fpe*pci/cr*g*sqrt(x)*or
242 e_0(ip) = e_0(ip) + x*or*g*g*cr*ep
247 END SUBROUTINE p86_u_0
258 SUBROUTINE p86_u_1(rho, grho, rs, e_rho, e_ndrho, npoints)
260 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, grho, rs
261 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho, e_ndrho
262 INTEGER,
INTENT(in) :: npoints
265 REAL(kind=
dp) :: cr, dcr, dphig, dphir, dpv, dq, ep, ff, &
266 g, or, p, phi, q, r, x
272 IF (rho(ip) > eps_rho)
THEN
277 p = pc2 + a*r + b*r*r
279 q = 1.0_dp + c*r + d*r*r + 1.e4_dp*b*r*r*r
280 dq = c + 2.0_dp*d*r + 3.e4_dp*b*r*r
282 dcr = (dpv*q - p*dq)/(q*q)*(-f13*r*or)
283 dphig = fpe*pci/cr*sqrt(x)*or
285 dphir = -phi*(dcr/cr + f76*or)
288 e_rho(ip) = e_rho(ip) + ff*g*dcr - ff*g*cr*dphir - ff*g*cr*f43*or
289 e_ndrho(ip) = e_ndrho(ip) + ff*cr*(2.0_dp - g*dphig)
294 END SUBROUTINE p86_u_1
306 SUBROUTINE p86_u_2(rho, grho, rs, e_rho_rho, e_rho_ndrho, e_ndrho_ndrho, &
309 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, grho, rs
310 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho_rho, e_rho_ndrho, e_ndrho_ndrho
311 INTEGER,
INTENT(in) :: npoints
314 REAL(kind=
dp) :: cr, d2cr, d2p, d2phir, d2q, dcr, dphig, &
315 dphigr, dphir, dpv, dq, ep, g, or, p, &
323 IF (rho(ip) > eps_rho)
THEN
328 p = pc2 + a*r + b*r*r
331 q = 1.0_dp + c*r + d*r*r + 1.e4_dp*b*r*r*r
332 dq = c + 2.0_dp*d*r + 3.e4_dp*b*r*r
333 d2q = 2.0_dp*d + 6.e4_dp*b*r
335 dcr = (dpv*q - p*dq)/(q*q)*(-f13*r*or)
336 d2cr = (d2p*q*q - p*q*d2q - 2*dpv*dq*q + 2*p*dq*dq)/(q*q*q)*(f13*r*or)**2 + &
337 (dpv*q - p*dq)/(q*q)*f13*f43*r*or*or
338 dphig = fpe*pci/cr*sqrt(x)*or
340 dphir = -phi*(dcr/cr + f76*or)
341 d2phir = -dphir*(dcr/cr + f76*or) - &
342 phi*((d2cr*cr - dcr*dcr)/(cr*cr) - f76*or*or)
343 dphigr = -dphig*(dcr/cr + f76*or)
345 e_rho_rho(ip) = e_rho_rho(ip) + x*or*ep*g*g* &
346 (-f43*or*dcr + d2cr - dcr*dphir + &
347 f43*or*cr*dphir - dcr*dphir - cr*d2phir + cr*dphir*dphir + &
348 f43*or*(7.*f13*or*cr - dcr + cr*dphir))
349 e_rho_ndrho(ip) = e_rho_ndrho(ip) + x*or*ep*g* &
350 (-2*f43*cr*or + 2*dcr - 2*cr*dphir + f43*or*g*cr*dphig - &
351 g*dcr*dphig + g*cr*dphir*dphig - g*cr*dphigr)
352 e_ndrho_ndrho(ip) = e_ndrho_ndrho(ip) + x*or*ep*cr* &
353 (2.0_dp - 4.0_dp*g*dphig + g*g*dphig*dphig)
358 END SUBROUTINE p86_u_2
371 SUBROUTINE p86_u_3(rho, grho, rs, e_rho_rho_rho, &
372 e_rho_rho_ndrho, e_rho_ndrho_ndrho, e_ndrho_ndrho_ndrho, &
375 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, grho, rs
376 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho_rho_rho, e_rho_rho_ndrho, &
377 e_rho_ndrho_ndrho, e_ndrho_ndrho_ndrho
378 INTEGER,
INTENT(in) :: npoints
381 REAL(kind=
dp) :: cr, d2cr, d2p, d2phir, d2phirg, d2pq, d2q, d2z, d3cr, d3phir, d3pq, d3q, &
382 d3z, dcr, dphig, dphigr, dphir, dpq, dpv, dq, dz, ep, g, or, oz, p, phi, pq, q, r, x
390 IF (rho(ip) > eps_rho)
THEN
395 p = pc2 + a*r + b*r*r
398 q = 1.0_dp + c*r + d*r*r + 1.e4_dp*b*r*r*r
399 dq = c + 2.0_dp*d*r + 3.e4_dp*b*r*r
400 d2q = 2.0_dp*d + 6.e4*b*r
403 dpq = (dpv*q - p*dq)/(q*q)
404 d2pq = (d2p*q*q - 2*dpv*dq*q + 2*p*dq*dq - p*d2q*q)/(q*q*q)
405 d3pq = -(3*d2p*dq*q*q - 6*dpv*dq*dq*q + 3*dpv*d2q*q*q + 6*p*dq*dq*dq - 6*p*dq*d2q*q &
406 + p*d3q*q*q)/(q*q*q*q)
408 dcr = dpq*(-f13*r*or)
409 d2cr = d2pq*f13*f13*r*r*or*or + dpq*f13*f43*r*or*or
410 d3cr = d3pq*(-f13*r*or)**3 + 3*d2pq*(-f13*f13*f43*r*r*or*or*or) + &
411 dpq*(-f13*f43*f13*7*r*or*or*or)
414 d2z = d2cr/cr + 2*f76*dcr/cr*or + f76/6.*or*or
415 d3z = d3cr/cr + 3*f76*d2cr/cr*or + 3*f76/6.*dcr/cr*or*or - 5*f76/36.*or*or*or
420 d2phir = -phi*(d2z - 2*dz*dz)
421 d3phir = -phi*(d3z - 6*d2z*dz + 6*dz*dz*dz)
422 d2phirg = -dphigr*dz - &
423 dphig*((d2cr*cr - dcr*dcr)/(cr*cr) - f76*or*or)
425 e_rho_rho_rho(ip) = e_rho_rho_rho(ip) &
426 + g*g*x*or*ep*(-280./27.*or*or*or*cr + 3*28./9.*or*or*dcr + &
427 3*28./9.*or*or*cr*(-dphir) - 4*or*d2cr - 8*or*dcr*(-dphir) - &
428 4*or*cr*(-d2phir + dphir*dphir) + d3cr + 3*d2cr*(-dphir) + &
429 3*dcr*(-d2phir + dphir*dphir) + cr*(-d3phir + 3*dphir*d2phir - &
431 e_rho_rho_ndrho(ip) = e_rho_rho_ndrho(ip) &
432 + 2.*x*or*ep*g*(-f43*or*dcr + d2cr - dcr*dphir + &
433 f43*or*cr*dphir - dcr*dphir - cr*d2phir + cr*dphir*dphir + &
434 f43*or*(7.*f13*or*cr - dcr + cr*dphir)) - &
435 dphig*x*or*ep*g*g*(-f43*or*dcr + d2cr - dcr*dphir + &
436 f43*or*cr*dphir - dcr*dphir - cr*d2phir + cr*dphir*dphir + &
437 f43*or*(7.*f13*or*cr - dcr + cr*dphir)) + &
438 x*or*ep*g*g*(-dcr*dphigr + f43*or*cr*dphigr - dcr*dphigr - cr*d2phirg + &
439 2.*cr*dphigr*dphir + f43*or*cr*dphigr)
440 e_rho_ndrho_ndrho(ip) = e_rho_ndrho_ndrho(ip) &
441 + x*or*ep*(-2*f43*cr*or + 2*dcr - 2*cr*dphir + f43*or*g*cr*dphig - &
442 g*dcr*dphig + g*cr*dphir*dphig - g*cr*dphigr) + &
443 x*or*ep*g*(-2*cr*dphigr + f43*or*cr*dphig - &
444 dcr*dphig + cr*dphir*dphig + g*cr*dphigr*dphig - cr*dphigr) - &
445 x*or*ep*g*dphig*(-2*f43*cr*or + 2*dcr - 2*cr*dphir + f43*or*g*cr*dphig - &
446 g*dcr*dphig + g*cr*dphir*dphig - g*cr*dphigr)
447 e_ndrho_ndrho_ndrho(ip) = e_ndrho_ndrho_ndrho(ip) &
448 + x*or*ep*cr*dphig*(-6.0_dp + 6.0_dp*g*dphig - g*g*dphig*dphig)
453 END SUBROUTINE p86_u_3
Defines the basic variable types.
integer, parameter, public dp
Module with functions to handle derivative descriptors. derivative description are strings have the f...
integer, parameter, public deriv_norm_drho
integer, parameter, public deriv_rho
represent a group ofunctional derivatives
type(xc_derivative_type) function, pointer, public xc_dset_get_derivative(derivative_set, description, allocate_deriv)
returns the requested xc_derivative
Provides types for the management of the xc-functionals and their derivatives.
subroutine, public xc_derivative_get(deriv, split_desc, order, deriv_data, accept_null_data)
returns various information on the given derivative
Utility routines for the functional calculations.
subroutine, public calc_rs_pw(rho, rs, n)
...
subroutine, public set_util(cutoff)
...
Calculate the Perdew Correlation from 1986.
subroutine, public p86_lda_info(reference, shortform, needs, max_deriv)
...
subroutine, public p86_lda_eval(rho_set, deriv_set, order, p86_params)
...
Calculate the Perdew-Zunger correlation potential and energy density and ist derivatives with respect...
subroutine, public pz_lda_eval(method, rho_set, deriv_set, order, pz_params)
Calculate the correlation energy and its derivatives wrt to rho (the electron density) up to 3rd orde...
subroutine, public xc_rho_set_get(rho_set, can_return_null, rho, drho, norm_drho, rhoa, rhob, norm_drhoa, norm_drhob, rho_1_3, rhoa_1_3, rhob_1_3, laplace_rho, laplace_rhoa, laplace_rhob, drhoa, drhob, rho_cutoff, drho_cutoff, tau_cutoff, tau, tau_a, tau_b, local_bounds)
returns the various attributes of rho_set