34#include "../base/base_uses.f90"
41 REAL(KIND=
dp),
PARAMETER :: f13 = 1.0_dp/3.0_dp, &
48 REAL(KIND=
dp) :: cf, flda, flsd, fvw
49 REAL(KIND=
dp) :: eps_rho
50 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xc_tfw'
58 SUBROUTINE tfw_init(cutoff)
60 REAL(KIND=
dp),
INTENT(IN) :: cutoff
65 cf = 0.3_dp*(3.0_dp*
pi*
pi)**f23
67 flsd = flda*2.0_dp**f23
70 END SUBROUTINE tfw_init
80 CHARACTER(LEN=*),
INTENT(OUT),
OPTIONAL :: reference, shortform
82 INTEGER,
INTENT(out),
OPTIONAL :: max_deriv
84 IF (
PRESENT(reference))
THEN
85 reference =
"Thomas-Fermi-Weizsaecker kinetic energy functional {LDA version}"
87 IF (
PRESENT(shortform))
THEN
88 shortform =
"TF+vW kinetic energy functional {LDA}"
90 IF (
PRESENT(needs))
THEN
92 needs%rho_1_3 = .true.
93 needs%norm_drho = .true.
95 IF (
PRESENT(max_deriv)) max_deriv = 3
107 CHARACTER(LEN=*),
INTENT(OUT),
OPTIONAL :: reference, shortform
109 INTEGER,
INTENT(out),
OPTIONAL :: max_deriv
111 IF (
PRESENT(reference))
THEN
112 reference =
"Thomas-Fermi-Weizsaecker kinetic energy functional"
114 IF (
PRESENT(shortform))
THEN
115 shortform =
"TF+vW kinetic energy functional"
117 IF (
PRESENT(needs))
THEN
118 needs%rho_spin = .true.
119 needs%rho_spin_1_3 = .true.
120 needs%norm_drho = .true.
122 IF (
PRESENT(max_deriv)) max_deriv = 3
135 INTEGER,
INTENT(in) :: order
137 CHARACTER(len=*),
PARAMETER :: routinen =
'tfw_lda_eval'
139 INTEGER :: handle, npoints
140 INTEGER,
DIMENSION(2, 3) :: bo
141 REAL(kind=
dp) :: epsilon_rho
142 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: s
143 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :),
POINTER :: e_0, e_ndrho, e_ndrho_ndrho, &
144 e_rho, e_rho_ndrho, e_rho_ndrho_ndrho, e_rho_rho, e_rho_rho_ndrho, e_rho_rho_rho, grho, &
148 CALL timeset(routinen, handle)
151 norm_drho=grho, local_bounds=bo, rho_cutoff=epsilon_rho)
152 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
153 CALL tfw_init(epsilon_rho)
155 ALLOCATE (s(npoints))
156 CALL calc_s(rho, grho, s, npoints)
160 allocate_deriv=.true.)
163 CALL tfw_u_0(rho, r13, s, e_0, npoints)
165 IF (order >= 1 .OR. order == -1)
THEN
167 allocate_deriv=.true.)
170 allocate_deriv=.true.)
173 CALL tfw_u_1(rho, grho, r13, s, e_rho, e_ndrho, npoints)
175 IF (order >= 2 .OR. order == -2)
THEN
177 allocate_deriv=.true.)
180 allocate_deriv=.true.)
186 CALL tfw_u_2(rho, grho, r13, s, e_rho_rho, e_rho_ndrho, &
187 e_ndrho_ndrho, npoints)
189 IF (order >= 3 .OR. order == -3)
THEN
191 allocate_deriv=.true.)
200 CALL tfw_u_3(rho, grho, r13, s, e_rho_rho_rho, e_rho_rho_ndrho, &
201 e_rho_ndrho_ndrho, npoints)
203 IF (order > 3 .OR. order < -3)
THEN
204 cpabort(
"derivatives bigger than 3 not implemented")
208 CALL timestop(handle)
218 SUBROUTINE calc_s(rho, grho, s, npoints)
219 REAL(kind=
dp),
DIMENSION(*),
INTENT(in) :: rho, grho
220 REAL(kind=
dp),
DIMENSION(*),
INTENT(out) :: s
221 INTEGER,
INTENT(in) :: npoints
228 IF (rho(ip) < eps_rho)
THEN
231 s(ip) = grho(ip)*grho(ip)/rho(ip)
234 END SUBROUTINE calc_s
245 INTEGER,
INTENT(in) :: order
247 CHARACTER(len=*),
PARAMETER :: routinen =
'tfw_lsd_eval'
248 INTEGER,
DIMENSION(2),
PARAMETER :: &
252 INTEGER :: handle, i, ispin, npoints
253 INTEGER,
DIMENSION(2, 3) :: bo
254 REAL(kind=
dp) :: epsilon_rho
255 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: s
256 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :), &
257 POINTER :: e_0, e_ndrho, e_ndrho_ndrho, e_rho, &
258 e_rho_ndrho, e_rho_ndrho_ndrho, &
259 e_rho_rho, e_rho_rho_ndrho, &
264 CALL timeset(routinen, handle)
267 NULLIFY (norm_drho(i)%array, rho(i)%array, rho_1_3(i)%array)
271 rhob_1_3=rho_1_3(2)%array, rhoa=rho(1)%array, &
272 rhob=rho(2)%array, norm_drhoa=norm_drho(1)%array, &
273 norm_drhob=norm_drho(2)%array, rho_cutoff=epsilon_rho, &
275 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
276 CALL tfw_init(epsilon_rho)
278 ALLOCATE (s(npoints))
281 CALL calc_s(rho(ispin)%array, norm_drho(ispin)%array, s, npoints)
285 allocate_deriv=.true.)
288 CALL tfw_p_0(rho(ispin)%array, &
289 rho_1_3(ispin)%array, s, e_0, npoints)
291 IF (order >= 1 .OR. order == -1)
THEN
293 allocate_deriv=.true.)
296 allocate_deriv=.true.)
299 CALL tfw_p_1(rho(ispin)%array, norm_drho(ispin)%array, &
300 rho_1_3(ispin)%array, s, e_rho, e_ndrho, npoints)
302 IF (order >= 2 .OR. order == -2)
THEN
304 rho_spin_name(ispin)], allocate_deriv=.true.)
307 norm_drho_spin_name(ispin)], allocate_deriv=.true.)
310 norm_drho_spin_name(ispin)], allocate_deriv=.true.)
313 CALL tfw_p_2(rho(ispin)%array, norm_drho(ispin)%array, &
314 rho_1_3(ispin)%array, s, e_rho_rho, e_rho_ndrho, &
315 e_ndrho_ndrho, npoints)
317 IF (order >= 3 .OR. order == -3)
THEN
319 rho_spin_name(ispin), rho_spin_name(ispin)], &
320 allocate_deriv=.true.)
323 rho_spin_name(ispin), norm_drho_spin_name(ispin)], &
324 allocate_deriv=.true.)
327 norm_drho_spin_name(ispin), norm_drho_spin_name(ispin)], &
328 allocate_deriv=.true.)
331 CALL tfw_p_3(rho(ispin)%array, norm_drho(ispin)%array, &
332 rho_1_3(ispin)%array, s, e_rho_rho_rho, e_rho_rho_ndrho, &
333 e_rho_ndrho_ndrho, npoints)
335 IF (order > 3 .OR. order < -3)
THEN
336 cpabort(
"derivatives bigger than 3 not implemented")
341 CALL timestop(handle)
352 SUBROUTINE tfw_u_0(rho, r13, s, e_0, npoints)
354 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, r13, s
355 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_0
356 INTEGER,
INTENT(in) :: npoints
364 IF (rho(ip) > eps_rho)
THEN
366 e_0(ip) = e_0(ip) + flda*r13(ip)*r13(ip)*rho(ip) + fvw*s(ip)
372 END SUBROUTINE tfw_u_0
384 SUBROUTINE tfw_u_1(rho, grho, r13, s, e_rho, e_ndrho, npoints)
386 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, grho, r13, s
387 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho, e_ndrho
388 INTEGER,
INTENT(in) :: npoints
399 IF (rho(ip) > eps_rho)
THEN
401 e_rho(ip) = e_rho(ip) + f*r13(ip)*r13(ip) - fvw*s(ip)/rho(ip)
402 e_ndrho(ip) = e_ndrho(ip) + 2.0_dp*fvw*grho(ip)/rho(ip)
408 END SUBROUTINE tfw_u_1
421 SUBROUTINE tfw_u_2(rho, grho, r13, s, e_rho_rho, e_rho_ndrho, e_ndrho_ndrho, &
424 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, grho, r13, s
425 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho_rho, e_rho_ndrho, e_ndrho_ndrho
426 INTEGER,
INTENT(in) :: npoints
437 IF (rho(ip) > eps_rho)
THEN
439 e_rho_rho(ip) = e_rho_rho(ip) + f/r13(ip) + 2.0_dp*fvw*s(ip)/(rho(ip)*rho(ip))
440 e_rho_ndrho(ip) = e_rho_ndrho(ip) - 2.0_dp*fvw*grho(ip)/(rho(ip)*rho(ip))
441 e_ndrho_ndrho(ip) = e_ndrho_ndrho(ip) + 2.0_dp*fvw/rho(ip)
447 END SUBROUTINE tfw_u_2
460 SUBROUTINE tfw_u_3(rho, grho, r13, s, e_rho_rho_rho, e_rho_rho_ndrho, &
461 e_rho_ndrho_ndrho, npoints)
463 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rho, grho, r13, s
464 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho_rho_rho, e_rho_rho_ndrho, &
466 INTEGER,
INTENT(in) :: npoints
471 f = -f13*f23*f53*flda
477 IF (rho(ip) > eps_rho)
THEN
479 e_rho_rho_rho(ip) = e_rho_rho_rho(ip) + f/(r13(ip)*rho(ip)) &
480 - 6.0_dp*fvw*s(ip)/(rho(ip)*rho(ip)*rho(ip))
481 e_rho_rho_ndrho(ip) = e_rho_rho_ndrho(ip) &
482 + 4.0_dp*fvw*grho(ip)/(rho(ip)*rho(ip)*rho(ip))
483 e_rho_ndrho_ndrho(ip) = e_rho_ndrho_ndrho(ip) &
484 - 2.0_dp*fvw/(rho(ip)*rho(ip))
489 END SUBROUTINE tfw_u_3
499 SUBROUTINE tfw_p_0(rhoa, r13a, sa, e_0, npoints)
501 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, r13a, sa
502 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_0
503 INTEGER,
INTENT(in) :: npoints
511 IF (rhoa(ip) > eps_rho)
THEN
512 e_0(ip) = e_0(ip) + flsd*r13a(ip)*r13a(ip)*rhoa(ip) + fvw*sa(ip)
517 END SUBROUTINE tfw_p_0
529 SUBROUTINE tfw_p_1(rhoa, grhoa, r13a, sa, e_rho, e_ndrho, npoints)
531 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, grhoa, r13a, sa
532 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho, e_ndrho
533 INTEGER,
INTENT(in) :: npoints
544 IF (rhoa(ip) > eps_rho)
THEN
545 e_rho(ip) = e_rho(ip) + f*r13a(ip)*r13a(ip) - fvw*sa(ip)/rhoa(ip)
546 e_ndrho(ip) = e_ndrho(ip) + 2.0_dp*fvw*grhoa(ip)/rhoa(ip)
551 END SUBROUTINE tfw_p_1
564 SUBROUTINE tfw_p_2(rhoa, grhoa, r13a, sa, e_rho_rho, e_rho_ndrho, &
565 e_ndrho_ndrho, npoints)
567 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, grhoa, r13a, sa
568 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho_rho, e_rho_ndrho, e_ndrho_ndrho
569 INTEGER,
INTENT(in) :: npoints
580 IF (rhoa(ip) > eps_rho)
THEN
581 e_rho_rho(ip) = e_rho_rho(ip) &
582 + f/r13a(ip) + 2.0_dp*fvw*sa(ip)/(rhoa(ip)*rhoa(ip))
583 e_rho_ndrho(ip) = e_rho_ndrho(ip) &
584 - 2.0_dp*fvw*grhoa(ip)/(rhoa(ip)*rhoa(ip))
585 e_ndrho_ndrho(ip) = e_ndrho_ndrho(ip) + 2.0_dp*fvw/rhoa(ip)
590 END SUBROUTINE tfw_p_2
603 SUBROUTINE tfw_p_3(rhoa, grhoa, r13a, sa, e_rho_rho_rho, e_rho_rho_ndrho, &
604 e_rho_ndrho_ndrho, npoints)
606 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: rhoa, grhoa, r13a, sa
607 REAL(kind=
dp),
DIMENSION(*),
INTENT(INOUT) :: e_rho_rho_rho, e_rho_rho_ndrho, &
609 INTEGER,
INTENT(in) :: npoints
614 f = -f13*f23*f53*flsd
620 IF (rhoa(ip) > eps_rho)
THEN
621 e_rho_rho_rho(ip) = e_rho_rho_rho(ip) &
622 + f/(r13a(ip)*rhoa(ip)) &
623 - 6.0_dp*fvw*sa(ip)/(rhoa(ip)*rhoa(ip)*rhoa(ip))
624 e_rho_rho_ndrho(ip) = e_rho_rho_ndrho(ip) &
625 + 4.0_dp*fvw*grhoa(ip)/(rhoa(ip)*rhoa(ip)*rhoa(ip))
626 e_rho_ndrho_ndrho(ip) = e_rho_ndrho_ndrho(ip) &
627 - 2.0_dp*fvw/(rhoa(ip)*rhoa(ip))
632 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
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_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)
...
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