33 #include "../base/base_uses.f90"
41 REAL(KIND=
dp),
PARAMETER :: pi = 3.14159265358979323846264338_dp
42 REAL(KIND=
dp),
PARAMETER :: f13 = 1.0_dp/3.0_dp, &
49 REAL(KIND=
dp) :: cf, flda, flsd, fvw
50 REAL(KIND=
dp) :: eps_rho
51 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xc_tfw'
59 SUBROUTINE tfw_init(cutoff)
61 REAL(KIND=
dp),
INTENT(IN) :: cutoff
66 cf = 0.3_dp*(3.0_dp*pi*pi)**f23
68 flsd = flda*2.0_dp**f23
71 END SUBROUTINE tfw_init
81 CHARACTER(LEN=*),
INTENT(OUT),
OPTIONAL :: reference, shortform
82 TYPE(xc_rho_cflags_type),
INTENT(inout),
OPTIONAL :: needs
83 INTEGER,
INTENT(out),
OPTIONAL :: max_deriv
85 IF (
PRESENT(reference))
THEN
86 reference =
"Thomas-Fermi-Weizsaecker kinetic energy functional {LDA version}"
88 IF (
PRESENT(shortform))
THEN
89 shortform =
"TF+vW kinetic energy functional {LDA}"
91 IF (
PRESENT(needs))
THEN
93 needs%rho_1_3 = .true.
94 needs%norm_drho = .true.
96 IF (
PRESENT(max_deriv)) max_deriv = 3
108 CHARACTER(LEN=*),
INTENT(OUT),
OPTIONAL :: reference, shortform
109 TYPE(xc_rho_cflags_type),
INTENT(inout),
OPTIONAL :: needs
110 INTEGER,
INTENT(out),
OPTIONAL :: max_deriv
112 IF (
PRESENT(reference))
THEN
113 reference =
"Thomas-Fermi-Weizsaecker kinetic energy functional"
115 IF (
PRESENT(shortform))
THEN
116 shortform =
"TF+vW kinetic energy functional"
118 IF (
PRESENT(needs))
THEN
119 needs%rho_spin = .true.
120 needs%rho_spin_1_3 = .true.
121 needs%norm_drho = .true.
123 IF (
PRESENT(max_deriv)) max_deriv = 3
134 TYPE(xc_rho_set_type),
INTENT(IN) :: rho_set
135 TYPE(xc_derivative_set_type),
INTENT(IN) :: deriv_set
136 INTEGER,
INTENT(in) :: order
138 CHARACTER(len=*),
PARAMETER :: routinen =
'tfw_lda_eval'
140 INTEGER :: handle, npoints
141 INTEGER,
DIMENSION(2, 3) :: bo
142 REAL(kind=
dp) :: epsilon_rho
143 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: s
144 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :),
POINTER :: e_0, e_ndrho, e_ndrho_ndrho, &
145 e_rho, e_rho_ndrho, e_rho_ndrho_ndrho, e_rho_rho, e_rho_rho_ndrho, e_rho_rho_rho, grho, &
147 TYPE(xc_derivative_type),
POINTER :: deriv
149 CALL timeset(routinen, handle)
152 norm_drho=grho, local_bounds=bo, rho_cutoff=epsilon_rho)
153 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
154 CALL tfw_init(epsilon_rho)
156 ALLOCATE (s(npoints))
157 CALL calc_s(rho, grho, s, npoints)
161 allocate_deriv=.true.)
164 CALL tfw_u_0(rho, r13, s, e_0, npoints)
166 IF (order >= 1 .OR. order == -1)
THEN
168 allocate_deriv=.true.)
171 allocate_deriv=.true.)
174 CALL tfw_u_1(rho, grho, r13, s, e_rho, e_ndrho, npoints)
176 IF (order >= 2 .OR. order == -2)
THEN
178 allocate_deriv=.true.)
181 allocate_deriv=.true.)
187 CALL tfw_u_2(rho, grho, r13, s, e_rho_rho, e_rho_ndrho, &
188 e_ndrho_ndrho, npoints)
190 IF (order >= 3 .OR. order == -3)
THEN
192 allocate_deriv=.true.)
201 CALL tfw_u_3(rho, grho, r13, s, e_rho_rho_rho, e_rho_rho_ndrho, &
202 e_rho_ndrho_ndrho, npoints)
204 IF (order > 3 .OR. order < -3)
THEN
205 cpabort(
"derivatives bigger than 3 not implemented")
209 CALL timestop(handle)
219 SUBROUTINE calc_s(rho, grho, s, npoints)
220 REAL(kind=
dp),
DIMENSION(*),
INTENT(in) :: rho, grho
221 REAL(kind=
dp),
DIMENSION(*),
INTENT(out) :: s
222 INTEGER,
INTENT(in) :: npoints
229 IF (rho(ip) < eps_rho)
THEN
232 s(ip) = grho(ip)*grho(ip)/rho(ip)
235 END SUBROUTINE calc_s
244 TYPE(xc_rho_set_type),
INTENT(IN) :: rho_set
245 TYPE(xc_derivative_set_type),
INTENT(IN) :: deriv_set
246 INTEGER,
INTENT(in) :: order
248 CHARACTER(len=*),
PARAMETER :: routinen =
'tfw_lsd_eval'
249 INTEGER,
DIMENSION(2),
PARAMETER :: &
253 INTEGER :: handle, i, ispin, npoints
254 INTEGER,
DIMENSION(2, 3) :: bo
255 REAL(kind=
dp) :: epsilon_rho
256 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: s
257 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :), &
258 POINTER :: e_0, e_ndrho, e_ndrho_ndrho, e_rho, &
259 e_rho_ndrho, e_rho_ndrho_ndrho, &
260 e_rho_rho, e_rho_rho_ndrho, &
262 TYPE(cp_3d_r_cp_type),
DIMENSION(2) :: norm_drho, rho, rho_1_3
263 TYPE(xc_derivative_type),
POINTER :: deriv
265 CALL timeset(routinen, handle)
268 NULLIFY (norm_drho(i)%array, rho(i)%array, rho_1_3(i)%array)
272 rhob_1_3=rho_1_3(2)%array, rhoa=rho(1)%array, &
273 rhob=rho(2)%array, norm_drhoa=norm_drho(1)%array, &
274 norm_drhob=norm_drho(2)%array, rho_cutoff=epsilon_rho, &
276 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
277 CALL tfw_init(epsilon_rho)
279 ALLOCATE (s(npoints))
282 CALL calc_s(rho(ispin)%array, norm_drho(ispin)%array, s, npoints)
286 allocate_deriv=.true.)
289 CALL tfw_p_0(rho(ispin)%array, &
290 rho_1_3(ispin)%array, s, e_0, npoints)
292 IF (order >= 1 .OR. order == -1)
THEN
294 allocate_deriv=.true.)
297 allocate_deriv=.true.)
300 CALL tfw_p_1(rho(ispin)%array, norm_drho(ispin)%array, &
301 rho_1_3(ispin)%array, s, e_rho, e_ndrho, npoints)
303 IF (order >= 2 .OR. order == -2)
THEN
305 rho_spin_name(ispin)], allocate_deriv=.true.)
308 norm_drho_spin_name(ispin)], allocate_deriv=.true.)
311 norm_drho_spin_name(ispin)], allocate_deriv=.true.)
314 CALL tfw_p_2(rho(ispin)%array, norm_drho(ispin)%array, &
315 rho_1_3(ispin)%array, s, e_rho_rho, e_rho_ndrho, &
316 e_ndrho_ndrho, npoints)
318 IF (order >= 3 .OR. order == -3)
THEN
320 rho_spin_name(ispin), rho_spin_name(ispin)], &
321 allocate_deriv=.true.)
324 rho_spin_name(ispin), norm_drho_spin_name(ispin)], &
325 allocate_deriv=.true.)
328 norm_drho_spin_name(ispin), norm_drho_spin_name(ispin)], &
329 allocate_deriv=.true.)
332 CALL tfw_p_3(rho(ispin)%array, norm_drho(ispin)%array, &
333 rho_1_3(ispin)%array, s, e_rho_rho_rho, e_rho_rho_ndrho, &
334 e_rho_ndrho_ndrho, npoints)
336 IF (order > 3 .OR. order < -3)
THEN
337 cpabort(
"derivatives bigger than 3 not implemented")
342 CALL timestop(handle)
353 SUBROUTINE tfw_u_0(rho, r13, s, e_0, npoints)
355 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, r13, s
356 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_0
357 INTEGER,
INTENT(in) :: npoints
365 IF (rho(ip) > eps_rho)
THEN
367 e_0(ip) = e_0(ip) + flda*r13(ip)*r13(ip)*rho(ip) + fvw*s(ip)
373 END SUBROUTINE tfw_u_0
385 SUBROUTINE tfw_u_1(rho, grho, r13, s, e_rho, e_ndrho, npoints)
387 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, grho, r13, s
388 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho, e_ndrho
389 INTEGER,
INTENT(in) :: npoints
400 IF (rho(ip) > eps_rho)
THEN
402 e_rho(ip) = e_rho(ip) + f*r13(ip)*r13(ip) - fvw*s(ip)/rho(ip)
403 e_ndrho(ip) = e_ndrho(ip) + 2.0_dp*fvw*grho(ip)/rho(ip)
409 END SUBROUTINE tfw_u_1
422 SUBROUTINE tfw_u_2(rho, grho, r13, s, e_rho_rho, e_rho_ndrho, e_ndrho_ndrho, &
425 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, grho, r13, s
426 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho_rho, e_rho_ndrho, e_ndrho_ndrho
427 INTEGER,
INTENT(in) :: npoints
438 IF (rho(ip) > eps_rho)
THEN
440 e_rho_rho(ip) = e_rho_rho(ip) + f/r13(ip) + 2.0_dp*fvw*s(ip)/(rho(ip)*rho(ip))
441 e_rho_ndrho(ip) = e_rho_ndrho(ip) - 2.0_dp*fvw*grho(ip)/(rho(ip)*rho(ip))
442 e_ndrho_ndrho(ip) = e_ndrho_ndrho(ip) + 2.0_dp*fvw/rho(ip)
448 END SUBROUTINE tfw_u_2
461 SUBROUTINE tfw_u_3(rho, grho, r13, s, e_rho_rho_rho, e_rho_rho_ndrho, &
462 e_rho_ndrho_ndrho, npoints)
464 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, grho, r13, s
465 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho_rho_rho, e_rho_rho_ndrho, &
467 INTEGER,
INTENT(in) :: npoints
472 f = -f13*f23*f53*flda
478 IF (rho(ip) > eps_rho)
THEN
480 e_rho_rho_rho(ip) = e_rho_rho_rho(ip) + f/(r13(ip)*rho(ip)) &
481 - 6.0_dp*fvw*s(ip)/(rho(ip)*rho(ip)*rho(ip))
482 e_rho_rho_ndrho(ip) = e_rho_rho_ndrho(ip) &
483 + 4.0_dp*fvw*grho(ip)/(rho(ip)*rho(ip)*rho(ip))
484 e_rho_ndrho_ndrho(ip) = e_rho_ndrho_ndrho(ip) &
485 - 2.0_dp*fvw/(rho(ip)*rho(ip))
490 END SUBROUTINE tfw_u_3
500 SUBROUTINE tfw_p_0(rhoa, r13a, sa, e_0, npoints)
502 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, r13a, sa
503 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_0
504 INTEGER,
INTENT(in) :: npoints
512 IF (rhoa(ip) > eps_rho)
THEN
513 e_0(ip) = e_0(ip) + flsd*r13a(ip)*r13a(ip)*rhoa(ip) + fvw*sa(ip)
518 END SUBROUTINE tfw_p_0
530 SUBROUTINE tfw_p_1(rhoa, grhoa, r13a, sa, e_rho, e_ndrho, npoints)
532 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, grhoa, r13a, sa
533 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho, e_ndrho
534 INTEGER,
INTENT(in) :: npoints
545 IF (rhoa(ip) > eps_rho)
THEN
546 e_rho(ip) = e_rho(ip) + f*r13a(ip)*r13a(ip) - fvw*sa(ip)/rhoa(ip)
547 e_ndrho(ip) = e_ndrho(ip) + 2.0_dp*fvw*grhoa(ip)/rhoa(ip)
552 END SUBROUTINE tfw_p_1
565 SUBROUTINE tfw_p_2(rhoa, grhoa, r13a, sa, e_rho_rho, e_rho_ndrho, &
566 e_ndrho_ndrho, npoints)
568 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, grhoa, r13a, sa
569 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho_rho, e_rho_ndrho, e_ndrho_ndrho
570 INTEGER,
INTENT(in) :: npoints
581 IF (rhoa(ip) > eps_rho)
THEN
582 e_rho_rho(ip) = e_rho_rho(ip) &
583 + f/r13a(ip) + 2.0_dp*fvw*sa(ip)/(rhoa(ip)*rhoa(ip))
584 e_rho_ndrho(ip) = e_rho_ndrho(ip) &
585 - 2.0_dp*fvw*grhoa(ip)/(rhoa(ip)*rhoa(ip))
586 e_ndrho_ndrho(ip) = e_ndrho_ndrho(ip) + 2.0_dp*fvw/rhoa(ip)
591 END SUBROUTINE tfw_p_2
604 SUBROUTINE tfw_p_3(rhoa, grhoa, r13a, sa, e_rho_rho_rho, e_rho_rho_ndrho, &
605 e_rho_ndrho_ndrho, npoints)
607 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, grhoa, r13a, sa
608 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho_rho_rho, e_rho_rho_ndrho, &
610 INTEGER,
INTENT(in) :: npoints
615 f = -f13*f23*f53*flsd
621 IF (rhoa(ip) > eps_rho)
THEN
622 e_rho_rho_rho(ip) = e_rho_rho_rho(ip) &
623 + f/(r13a(ip)*rhoa(ip)) &
624 - 6.0_dp*fvw*sa(ip)/(rhoa(ip)*rhoa(ip)*rhoa(ip))
625 e_rho_rho_ndrho(ip) = e_rho_rho_ndrho(ip) &
626 + 4.0_dp*fvw*grhoa(ip)/(rhoa(ip)*rhoa(ip)*rhoa(ip))
627 e_rho_ndrho_ndrho(ip) = e_rho_ndrho_ndrho(ip) &
628 - 2.0_dp*fvw/(rhoa(ip)*rhoa(ip))
633 END SUBROUTINE tfw_p_3
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
Module with functions to handle derivative descriptors. derivative description are strings have the f...
integer, parameter, public deriv_norm_drho
integer, parameter, public deriv_norm_drhoa
integer, parameter, public deriv_rhob
integer, parameter, public deriv_rhoa
integer, parameter, public deriv_rho
integer, parameter, public deriv_norm_drhob
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 Thomas-Fermi kinetic energy functional plus the von Weizsaecker term.
subroutine, public tfw_lda_info(reference, shortform, needs, max_deriv)
...
subroutine, public tfw_lda_eval(rho_set, deriv_set, order)
...
subroutine, public tfw_lsd_info(reference, shortform, needs, max_deriv)
...
subroutine, public tfw_lsd_eval(rho_set, deriv_set, order)
...