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
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
73 TYPE(xc_rho_cflags_type),
INTENT(inout),
OPTIONAL :: needs
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
136 SUBROUTINE pz_lda_eval(method, rho_set, deriv_set, order, pz_params)
138 INTEGER,
INTENT(in) :: method
139 TYPE(xc_rho_set_type),
INTENT(IN) :: rho_set
140 TYPE(xc_derivative_set_type),
INTENT(IN) :: deriv_set
141 INTEGER,
INTENT(in) :: order
142 TYPE(section_vals_type),
POINTER :: pz_params
144 CHARACTER(len=*),
PARAMETER :: routinen =
'pz_lda_eval'
146 INTEGER :: npoints, timer_handle
147 INTEGER,
DIMENSION(2, 3) :: bo
148 REAL(kind=
dp) :: rho_cutoff, sc
149 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :), &
150 POINTER :: dummy, e_0, e_rho, e_rho_rho, &
152 TYPE(xc_derivative_type),
POINTER :: deriv
154 CALL timeset(routinen, timer_handle)
155 NULLIFY (rho, e_0, e_rho, e_rho_rho, e_rho_rho_rho, dummy)
160 local_bounds=bo, rho_cutoff=rho_cutoff)
161 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
163 CALL pz_init(method, rho_cutoff)
170 e_rho_rho_rho => dummy
174 allocate_deriv=.true.)
177 IF (order >= 1 .OR. order == -1)
THEN
179 allocate_deriv=.true.)
182 IF (order >= 2 .OR. order == -2)
THEN
184 allocate_deriv=.true.)
187 IF (order >= 3 .OR. order == -3)
THEN
189 allocate_deriv=.true.)
192 IF (order > 3 .OR. order < -3)
THEN
193 cpabort(
"derivatives bigger than 3 not implemented")
196 CALL pz_lda_calc(rho, e_0, e_rho, e_rho_rho, e_rho_rho_rho, npoints, order, sc)
198 CALL timestop(timer_handle)
213 SUBROUTINE pz_lda_calc(rho, e_0, e_rho, e_rho_rho, e_rho_rho_rho, npoints, order, sc)
215 REAL(kind=
dp),
DIMENSION(*),
INTENT(in) :: rho
216 REAL(kind=
dp),
DIMENSION(*),
INTENT(inout) :: e_0, e_rho, e_rho_rho, e_rho_rho_rho
217 INTEGER,
INTENT(in) :: npoints, order
221 REAL(kind=
dp),
DIMENSION(0:3) :: ed
227 IF (rho(k) > eps_rho)
THEN
229 CALL pz_lda_ed_loc(rho(k), ed, abs(order), sc)
232 e_0(k) = e_0(k) + rho(k)*ed(0)
234 IF (order >= 1 .OR. order == -1)
THEN
235 e_rho(k) = e_rho(k) + ed(0) + rho(k)*ed(1)
237 IF (order >= 2 .OR. order == -2)
THEN
238 e_rho_rho(k) = e_rho_rho(k) + 2.0_dp*ed(1) + rho(k)*ed(2)
240 IF (order >= 3 .OR. order == -3)
THEN
241 e_rho_rho_rho(k) = e_rho_rho_rho(k) + 3.0_dp*ed(2) + rho(k)*ed(3)
249 END SUBROUTINE pz_lda_calc
268 SUBROUTINE pz_lsd_eval(method, rho_set, deriv_set, order, pz_params)
269 INTEGER,
INTENT(in) :: method
270 TYPE(xc_rho_set_type),
INTENT(IN) :: rho_set
271 TYPE(xc_derivative_set_type),
INTENT(IN) :: deriv_set
272 INTEGER,
INTENT(IN),
OPTIONAL :: order
273 TYPE(section_vals_type),
POINTER :: pz_params
275 CHARACTER(len=*),
PARAMETER :: routinen =
'pz_lsd_eval'
277 INTEGER :: npoints, timer_handle
278 INTEGER,
DIMENSION(2, 3) :: bo
279 REAL(kind=
dp) :: rho_cutoff, sc
280 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :), &
281 POINTER :: a, b, dummy, e_0, ea, eaa, eaaa, eaab, &
283 TYPE(xc_derivative_type),
POINTER :: deriv
285 CALL timeset(routinen, timer_handle)
286 NULLIFY (a, b, e_0, ea, eaa, eab, ebb, eaaa, eaab, eabb, ebbb)
291 local_bounds=bo, rho_cutoff=rho_cutoff)
292 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
294 CALL pz_init(method, rho_cutoff)
300 eaa => dummy; eab => dummy; ebb => dummy
301 eaaa => dummy; eaab => dummy; eabb => dummy; ebbb => dummy
305 allocate_deriv=.true.)
308 IF (order >= 1 .OR. order == -1)
THEN
310 allocate_deriv=.true.)
313 IF (order >= 2 .OR. order == -2)
THEN
315 allocate_deriv=.true.)
318 allocate_deriv=.true.)
321 allocate_deriv=.true.)
324 IF (order >= 3 .OR. order == -3)
THEN
326 allocate_deriv=.true.)
329 allocate_deriv=.true.)
332 allocate_deriv=.true.)
335 allocate_deriv=.true.)
338 IF (order > 3 .OR. order < -3)
THEN
339 cpabort(
"derivatives bigger than 3 not implemented")
342 CALL pz_lsd_calc(a, b, e_0, ea, eaa, eab, ebb, eaaa, eaab, eabb, &
343 ebbb, npoints, order, sc)
345 CALL timestop(timer_handle)
366 SUBROUTINE pz_lsd_calc(a, b, e_0, ea, eaa, eab, ebb, eaaa, eaab, eabb, &
367 ebbb, npoints, order, sc)
369 REAL(kind=
dp),
DIMENSION(*),
INTENT(in) :: a, b
370 REAL(kind=
dp),
DIMENSION(*),
INTENT(inout) :: e_0, ea, eaa, eab, ebb, eaaa, eaab, &
372 INTEGER,
INTENT(in) :: npoints, order
373 REAL(kind=
dp),
INTENT(IN) :: sc
377 REAL(kind=
dp),
DIMENSION(0:9) :: ed
387 IF (rho > eps_rho)
THEN
389 CALL pz_lsd_ed_loc(a(k), b(k), ed, order_, sc)
392 e_0(k) = e_0(k) + rho*ed(0)
395 IF (order >= 1 .OR. order == -1)
THEN
396 ea(k) = ea(k) + ed(0) + rho*ed(1)
397 ea(k) = ea(k) + ed(0) + rho*ed(2)
400 IF (order >= 2 .OR. order == -2)
THEN
401 eaa(k) = eaa(k) + 2.0_dp*ed(1) + rho*ed(3)
402 eab(k) = eab(k) + ed(1) + ed(2) + rho*ed(4)
403 ebb(k) = ebb(k) + 2.0_dp*ed(2) + rho*ed(5)
406 IF (order >= 3 .OR. order == -3)
THEN
407 eaaa(k) = eaaa(k) + 3.0_dp*ed(3) + rho*ed(6)
408 eaab(k) = eaab(k) + 2.0_dp*ed(4) + ed(3) + rho*ed(7)
409 eabb(k) = eabb(k) + 2.0_dp*ed(4) + ed(5) + rho*ed(8)
410 ebbb(k) = ebbb(k) + 3.0_dp*ed(5) + rho*ed(9)
418 END SUBROUTINE pz_lsd_calc
428 SUBROUTINE pz_init(method, cutoff)
430 INTEGER,
INTENT(IN) :: method
431 REAL(kind=
dp),
INTENT(IN) :: cutoff
437 initialized = .false.
442 cpabort(
"Unknown method")
446 ga(0) = -0.1423_dp; ga(1) = -0.0843_dp
447 b1(0) = 1.0529_dp; b1(1) = 1.3981_dp
448 b2(0) = 0.3334_dp; b2(1) = 0.2611_dp
449 a(0) = 0.0311_dp; a(1) = 0.01555_dp
450 b(0) = -0.048_dp; b(1) = -0.0269_dp
451 c(0) = +0.0020_dp; c(1) = +0.0007_dp
452 d(0) = -0.0116_dp; d(1) = -0.0048_dp
456 ga(0) = -0.103756_dp; ga(1) = -0.065951_dp
457 b1(0) = 0.56371_dp; b1(1) = 1.11846_dp
458 b2(0) = 0.27358_dp; b2(1) = 0.18797_dp
459 a(0) = 0.031091_dp; a(1) = 0.015545_dp
460 b(0) = -0.046644_dp; b(1) = -0.025599_dp
461 c(0) = -0.00419_dp; c(1) = -0.00329_dp
462 d(0) = -0.00983_dp; d(1) = -0.00300_dp
466 ga(0) = -0.093662_dp; ga(1) = -0.055331_dp
467 b1(0) = 0.49453_dp; b1(1) = 0.93766_dp
468 b2(0) = 0.25534_dp; b2(1) = 0.14829_dp
469 a(0) = 0.031091_dp; a(1) = 0.015545_dp
470 b(0) = -0.046644_dp; b(1) = -0.025599_dp
471 c(0) = -0.00884_dp; c(1) = -0.00677_dp
472 d(0) = -0.00688_dp; d(1) = -0.00093_dp
478 END SUBROUTINE pz_init
487 SUBROUTINE calc_g(r, z, g, order)
489 REAL(kind=
dp),
INTENT(IN) :: r
490 INTEGER,
INTENT(IN) :: z
491 REAL(kind=
dp),
DIMENSION(0:),
INTENT(OUT) :: g
492 INTEGER,
INTENT(IN) :: order
494 REAL(kind=
dp) :: rr, rsr, sr
496 IF (r >= 1.0_dp)
THEN
500 g(0) = ga(z)/(1.0_dp + b1(z)*sr + b2(z)*r)
502 g(1) = -ga(z)*(b1(z)/(2.0_dp*sr) + b2(z))/ &
503 (1.0_dp + b1(z)*sr + b2(z)*r)**2
508 2.0_dp*ga(z)*(b1(z)/(2.0_dp*sr) + b2(z))**2 &
509 /(1.0_dp + b1(z)*sr + b2(z)*r)**3 &
511 /(4.0_dp*(1.0_dp + b1(z)*sr + b2(z)*r)**2*rsr)
515 -6.0_dp*ga(z)*(b1(z)/(2.0_dp*sr) + b2(z))**3/ &
516 (1.0_dp + b1(z)*sr + b2(z)*r)**4 &
517 - (3.0_dp/2.0_dp)*ga(z)*(b1(z)/(2.0_dp*sr) + b2(z))*b1(z)/ &
518 ((1.0_dp + b1(z)*sr + b2(z)*r)**3*rsr) &
519 - (3.0_dp/8.0_dp)*ga(z)*b1(z)/ &
520 ((1.0_dp + b1(z)*sr + b2(z)*r)**2*r*rsr)
526 g(0) = a(z)*log(r) + b(z) + c(z)*r*log(r) + d(z)*r
528 g(1) = a(z)/r + c(z)*log(r) + c(z) + d(z)
532 g(2) = -a(z)/rr + c(z)/r
535 g(3) = 2.0_dp*a(z)/(rr*r) - c(z)/rr
540 END SUBROUTINE calc_g
549 SUBROUTINE pz_lda_ed_loc(rho, ed, order, sc)
551 REAL(kind=
dp),
INTENT(IN) :: rho
552 REAL(kind=
dp),
DIMENSION(0:),
INTENT(OUT) :: ed
553 INTEGER,
INTENT(IN) :: order
554 REAL(
dp),
INTENT(IN) :: sc
557 LOGICAL,
DIMENSION(0:3) :: calc
558 REAL(kind=
dp),
DIMENSION(0:3) :: e0, r
563 IF (order_ >= 0)
THEN
564 calc(0:order_) = .true.
567 calc(order_) = .true.
570 CALL calc_rs(rho, r(0))
571 CALL calc_g(r(0), 0, e0, order_)
573 IF (order_ >= 1) r(1) = (-1.0_dp/3.0_dp)*r(0)/rho
574 IF (order_ >= 2) r(2) = (-4.0_dp/3.0_dp)*r(1)/rho
575 IF (order_ >= 3) r(3) = (-7.0_dp/3.0_dp)*r(2)/rho
583 ed(m) = sc*e0(1)*r(1)
587 ed(m) = sc*e0(2)*r(1)**2 + sc*e0(1)*r(2)
591 ed(m) = sc*e0(3)*r(1)**3 + sc*e0(2)*3.0_dp*r(1)*r(2) + sc*e0(1)*r(3)
594 END SUBROUTINE pz_lda_ed_loc
604 SUBROUTINE pz_lsd_ed_loc(a, b, ed, order, sc)
606 REAL(kind=
dp),
INTENT(IN) :: a, b
607 REAL(kind=
dp),
DIMENSION(0:),
INTENT(OUT) :: ed
608 INTEGER,
INTENT(IN),
OPTIONAL :: order
609 REAL(kind=
dp),
INTENT(IN) :: sc
612 LOGICAL,
DIMENSION(0:3) :: calc
613 REAL(kind=
dp) :: rho, tr, trr, trrr, trrz, trz, trzz, tz, &
615 REAL(kind=
dp),
DIMENSION(0:3) :: e0, e1, f, r
616 REAL(kind=
dp),
DIMENSION(0:3, 0:3) :: z
621 IF (
PRESENT(order)) order_ = order
623 IF (order_ >= 0)
THEN
624 calc(0:order_) = .true.
627 calc(order_) = .true.
632 CALL calc_fx(a, b, f(0:order_), order_)
633 CALL calc_rs(rho, r(0))
634 CALL calc_g(r(0), 0, e0(0:order_), order_)
635 CALL calc_g(r(0), 1, e1(0:order_), order_)
636 CALL calc_z(a, b, z(:, :), order_)
639 IF (order_ >= 1)
THEN
640 r(1) = (-1.0_dp/3.0_dp)*r(0)/rho
641 tr = e0(1) + (e1(1) - e0(1))*f(0)
642 tz = (e1(0) - e0(0))*f(1)
646 IF (order_ >= 2)
THEN
647 r(2) = (-4.0_dp/3.0_dp)*r(1)/rho
648 trr = e0(2) + (e1(2) - e0(2))*f(0)
649 trz = (e1(1) - e0(1))*f(1)
650 tzz = (e1(0) - e0(0))*f(2)
654 IF (order_ >= 3)
THEN
655 r(3) = (-7.0_dp/3.0_dp)*r(2)/rho
656 trrr = e0(3) + (e1(3) - e0(3))*f(0)
657 trrz = (e1(2) - e0(2))*f(1)
658 trzz = (e1(1) - e0(1))*f(2)
659 tzzz = (e1(0) - e0(0))*f(3)
664 ed(m) = e0(0) + (e1(0) - e0(0))*f(0)
670 ed(m) = tr*r(1) + tz*z(1, 0)
672 ed(m + 1) = tr*r(1) + tz*z(0, 1)
673 ed(m + 1) = ed(m + 1)*sc
678 ed(m) = trr*r(1)**2 + 2.0_dp*trz*r(1)*z(1, 0) &
679 + tr*r(2) + tzz*z(1, 0)**2 + tz*z(2, 0)
681 ed(m + 1) = trr*r(1)**2 + trz*r(1)*(z(0, 1) + z(1, 0)) &
682 + tr*r(2) + tzz*z(1, 0)*z(0, 1) + tz*z(1, 1)
683 ed(m + 1) = ed(m + 1)*sc
684 ed(m + 2) = trr*r(1)**2 + 2.0_dp*trz*r(1)*z(0, 1) &
685 + tr*r(2) + tzz*z(0, 1)**2 + tz*z(0, 2)
686 ed(m + 2) = ed(m + 2)*sc
691 ed(m) = trrr*r(1)**3 + 3.0_dp*trrz*r(1)**2*z(1, 0) &
692 + 3.0_dp*trr*r(1)*r(2) + 3.0_dp*trz*r(2)*z(1, 0) &
693 + tr*r(3) + 3.0_dp*trzz*r(1)*z(1, 0)**2 &
694 + tzzz*z(1, 0)**3 + 3.0_dp*trz*r(1)*z(2, 0) &
695 + 3.0_dp*tzz*z(1, 0)*z(2, 0) + tz*z(3, 0)
697 ed(m + 1) = trrr*r(1)**3 + trrz*r(1)**2*(2.0_dp*z(1, 0) + z(0, 1)) &
698 + 2.0_dp*trzz*r(1)*z(1, 0)*z(0, 1) &
699 + 2.0_dp*trz*(r(2)*z(1, 0) + r(1)*z(1, 1)) &
700 + 3.0_dp*trr*r(2)*r(1) + trz*r(2)*z(0, 1) + tr*r(3) &
701 + trzz*r(1)*z(1, 0)**2 + tzzz*z(1, 0)**2*z(0, 1) &
702 + 2.0_dp*tzz*z(1, 0)*z(1, 1) &
703 + trz*r(1)*z(2, 0) + tzz*z(2, 0)*z(0, 1) + tz*z(2, 1)
704 ed(m + 1) = ed(m + 1)*sc
705 ed(m + 2) = trrr*r(1)**3 + trrz*r(1)**2*(2.0_dp*z(0, 1) + z(1, 0)) &
706 + 2.0_dp*trzz*r(1)*z(0, 1)*z(1, 0) &
707 + 2.0_dp*trz*(r(2)*z(0, 1) + r(1)*z(1, 1)) &
708 + 3.0_dp*trr*r(2)*r(1) + trz*r(2)*z(1, 0) + tr*r(3) &
709 + trzz*r(1)*z(0, 1)**2 + tzzz*z(0, 1)**2*z(1, 0) &
710 + 2.0_dp*tzz*z(0, 1)*z(1, 1) &
711 + trz*r(1)*z(0, 2) + tzz*z(0, 2)*z(1, 0) + tz*z(1, 2)
712 ed(m + 2) = ed(m + 2)*sc
713 ed(m + 3) = trrr*r(1)**3 + 3.0_dp*trrz*r(1)**2*z(0, 1) &
714 + 3.0_dp*trr*r(1)*r(2) + 3.0_dp*trz*r(2)*z(0, 1) + tr*r(3) &
715 + 3.0_dp*trzz*r(1)*z(0, 1)**2 + tzzz*z(0, 1)**3 &
716 + 3.0_dp*trz*r(1)*z(0, 2) &
717 + 3.0_dp*tzz*z(0, 1)*z(0, 2) + tz*z(0, 3)
718 ed(m + 3) = ed(m + 3)*sc
721 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