41#include "../base/base_uses.f90"
46 LOGICAL :: initialized = .false.
47 REAL(KIND=
dp),
DIMENSION(0:1) :: a = 0.0_dp, b = 0.0_dp, c = 0.0_dp, d = 0.0_dp, &
48 b1 = 0.0_dp, b2 = 0.0_dp, ga = 0.0_dp
50 REAL(KIND=
dp),
PARAMETER :: epsilon = 5.e-13_dp
51 REAL(KIND=
dp) :: eps_rho
54 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xc_perdew_zunger'
69 SUBROUTINE pz_info(method, lsd, reference, shortform, needs, max_deriv)
70 INTEGER,
INTENT(in) :: method
71 LOGICAL,
INTENT(in) :: lsd
72 CHARACTER(LEN=*),
INTENT(OUT),
OPTIONAL :: reference, shortform
74 INTEGER,
INTENT(out),
OPTIONAL :: max_deriv
76 CHARACTER(len=4) :: p_string
80 cpabort(
"Unsupported parametrization")
89 IF (
PRESENT(reference))
THEN
90 reference =
"J. P. Perdew and Alex Zunger," &
91 //
" Phys. Rev. B 23, 5048 (1981)" &
92 //
"["//trim(p_string)//
"]"
94 IF (len_trim(reference) + 6 < len(reference))
THEN
95 reference(len_trim(reference):len_trim(reference) + 6) =
' {LDA}'
99 IF (
PRESENT(shortform))
THEN
100 shortform =
"J. P. Perdew et al., PRB 23, 5048 (1981)" &
101 //
"["//trim(p_string)//
"]"
103 IF (len_trim(shortform) + 6 < len(shortform))
THEN
104 shortform(len_trim(shortform):len_trim(shortform) + 6) =
' {LDA}'
108 IF (
PRESENT(needs))
THEN
110 needs%rho_spin = .true.
115 IF (
PRESENT(max_deriv)) max_deriv = 3
134 SUBROUTINE pz_lda_eval(method, rho_set, deriv_set, order, pz_params)
136 INTEGER,
INTENT(in) :: method
139 INTEGER,
INTENT(in) :: order
142 CHARACTER(len=*),
PARAMETER :: routinen =
'pz_lda_eval'
144 INTEGER :: npoints, timer_handle
145 INTEGER,
DIMENSION(2, 3) :: bo
146 REAL(kind=
dp) :: rho_cutoff, sc
147 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :), &
148 POINTER :: dummy, e_0, e_rho, e_rho_rho, &
152 CALL timeset(routinen, timer_handle)
153 NULLIFY (rho, e_0, e_rho, e_rho_rho, e_rho_rho_rho, dummy)
158 local_bounds=bo, rho_cutoff=rho_cutoff)
159 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
161 CALL pz_init(method, rho_cutoff)
168 e_rho_rho_rho => dummy
171 allocate_deriv=.true.)
175 allocate_deriv=.true.)
180 allocate_deriv=.true.)
185 allocate_deriv=.true.)
189 cpabort(
"derivatives bigger than 3 not implemented")
192 CALL pz_lda_calc(rho, e_0, e_rho, e_rho_rho, e_rho_rho_rho, npoints, order, sc)
194 CALL timestop(timer_handle)
209 SUBROUTINE pz_lda_calc(rho, e_0, e_rho, e_rho_rho, e_rho_rho_rho, npoints, order, sc)
211 REAL(kind=
dp),
DIMENSION(*),
INTENT(in) :: rho
212 REAL(kind=
dp),
DIMENSION(*),
INTENT(inout) :: e_0, e_rho, e_rho_rho, e_rho_rho_rho
213 INTEGER,
INTENT(in) :: npoints, order
217 REAL(kind=
dp),
DIMENSION(0:3) :: ed
223 IF (rho(k) > eps_rho)
THEN
225 CALL pz_lda_ed_loc(rho(k), ed, abs(order), sc)
227 e_0(k) = e_0(k) + rho(k)*ed(0)
229 e_rho(k) = e_rho(k) + ed(0) + rho(k)*ed(1)
232 e_rho_rho(k) = e_rho_rho(k) + 2.0_dp*ed(1) + rho(k)*ed(2)
235 e_rho_rho_rho(k) = e_rho_rho_rho(k) + 3.0_dp*ed(2) + rho(k)*ed(3)
243 END SUBROUTINE pz_lda_calc
260 SUBROUTINE pz_lsd_eval(method, rho_set, deriv_set, order, pz_params)
261 INTEGER,
INTENT(in) :: method
264 INTEGER,
INTENT(IN),
OPTIONAL :: order
267 CHARACTER(len=*),
PARAMETER :: routinen =
'pz_lsd_eval'
269 INTEGER :: npoints, timer_handle
270 INTEGER,
DIMENSION(2, 3) :: bo
271 REAL(kind=
dp) :: rho_cutoff, sc
272 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :), &
273 POINTER :: a, b, dummy, e_0, ea, eaa, eaaa, eaab, &
277 CALL timeset(routinen, timer_handle)
278 NULLIFY (a, b, e_0, ea, eaa, eab, ebb, eaaa, eaab, eabb, ebbb)
283 local_bounds=bo, rho_cutoff=rho_cutoff)
284 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
286 CALL pz_init(method, rho_cutoff)
292 eaa => dummy; eab => dummy; ebb => dummy
293 eaaa => dummy; eaab => dummy; eabb => dummy; ebbb => dummy
296 allocate_deriv=.true.)
300 allocate_deriv=.true.)
305 allocate_deriv=.true.)
308 allocate_deriv=.true.)
311 allocate_deriv=.true.)
316 allocate_deriv=.true.)
319 allocate_deriv=.true.)
322 allocate_deriv=.true.)
325 allocate_deriv=.true.)
329 cpabort(
"derivatives bigger than 3 not implemented")
332 CALL pz_lsd_calc(a, b, e_0, ea, eaa, eab, ebb, eaaa, eaab, eabb, &
333 ebbb, npoints, order, sc)
335 CALL timestop(timer_handle)
356 SUBROUTINE pz_lsd_calc(a, b, e_0, ea, eaa, eab, ebb, eaaa, eaab, eabb, &
357 ebbb, npoints, order, sc)
359 REAL(kind=
dp),
DIMENSION(*),
INTENT(in) :: a, b
360 REAL(kind=
dp),
DIMENSION(*),
INTENT(inout) :: e_0, ea, eaa, eab, ebb, eaaa, eaab, &
362 INTEGER,
INTENT(in) :: npoints, order
363 REAL(kind=
dp),
INTENT(IN) :: sc
367 REAL(kind=
dp),
DIMENSION(0:9) :: ed
377 IF (rho > eps_rho)
THEN
379 CALL pz_lsd_ed_loc(a(k), b(k), ed, order_, sc)
381 e_0(k) = e_0(k) + rho*ed(0)
384 ea(k) = ea(k) + ed(0) + rho*ed(1)
385 ea(k) = ea(k) + ed(0) + rho*ed(2)
389 eaa(k) = eaa(k) + 2.0_dp*ed(1) + rho*ed(3)
390 eab(k) = eab(k) + ed(1) + ed(2) + rho*ed(4)
391 ebb(k) = ebb(k) + 2.0_dp*ed(2) + rho*ed(5)
395 eaaa(k) = eaaa(k) + 3.0_dp*ed(3) + rho*ed(6)
396 eaab(k) = eaab(k) + 2.0_dp*ed(4) + ed(3) + rho*ed(7)
397 eabb(k) = eabb(k) + 2.0_dp*ed(4) + ed(5) + rho*ed(8)
398 ebbb(k) = ebbb(k) + 3.0_dp*ed(5) + rho*ed(9)
406 END SUBROUTINE pz_lsd_calc
416 SUBROUTINE pz_init(method, cutoff)
418 INTEGER,
INTENT(IN) :: method
419 REAL(kind=
dp),
INTENT(IN) :: cutoff
425 initialized = .false.
430 cpabort(
"Unknown method")
434 ga(0) = -0.1423_dp; ga(1) = -0.0843_dp
435 b1(0) = 1.0529_dp; b1(1) = 1.3981_dp
436 b2(0) = 0.3334_dp; b2(1) = 0.2611_dp
437 a(0) = 0.0311_dp; a(1) = 0.01555_dp
438 b(0) = -0.048_dp; b(1) = -0.0269_dp
439 c(0) = +0.0020_dp; c(1) = +0.0007_dp
440 d(0) = -0.0116_dp; d(1) = -0.0048_dp
444 ga(0) = -0.103756_dp; ga(1) = -0.065951_dp
445 b1(0) = 0.56371_dp; b1(1) = 1.11846_dp
446 b2(0) = 0.27358_dp; b2(1) = 0.18797_dp
447 a(0) = 0.031091_dp; a(1) = 0.015545_dp
448 b(0) = -0.046644_dp; b(1) = -0.025599_dp
449 c(0) = -0.00419_dp; c(1) = -0.00329_dp
450 d(0) = -0.00983_dp; d(1) = -0.00300_dp
454 ga(0) = -0.093662_dp; ga(1) = -0.055331_dp
455 b1(0) = 0.49453_dp; b1(1) = 0.93766_dp
456 b2(0) = 0.25534_dp; b2(1) = 0.14829_dp
457 a(0) = 0.031091_dp; a(1) = 0.015545_dp
458 b(0) = -0.046644_dp; b(1) = -0.025599_dp
459 c(0) = -0.00884_dp; c(1) = -0.00677_dp
460 d(0) = -0.00688_dp; d(1) = -0.00093_dp
466 END SUBROUTINE pz_init
475 SUBROUTINE calc_g(r, z, g, order)
477 REAL(kind=
dp),
INTENT(IN) :: r
478 INTEGER,
INTENT(IN) :: z
479 REAL(kind=
dp),
DIMENSION(0:),
INTENT(OUT) :: g
480 INTEGER,
INTENT(IN) :: order
482 REAL(kind=
dp) :: rr, rsr, sr
484 IF (r >= 1.0_dp)
THEN
488 g(0) = ga(z)/(1.0_dp + b1(z)*sr + b2(z)*r)
490 g(1) = -ga(z)*(b1(z)/(2.0_dp*sr) + b2(z))/ &
491 (1.0_dp + b1(z)*sr + b2(z)*r)**2
496 2.0_dp*ga(z)*(b1(z)/(2.0_dp*sr) + b2(z))**2 &
497 /(1.0_dp + b1(z)*sr + b2(z)*r)**3 &
499 /(4.0_dp*(1.0_dp + b1(z)*sr + b2(z)*r)**2*rsr)
503 -6.0_dp*ga(z)*(b1(z)/(2.0_dp*sr) + b2(z))**3/ &
504 (1.0_dp + b1(z)*sr + b2(z)*r)**4 &
505 - (3.0_dp/2.0_dp)*ga(z)*(b1(z)/(2.0_dp*sr) + b2(z))*b1(z)/ &
506 ((1.0_dp + b1(z)*sr + b2(z)*r)**3*rsr) &
507 - (3.0_dp/8.0_dp)*ga(z)*b1(z)/ &
508 ((1.0_dp + b1(z)*sr + b2(z)*r)**2*r*rsr)
514 g(0) = a(z)*log(r) + b(z) + c(z)*r*log(r) + d(z)*r
516 g(1) = a(z)/r + c(z)*log(r) + c(z) + d(z)
520 g(2) = -a(z)/rr + c(z)/r
523 g(3) = 2.0_dp*a(z)/(rr*r) - c(z)/rr
528 END SUBROUTINE calc_g
537 SUBROUTINE pz_lda_ed_loc(rho, ed, order, sc)
539 REAL(kind=
dp),
INTENT(IN) :: rho
540 REAL(kind=
dp),
DIMENSION(0:),
INTENT(OUT) :: ed
541 INTEGER,
INTENT(IN) :: order
542 REAL(
dp),
INTENT(IN) :: sc
545 LOGICAL,
DIMENSION(0:3) :: calc
546 REAL(kind=
dp),
DIMENSION(0:3) :: e0, r
551 IF (order_ >= 0)
THEN
552 calc(0:order_) = .true.
555 calc(order_) = .true.
559 CALL calc_g(r(0), 0, e0, order_)
561 IF (order_ >= 1) r(1) = (-1.0_dp/3.0_dp)*r(0)/rho
562 IF (order_ >= 2) r(2) = (-4.0_dp/3.0_dp)*r(1)/rho
563 IF (order_ >= 3) r(3) = (-7.0_dp/3.0_dp)*r(2)/rho
571 ed(m) = sc*e0(1)*r(1)
575 ed(m) = sc*e0(2)*r(1)**2 + sc*e0(1)*r(2)
579 ed(m) = sc*e0(3)*r(1)**3 + sc*e0(2)*3.0_dp*r(1)*r(2) + sc*e0(1)*r(3)
582 END SUBROUTINE pz_lda_ed_loc
592 SUBROUTINE pz_lsd_ed_loc(a, b, ed, order, sc)
594 REAL(kind=
dp),
INTENT(IN) :: a, b
595 REAL(kind=
dp),
DIMENSION(0:),
INTENT(OUT) :: ed
596 INTEGER,
INTENT(IN),
OPTIONAL :: order
597 REAL(kind=
dp),
INTENT(IN) :: sc
600 LOGICAL,
DIMENSION(0:3) :: calc
601 REAL(kind=
dp) :: rho, tr, trr, trrr, trrz, trz, trzz, tz, &
603 REAL(kind=
dp),
DIMENSION(0:3) :: e0, e1, f, r
604 REAL(kind=
dp),
DIMENSION(0:3, 0:3) :: z
609 IF (
PRESENT(order)) order_ = order
611 IF (order_ >= 0)
THEN
612 calc(0:order_) = .true.
615 calc(order_) = .true.
620 CALL calc_fx(a, b, f(0:order_), order_)
622 CALL calc_g(r(0), 0, e0(0:order_), order_)
623 CALL calc_g(r(0), 1, e1(0:order_), order_)
624 CALL calc_z(a, b, z(:, :), order_)
627 IF (order_ >= 1)
THEN
628 r(1) = (-1.0_dp/3.0_dp)*r(0)/rho
629 tr = e0(1) + (e1(1) - e0(1))*f(0)
630 tz = (e1(0) - e0(0))*f(1)
634 IF (order_ >= 2)
THEN
635 r(2) = (-4.0_dp/3.0_dp)*r(1)/rho
636 trr = e0(2) + (e1(2) - e0(2))*f(0)
637 trz = (e1(1) - e0(1))*f(1)
638 tzz = (e1(0) - e0(0))*f(2)
642 IF (order_ >= 3)
THEN
643 r(3) = (-7.0_dp/3.0_dp)*r(2)/rho
644 trrr = e0(3) + (e1(3) - e0(3))*f(0)
645 trrz = (e1(2) - e0(2))*f(1)
646 trzz = (e1(1) - e0(1))*f(2)
647 tzzz = (e1(0) - e0(0))*f(3)
652 ed(m) = e0(0) + (e1(0) - e0(0))*f(0)
658 ed(m) = tr*r(1) + tz*z(1, 0)
660 ed(m + 1) = tr*r(1) + tz*z(0, 1)
661 ed(m + 1) = ed(m + 1)*sc
666 ed(m) = trr*r(1)**2 + 2.0_dp*trz*r(1)*z(1, 0) &
667 + tr*r(2) + tzz*z(1, 0)**2 + tz*z(2, 0)
669 ed(m + 1) = trr*r(1)**2 + trz*r(1)*(z(0, 1) + z(1, 0)) &
670 + tr*r(2) + tzz*z(1, 0)*z(0, 1) + tz*z(1, 1)
671 ed(m + 1) = ed(m + 1)*sc
672 ed(m + 2) = trr*r(1)**2 + 2.0_dp*trz*r(1)*z(0, 1) &
673 + tr*r(2) + tzz*z(0, 1)**2 + tz*z(0, 2)
674 ed(m + 2) = ed(m + 2)*sc
679 ed(m) = trrr*r(1)**3 + 3.0_dp*trrz*r(1)**2*z(1, 0) &
680 + 3.0_dp*trr*r(1)*r(2) + 3.0_dp*trz*r(2)*z(1, 0) &
681 + tr*r(3) + 3.0_dp*trzz*r(1)*z(1, 0)**2 &
682 + tzzz*z(1, 0)**3 + 3.0_dp*trz*r(1)*z(2, 0) &
683 + 3.0_dp*tzz*z(1, 0)*z(2, 0) + tz*z(3, 0)
685 ed(m + 1) = trrr*r(1)**3 + trrz*r(1)**2*(2.0_dp*z(1, 0) + z(0, 1)) &
686 + 2.0_dp*trzz*r(1)*z(1, 0)*z(0, 1) &
687 + 2.0_dp*trz*(r(2)*z(1, 0) + r(1)*z(1, 1)) &
688 + 3.0_dp*trr*r(2)*r(1) + trz*r(2)*z(0, 1) + tr*r(3) &
689 + trzz*r(1)*z(1, 0)**2 + tzzz*z(1, 0)**2*z(0, 1) &
690 + 2.0_dp*tzz*z(1, 0)*z(1, 1) &
691 + trz*r(1)*z(2, 0) + tzz*z(2, 0)*z(0, 1) + tz*z(2, 1)
692 ed(m + 1) = ed(m + 1)*sc
693 ed(m + 2) = trrr*r(1)**3 + trrz*r(1)**2*(2.0_dp*z(0, 1) + z(1, 0)) &
694 + 2.0_dp*trzz*r(1)*z(0, 1)*z(1, 0) &
695 + 2.0_dp*trz*(r(2)*z(0, 1) + r(1)*z(1, 1)) &
696 + 3.0_dp*trr*r(2)*r(1) + trz*r(2)*z(1, 0) + tr*r(3) &
697 + trzz*r(1)*z(0, 1)**2 + tzzz*z(0, 1)**2*z(1, 0) &
698 + 2.0_dp*tzz*z(0, 1)*z(1, 1) &
699 + trz*r(1)*z(0, 2) + tzz*z(0, 2)*z(1, 0) + tz*z(1, 2)
700 ed(m + 2) = ed(m + 2)*sc
701 ed(m + 3) = trrr*r(1)**3 + 3.0_dp*trrz*r(1)**2*z(0, 1) &
702 + 3.0_dp*trr*r(1)*r(2) + 3.0_dp*trz*r(2)*z(0, 1) + tr*r(3) &
703 + 3.0_dp*trzz*r(1)*z(0, 1)**2 + tzzz*z(0, 1)**3 &
704 + 3.0_dp*trz*r(1)*z(0, 2) &
705 + 3.0_dp*tzz*z(0, 1)*z(0, 2) + tz*z(0, 3)
706 ed(m + 3) = ed(m + 3)*sc
709 END SUBROUTINE pz_lsd_ed_loc
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public perdew1981
integer, save, public ortiz1994
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_rhob
integer, parameter, public deriv_rhoa
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 set_util(cutoff)
...
pure subroutine, public calc_z(a, b, z, order)
...
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 pz_lsd_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 pz_info(method, lsd, reference, shortform, needs, max_deriv)
Return some info on the functionals.
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
A derivative set contains the different derivatives of a xc-functional in form of a linked list.
represent a derivative of a functional
contains a flag for each component of xc_rho_set, so that you can use it to tell which components you...
represent a density, with all the representation and data needed to perform a functional evaluation