37#include "../base/base_uses.f90"
44 REAL(KIND=
dp),
PARAMETER :: f13 = 1.0_dp/3.0_dp, &
50 REAL(KIND=
dp) :: xparam, flda, flsd
51 REAL(KIND=
dp) :: eps_rho
52 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xc_xalpha'
61 SUBROUTINE xalpha_init(cutoff, xalpha)
63 REAL(KIND=
dp),
INTENT(IN) :: cutoff
64 REAL(KIND=
dp),
INTENT(IN),
OPTIONAL :: xalpha
68 IF (
PRESENT(xalpha))
THEN
71 xparam = 2.0_dp/3.0_dp
74 flda = -9.0_dp/8.0_dp*xparam*(3.0_dp/
pi)**f13
75 flsd = flda*2.0_dp**f13
77 END SUBROUTINE xalpha_init
89 SUBROUTINE xalpha_info(lsd, reference, shortform, needs, max_deriv, &
90 xa_parameter, scaling)
91 LOGICAL,
INTENT(in) :: lsd
92 CHARACTER(LEN=*),
INTENT(OUT),
OPTIONAL :: reference, shortform
94 INTEGER,
INTENT(out),
OPTIONAL :: max_deriv
95 REAL(kind=
dp),
INTENT(in),
OPTIONAL :: xa_parameter, scaling
97 REAL(kind=
dp) :: my_scaling, my_xparam
99 my_xparam = 2.0_dp/3.0_dp
100 IF (
PRESENT(xa_parameter)) my_xparam = xa_parameter
102 IF (
PRESENT(scaling)) my_scaling = scaling
104 IF (
PRESENT(reference))
THEN
105 IF (my_scaling /= 1._dp)
THEN
106 WRITE (reference,
'(A,F8.4,A,F8.4)') &
107 "Dirac/Slater local exchange; parameter=", my_xparam,
" scaling=", my_scaling
109 WRITE (reference,
'(A,F8.4)') &
110 "Dirac/Slater local exchange; parameter=", my_xparam
113 IF (len_trim(reference) + 6 < len(reference))
THEN
114 reference(len_trim(reference):len_trim(reference) + 6) =
' {LDA}'
118 IF (
PRESENT(shortform))
THEN
119 IF (my_scaling /= 1._dp)
THEN
120 WRITE (shortform,
'(A,F8.4,F8.4)')
"Dirac/Slater exchange", my_xparam, my_scaling
122 WRITE (shortform,
'(A,F8.4)')
"Dirac/Slater exchange", my_xparam
125 IF (len_trim(shortform) + 6 < len(shortform))
THEN
126 shortform(len_trim(shortform):len_trim(shortform) + 6) =
' {LDA}'
130 IF (
PRESENT(needs))
THEN
132 needs%rho_spin = .true.
133 needs%rho_spin_1_3 = .true.
136 needs%rho_1_3 = .true.
139 IF (
PRESENT(max_deriv)) max_deriv = 3
154 INTEGER,
INTENT(in) :: order
156 REAL(kind=
dp),
INTENT(in),
OPTIONAL :: xa_parameter
158 CHARACTER(len=*),
PARAMETER :: routinen =
'xalpha_lda_eval'
160 INTEGER :: handle, npoints
161 INTEGER,
DIMENSION(2, 3) :: bo
162 REAL(kind=
dp) :: epsilon_rho, sx
163 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :), &
164 POINTER :: e_0, e_rho, e_rho_rho, e_rho_rho_rho, &
168 CALL timeset(routinen, handle)
173 local_bounds=bo, rho_cutoff=epsilon_rho)
174 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
175 CALL xalpha_init(epsilon_rho, xa_parameter)
179 allocate_deriv=.true.)
182 CALL xalpha_lda_0(npoints, rho, r13, e_0, sx)
185 IF (order >= 1 .OR. order == -1)
THEN
187 allocate_deriv=.true.)
190 CALL xalpha_lda_1(npoints, rho, r13, e_rho, sx)
192 IF (order >= 2 .OR. order == -2)
THEN
194 allocate_deriv=.true.)
197 CALL xalpha_lda_2(npoints, rho, r13, e_rho_rho, sx)
199 IF (order >= 3 .OR. order == -3)
THEN
201 allocate_deriv=.true.)
204 CALL xalpha_lda_3(npoints, rho, r13, e_rho_rho_rho, sx)
206 IF (order > 3 .OR. order < -3)
THEN
207 cpabort(
"derivatives bigger than 3 not implemented")
209 CALL timestop(handle)
224 INTEGER,
INTENT(in) :: order
226 REAL(kind=
dp),
INTENT(in),
OPTIONAL :: xa_parameter
228 CHARACTER(len=*),
PARAMETER :: routinen =
'xalpha_lsd_eval'
231 INTEGER :: handle, i, ispin, npoints
232 INTEGER,
DIMENSION(2, 3) :: bo
233 REAL(kind=
dp) :: epsilon_rho, sx
234 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :), &
235 POINTER :: e_0, e_rho, e_rho_rho, e_rho_rho_rho
239 CALL timeset(routinen, handle)
242 NULLIFY (rho(i)%array, rho_1_3(i)%array)
248 rhob_1_3=rho_1_3(2)%array, rhoa=rho(1)%array, &
249 rhob=rho(2)%array, rho_cutoff=epsilon_rho, &
251 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
252 CALL xalpha_init(epsilon_rho, xa_parameter)
257 allocate_deriv=.true.)
260 CALL xalpha_lsd_0(npoints, rho(ispin)%array, rho_1_3(ispin)%array, &
263 IF (order >= 1 .OR. order == -1)
THEN
265 allocate_deriv=.true.)
268 CALL xalpha_lsd_1(npoints, rho(ispin)%array, rho_1_3(ispin)%array, &
271 IF (order >= 2 .OR. order == -2)
THEN
273 rho_spin_name(ispin)], allocate_deriv=.true.)
276 CALL xalpha_lsd_2(npoints, rho(ispin)%array, rho_1_3(ispin)%array, &
279 IF (order >= 3 .OR. order == -3)
THEN
281 rho_spin_name(ispin), rho_spin_name(ispin)], &
282 allocate_deriv=.true.)
285 CALL xalpha_lsd_3(npoints, rho(ispin)%array, rho_1_3(ispin)%array, &
288 IF (order > 3 .OR. order < -3)
THEN
289 cpabort(
"derivatives bigger than 3 not implemented")
292 CALL timestop(handle)
303 SUBROUTINE xalpha_lda_0(n, rho, r13, pot, sx)
305 INTEGER,
INTENT(IN) :: n
306 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, r13
307 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: pot
308 REAL(kind=
dp),
INTENT(IN) :: sx
318 IF (rho(ip) > eps_rho)
THEN
319 pot(ip) = pot(ip) + f*r13(ip)*rho(ip)
323 END SUBROUTINE xalpha_lda_0
333 SUBROUTINE xalpha_lda_1(n, rho, r13, pot, sx)
335 INTEGER,
INTENT(IN) :: n
336 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, r13
337 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: pot
347 IF (rho(ip) > eps_rho)
THEN
348 pot(ip) = pot(ip) + f*r13(ip)
352 END SUBROUTINE xalpha_lda_1
362 SUBROUTINE xalpha_lda_2(n, rho, r13, pot, sx)
364 INTEGER,
INTENT(IN) :: n
365 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, r13
366 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: pot
376 IF (rho(ip) > eps_rho)
THEN
377 pot(ip) = pot(ip) + f*r13(ip)/rho(ip)
381 END SUBROUTINE xalpha_lda_2
391 SUBROUTINE xalpha_lda_3(n, rho, r13, pot, sx)
393 INTEGER,
INTENT(IN) :: n
394 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, r13
395 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: pot
401 f = -f23*f13*f43*flda*sx
405 IF (rho(ip) > eps_rho)
THEN
406 pot(ip) = pot(ip) + f*r13(ip)/(rho(ip)*rho(ip))
410 END SUBROUTINE xalpha_lda_3
420 SUBROUTINE xalpha_lsd_0(n, rhoa, r13a, pot, sx)
422 INTEGER,
INTENT(IN) :: n
423 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, r13a
424 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: pot
438 IF (rhoa(ip) > eps_rho)
THEN
439 pot(ip) = pot(ip) + f*r13a(ip)*rhoa(ip)
444 END SUBROUTINE xalpha_lsd_0
454 SUBROUTINE xalpha_lsd_1(n, rhoa, r13a, pota, sx)
456 INTEGER,
INTENT(IN) :: n
457 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, r13a
458 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: pota
472 IF (rhoa(ip) > eps_rho)
THEN
473 pota(ip) = pota(ip) + f*r13a(ip)
478 END SUBROUTINE xalpha_lsd_1
488 SUBROUTINE xalpha_lsd_2(n, rhoa, r13a, potaa, sx)
490 INTEGER,
INTENT(IN) :: n
491 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, r13a
492 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: potaa
506 IF (rhoa(ip) > eps_rho)
THEN
507 potaa(ip) = potaa(ip) + f*r13a(ip)/rhoa(ip)
512 END SUBROUTINE xalpha_lsd_2
522 SUBROUTINE xalpha_lsd_3(n, rhoa, r13a, potaaa, sx)
524 INTEGER,
INTENT(IN) :: n
525 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, r13a
526 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: potaaa
534 f = -f23*f13*f43*flsd*sx
540 IF (rhoa(ip) > eps_rho)
THEN
541 potaaa(ip) = potaaa(ip) + f*r13a(ip)/(rhoa(ip)*rhoa(ip))
546 END SUBROUTINE xalpha_lsd_3
560 REAL(kind=
dp),
INTENT(IN) :: scale_x, eps_rho
563 INTEGER,
DIMENSION(2, 3) :: bo
564 REAL(kind=
dp) :: eaa, ebb, f, flda, flsd, rhoa, rhob
566 flda = -3.0_dp/4.0_dp*(3.0_dp/
pi)**f13
567 flsd = flda*2.0_dp**f13
568 f = f13*f43*flsd*scale_x
569 bo(1:2, 1:3) = rho_a%pw_grid%bounds_local(1:2, 1:3)
572 DO k = bo(1, 3), bo(2, 3)
573 DO j = bo(1, 2), bo(2, 2)
574 DO i = bo(1, 1), bo(2, 1)
576 rhoa = rho_a%array(i, j, k)
577 IF (rhoa > eps_rho)
THEN
579 fxc_aa%array(i, j, k) = fxc_aa%array(i, j, k) + f*eaa
581 rhob = rho_b%array(i, j, k)
582 IF (rhob > eps_rho)
THEN
584 fxc_bb%array(i, j, k) = fxc_bb%array(i, j, k) + f*ebb
various utilities that regard array of different kinds: output, allocation,... maybe it is not a good...
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
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)
...
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
Calculate the local exchange functional.
subroutine, public xalpha_fxc_eval(rho_a, rho_b, fxc_aa, fxc_bb, scale_x, eps_rho)
...
subroutine, public xalpha_lda_eval(rho_set, deriv_set, order, xa_params, xa_parameter)
...
subroutine, public xalpha_info(lsd, reference, shortform, needs, max_deriv, xa_parameter, scaling)
...
subroutine, public xalpha_lsd_eval(rho_set, deriv_set, order, xa_params, xa_parameter)
...
represent a pointer to a contiguous 3d array
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