53 #include "../base/base_uses.f90"
58 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
59 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xc_xbr_pbe_lda_hole_t_c_lr'
61 REAL(dp),
PARAMETER,
PRIVATE :: br_a1 = 1.5255251812009530_dp, &
62 br_a2 = 0.4576575543602858_dp, &
63 br_a3 = 0.4292036732051034_dp, &
64 br_c0 = 0.7566445420735584_dp, &
65 br_c1 = -2.6363977871370960_dp, &
66 br_c2 = 5.4745159964232880_dp, &
67 br_c3 = -12.657308127108290_dp, &
68 br_c4 = 4.1250584725121360_dp, &
69 br_c5 = -30.425133957163840_dp, &
70 br_b0 = 0.4771976183772063_dp, &
71 br_b1 = -1.7799813494556270_dp, &
72 br_b2 = 3.8433841862302150_dp, &
73 br_b3 = -9.5912050880518490_dp, &
74 br_b4 = 2.1730180285916720_dp, &
75 br_b5 = -30.425133851603660_dp, &
76 br_d0 = 0.00004435009886795587_dp, &
77 br_d1 = 0.58128653604457910_dp, &
78 br_d2 = 66.742764515940610_dp, &
79 br_d3 = 434.26780897229770_dp, &
80 br_d4 = 824.7765766052239000_dp, &
81 br_d5 = 1657.9652731582120_dp, &
82 br_e0 = 0.00003347285060926091_dp, &
83 br_e1 = 0.47917931023971350_dp, &
84 br_e2 = 62.392268338574240_dp, &
85 br_e3 = 463.14816427938120_dp, &
86 br_e4 = 785.2360350104029000_dp, &
87 br_e5 = 1657.962968223273000000_dp, &
88 br_bb = 2.085749716493756_dp
90 REAL(dp),
PARAMETER,
PRIVATE :: smax = 8.572844_dp, &
92 sconst = 18.79622316_dp, &
95 REAL(dp),
PARAMETER,
PRIVATE :: alpha = 0.3956891_dp, &
96 n = -0.0009800242_dp, &
115 CHARACTER(LEN=*),
INTENT(OUT),
OPTIONAL :: reference, shortform
116 TYPE(xc_rho_cflags_type),
INTENT(inout),
OPTIONAL :: needs
117 INTEGER,
INTENT(out),
OPTIONAL :: max_deriv
119 IF (
PRESENT(reference))
THEN
120 reference =
"{LDA version}"
122 IF (
PRESENT(shortform))
THEN
126 IF (
PRESENT(needs))
THEN
128 needs%norm_drho = .true.
130 needs%laplace_rho = .true.
133 IF (
PRESENT(max_deriv)) max_deriv = 1
147 CHARACTER(LEN=*),
INTENT(OUT),
OPTIONAL :: reference, shortform
148 TYPE(xc_rho_cflags_type),
INTENT(inout),
OPTIONAL :: needs
149 INTEGER,
INTENT(out),
OPTIONAL :: max_deriv
151 IF (
PRESENT(reference))
THEN
152 reference =
"{LDA version}"
154 IF (
PRESENT(shortform))
THEN
158 IF (
PRESENT(needs))
THEN
159 needs%rho_spin = .true.
160 needs%norm_drho_spin = .true.
161 needs%tau_spin = .true.
162 needs%laplace_rho_spin = .true.
164 IF (
PRESENT(max_deriv)) max_deriv = 1
180 TYPE(xc_rho_set_type),
INTENT(IN) :: rho_set
181 TYPE(xc_derivative_set_type),
INTENT(IN) :: deriv_set
182 INTEGER,
INTENT(in) :: grad_deriv
183 TYPE(section_vals_type),
POINTER :: params
185 CHARACTER(len=*),
PARAMETER :: routinen =
'xbr_pbe_lda_hole_tc_lr_lda_eval'
187 INTEGER :: handle, npoints
188 INTEGER,
DIMENSION(2, 3) :: bo
189 REAL(dp) ::
gamma, r, sx
190 REAL(kind=dp) :: epsilon_rho
191 REAL(kind=dp),
CONTIGUOUS,
DIMENSION(:, :, :), &
192 POINTER :: dummy, e_0, e_laplace_rho, e_ndrho, &
193 e_rho, e_tau, laplace_rho, norm_drho, &
195 TYPE(xc_derivative_type),
POINTER :: deriv
197 CALL timeset(routinen, handle)
200 tau=tau, laplace_rho=laplace_rho, local_bounds=bo, &
201 rho_cutoff=epsilon_rho)
202 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
210 e_laplace_rho => dummy
212 IF (grad_deriv >= 0)
THEN
214 allocate_deriv=.true.)
217 IF (grad_deriv >= 1 .OR. grad_deriv == -1)
THEN
219 allocate_deriv=.true.)
222 allocate_deriv=.true.)
225 allocate_deriv=.true.)
228 allocate_deriv=.true.)
231 IF (grad_deriv > 1 .OR. grad_deriv < -1)
THEN
232 cpabort(
"derivatives bigger than 1 not implemented")
239 IF (r == 0.0_dp)
THEN
240 cpabort(
"Cutoff_Radius 0.0 not implemented")
249 CALL xbr_pbe_lda_hole_tc_lr_lda_calc(rho=rho, norm_drho=norm_drho, &
250 laplace_rho=laplace_rho, tau=tau, e_0=e_0, e_rho=e_rho, e_ndrho=e_ndrho, &
251 e_tau=e_tau, e_laplace_rho=e_laplace_rho, grad_deriv=grad_deriv, &
252 npoints=npoints, epsilon_rho=epsilon_rho, sx=sx, r=r,
gamma=
gamma)
256 CALL timestop(handle)
281 SUBROUTINE xbr_pbe_lda_hole_tc_lr_lda_calc(rho, norm_drho, laplace_rho, tau, e_0, e_rho, &
282 e_ndrho, e_tau, e_laplace_rho, grad_deriv, npoints, &
283 epsilon_rho, sx, R, gamma)
285 INTEGER,
INTENT(in) :: npoints, grad_deriv
286 REAL(kind=dp),
DIMENSION(1:npoints),
INTENT(inout) :: e_laplace_rho, e_tau, e_ndrho, e_rho, e_0
287 REAL(kind=dp),
DIMENSION(1:npoints),
INTENT(in) :: tau, laplace_rho, norm_drho, rho
288 REAL(kind=dp),
INTENT(in) :: epsilon_rho, sx, r,
gamma
291 REAL(dp) :: dfermi_dlaplace_rho, dfermi_dndrho, dfermi_drho, dfermi_dtau, e_0_br, e_0_lda, &
292 e_0_pbe, e_laplace_rho_br, e_ndrho_br, e_ndrho_pbe, e_rho_br, e_rho_lda, e_rho_pbe, &
293 e_tau_br, fermi, fx, my_laplace_rho, my_ndrho, my_rho, my_tau, ss, ss2, sscale, t1, t15, &
294 t16, t2, t3, t4, t5, t6, t7, t8, t9, yval
299 my_rho = 0.5_dp*max(rho(ip), 0.0_dp)
300 IF (my_rho > epsilon_rho)
THEN
301 my_ndrho = 0.5_dp*max(norm_drho(ip), epsilon(0.0_dp)*1.e4_dp)
302 my_tau = 0.5_dp*max(epsilon(0.0_dp)*1.e4_dp, tau(ip))
303 my_laplace_rho = 0.5_dp*laplace_rho(ip)
306 t1 =
pi**(0.1e1_dp/0.3e1_dp)
308 t3 = my_rho**(0.1e1_dp/0.3e1_dp)
313 t15 = my_laplace_rho/0.6e1_dp -
gamma*(2.0_dp*my_tau - t8*t9/0.4e1_dp)/0.3e1_dp
315 yval = 0.2e1_dp/0.3e1_dp*t2*t5*t16
321 e_laplace_rho_br = 0.0_dp
323 IF (r == 0.0_dp)
THEN
324 IF (yval <= 0.0_dp)
THEN
326 e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
327 sx,
gamma, grad_deriv)
329 e_0_br = 2.0_dp*e_0_br
331 CALL x_br_lsd_y_gt_0(my_rho, my_ndrho, my_tau, my_laplace_rho, e_0_br, &
332 e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
333 sx,
gamma, grad_deriv)
335 e_0_br = 2.0_dp*e_0_br
338 IF (yval <= 0.0_dp)
THEN
340 e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
341 sx, r,
gamma, grad_deriv)
343 e_0_br = 2.0_dp*e_0_br
346 e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
347 sx, r,
gamma, grad_deriv)
349 e_0_br = 2.0_dp*e_0_br
355 my_rho = my_rho*2.0_dp
356 my_ndrho = my_ndrho*2.0_dp
362 t3 = t2**(0.1e1_dp/0.3e1_dp)
367 ss = 0.3466806371753173524216762e0_dp*t6*t8
368 IF (ss > scutoff)
THEN
370 sscale = (smax*ss2 - sconst)/(ss2*ss)
375 IF (ss*sscale > gcutoff)
THEN
378 my_ndrho, sscale, sx, r, grad_deriv)
382 my_ndrho, sscale, sx, r, grad_deriv)
394 fermi = alpha/(exp((fx - mu)/n) + 1.0_dp)
396 dfermi_drho = -fermi**2/alpha/n*(e_rho_br/e_0_lda - e_0_br*e_rho_lda/e_0_lda**2)*exp((fx - mu)/n)
397 dfermi_dndrho = -fermi**2/alpha/n*(e_ndrho_br/e_0_lda)*exp((fx - mu)/n)
398 dfermi_dtau = -fermi**2/alpha/n*(e_tau_br/e_0_lda)*exp((fx - mu)/n)
399 dfermi_dlaplace_rho = -fermi**2/alpha/n*(e_laplace_rho_br/e_0_lda)*exp((fx - mu)/n)
401 e_0(ip) = e_0(ip) + (fermi*e_0_pbe + (1.0_dp - fermi)*e_0_br)*sx
403 IF (grad_deriv >= 1 .OR. grad_deriv == -1)
THEN
405 e_rho(ip) = e_rho(ip) + (fermi*e_rho_pbe + dfermi_drho*e_0_pbe + &
406 (1.0_dp - fermi)*e_rho_br - dfermi_drho*e_0_br)*sx
408 e_ndrho(ip) = e_ndrho(ip) + (fermi*e_ndrho_pbe + dfermi_dndrho*e_0_pbe + &
409 (1.0_dp - fermi)*e_ndrho_br - dfermi_dndrho*e_0_br)*sx
411 e_tau(ip) = e_tau(ip) + (dfermi_dtau*e_0_pbe + &
412 (1.0_dp - fermi)*e_tau_br - dfermi_dtau*e_0_br)*sx
414 e_laplace_rho(ip) = e_laplace_rho(ip) + (dfermi_dlaplace_rho*e_0_pbe + &
415 (1.0_dp - fermi)*e_laplace_rho_br - dfermi_dlaplace_rho*e_0_br)*sx
423 END SUBROUTINE xbr_pbe_lda_hole_tc_lr_lda_calc
437 TYPE(xc_rho_set_type),
INTENT(IN) :: rho_set
438 TYPE(xc_derivative_set_type),
INTENT(IN) :: deriv_set
439 INTEGER,
INTENT(in) :: grad_deriv
440 TYPE(section_vals_type),
POINTER :: params
442 CHARACTER(len=*),
PARAMETER :: routinen =
'xbr_pbe_lda_hole_tc_lr_lsd_eval'
444 INTEGER :: handle, npoints
445 INTEGER,
DIMENSION(2, 3) :: bo
446 REAL(dp) ::
gamma, r, sx
447 REAL(kind=dp) :: epsilon_rho
448 REAL(kind=dp),
CONTIGUOUS,
DIMENSION(:, :, :),
POINTER :: dummy, e_0, e_laplace_rhoa, &
449 e_laplace_rhob, e_ndrhoa, e_ndrhob, e_rhoa, e_rhob, e_tau_a, e_tau_b, laplace_rhoa, &
450 laplace_rhob, norm_drhoa, norm_drhob, rhoa, rhob, tau_a, tau_b
451 TYPE(xc_derivative_type),
POINTER :: deriv
453 CALL timeset(routinen, handle)
455 CALL xc_rho_set_get(rho_set, rhoa=rhoa, rhob=rhob, norm_drhoa=norm_drhoa, &
456 norm_drhob=norm_drhob, tau_a=tau_a, tau_b=tau_b, laplace_rhoa=laplace_rhoa, &
457 laplace_rhob=laplace_rhob, local_bounds=bo, &
458 rho_cutoff=epsilon_rho)
459 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
470 e_laplace_rhoa => dummy
471 e_laplace_rhob => dummy
473 IF (grad_deriv >= 0)
THEN
475 allocate_deriv=.true.)
478 IF (grad_deriv >= 1 .OR. grad_deriv == -1)
THEN
480 allocate_deriv=.true.)
483 allocate_deriv=.true.)
487 allocate_deriv=.true.)
490 allocate_deriv=.true.)
494 allocate_deriv=.true.)
497 allocate_deriv=.true.)
501 allocate_deriv=.true.)
504 allocate_deriv=.true.)
507 IF (grad_deriv > 1 .OR. grad_deriv < -1)
THEN
508 cpabort(
"derivatives bigger than 1 not implemented")
515 IF (r == 0.0_dp)
THEN
516 cpabort(
"Cutoff_Radius 0.0 not implemented")
527 CALL xbr_pbe_lda_hole_tc_lr_lsd_calc(rho=rhoa, norm_drho=norm_drhoa, &
528 laplace_rho=laplace_rhoa, tau=tau_a, e_0=e_0, e_rho=e_rhoa, e_ndrho=e_ndrhoa, &
529 e_tau=e_tau_a, e_laplace_rho=e_laplace_rhoa, grad_deriv=grad_deriv, &
530 npoints=npoints, epsilon_rho=epsilon_rho, &
533 CALL xbr_pbe_lda_hole_tc_lr_lsd_calc(rho=rhob, norm_drho=norm_drhob, &
534 laplace_rho=laplace_rhob, tau=tau_b, e_0=e_0, e_rho=e_rhob, e_ndrho=e_ndrhob, &
535 e_tau=e_tau_b, e_laplace_rho=e_laplace_rhob, grad_deriv=grad_deriv, &
536 npoints=npoints, epsilon_rho=epsilon_rho, &
541 CALL timestop(handle)
565 SUBROUTINE xbr_pbe_lda_hole_tc_lr_lsd_calc(rho, norm_drho, laplace_rho, tau, e_0, e_rho, &
566 e_ndrho, e_tau, e_laplace_rho, grad_deriv, npoints, &
567 epsilon_rho, sx, R, gamma)
569 INTEGER,
INTENT(in) :: npoints, grad_deriv
570 REAL(kind=dp),
DIMENSION(1:npoints),
INTENT(inout) :: e_laplace_rho, e_tau, e_ndrho, e_rho, e_0
571 REAL(kind=dp),
DIMENSION(1:npoints),
INTENT(in) :: tau, laplace_rho, norm_drho, rho
572 REAL(kind=dp),
INTENT(in) :: epsilon_rho, sx, r,
gamma
575 REAL(dp) :: dfermi_dlaplace_rho, dfermi_dndrho, dfermi_drho, dfermi_dtau, e_0_br, e_0_lda, &
576 e_0_pbe, e_laplace_rho_br, e_ndrho_br, e_ndrho_pbe, e_rho_br, e_rho_lda, e_rho_pbe, &
577 e_tau_br, fermi, fx, my_laplace_rho, my_ndrho, my_rho, my_tau, ss, ss2, sscale, t1, t15, &
578 t16, t2, t3, t4, t5, t6, t7, t8, t9, yval
583 my_rho = max(rho(ip), 0.0_dp)
584 IF (my_rho > epsilon_rho)
THEN
585 my_ndrho = max(norm_drho(ip), epsilon(0.0_dp)*1.e4_dp)
586 my_tau = 1.0_dp*max(epsilon(0.0_dp)*1.e4_dp, tau(ip))
587 my_laplace_rho = 1.0_dp*laplace_rho(ip)
589 t1 =
pi**(0.1e1_dp/0.3e1_dp)
591 t3 = my_rho**(0.1e1_dp/0.3e1_dp)
596 t15 = my_laplace_rho/0.6e1_dp -
gamma*(2.0_dp*my_tau - t8*t9/0.4e1_dp)/0.3e1_dp
598 yval = 0.2e1_dp/0.3e1_dp*t2*t5*t16
604 e_laplace_rho_br = 0.0_dp
606 IF (r == 0.0_dp)
THEN
607 IF (yval <= 0.0_dp)
THEN
609 e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
610 sx,
gamma, grad_deriv)
612 CALL x_br_lsd_y_gt_0(my_rho, my_ndrho, my_tau, my_laplace_rho, e_0_br, &
613 e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
614 sx,
gamma, grad_deriv)
617 IF (yval <= 0.0_dp)
THEN
619 e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
620 sx, r,
gamma, grad_deriv)
623 e_rho_br, e_ndrho_br, e_tau_br, e_laplace_rho_br, &
624 sx, r,
gamma, grad_deriv)
630 my_rho = my_rho*2.0_dp
631 my_ndrho = my_ndrho*2.0_dp
637 t3 = t2**(0.1e1_dp/0.3e1_dp)
642 ss = 0.3466806371753173524216762e0_dp*t6*t8
643 IF (ss > scutoff)
THEN
645 sscale = (smax*ss2 - sconst)/(ss2*ss)
650 IF (ss*sscale > gcutoff)
THEN
653 my_ndrho, sscale, sx, r, grad_deriv)
657 my_ndrho, sscale, sx, r, grad_deriv)
660 e_0_pbe = 0.5_dp*e_0_pbe
668 e_0_lda = 0.5_dp*e_0_lda
672 fermi = alpha/(exp((fx - mu)/n) + 1.0_dp)
674 dfermi_drho = -fermi**2/alpha/n*(e_rho_br/e_0_lda - e_0_br*e_rho_lda/e_0_lda**2)*exp((fx - mu)/n)
675 dfermi_dndrho = -fermi**2/alpha/n*(e_ndrho_br/e_0_lda)*exp((fx - mu)/n)
676 dfermi_dtau = -fermi**2/alpha/n*(e_tau_br/e_0_lda)*exp((fx - mu)/n)
677 dfermi_dlaplace_rho = -fermi**2/alpha/n*(e_laplace_rho_br/e_0_lda)*exp((fx - mu)/n)
679 e_0(ip) = e_0(ip) + (fermi*e_0_pbe + (1.0_dp - fermi)*e_0_br)*sx
681 IF (grad_deriv >= 1 .OR. grad_deriv == -1)
THEN
683 e_rho(ip) = e_rho(ip) + (fermi*e_rho_pbe + dfermi_drho*e_0_pbe + &
684 (1.0_dp - fermi)*e_rho_br - dfermi_drho*e_0_br)*sx
686 e_ndrho(ip) = e_ndrho(ip) + (fermi*e_ndrho_pbe + dfermi_dndrho*e_0_pbe + &
687 (1.0_dp - fermi)*e_ndrho_br - dfermi_dndrho*e_0_br)*sx
689 e_tau(ip) = e_tau(ip) + (dfermi_dtau*e_0_pbe + &
690 (1.0_dp - fermi)*e_tau_br - dfermi_dtau*e_0_br)*sx
692 e_laplace_rho(ip) = e_laplace_rho(ip) + (dfermi_dlaplace_rho*e_0_pbe + &
693 (1.0_dp - fermi)*e_laplace_rho_br - dfermi_dlaplace_rho*e_0_br)*sx
701 END SUBROUTINE xbr_pbe_lda_hole_tc_lr_lsd_calc
Calculation of the incomplete Gamma function F_n(t) for multi-center integrals over Cartesian Gaussia...
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_laplace_rhob
integer, parameter, public deriv_norm_drhoa
integer, parameter, public deriv_rhob
integer, parameter, public deriv_rhoa
integer, parameter, public deriv_tau
integer, parameter, public deriv_tau_b
integer, parameter, public deriv_tau_a
integer, parameter, public deriv_laplace_rhoa
integer, parameter, public deriv_rho
integer, parameter, public deriv_norm_drhob
integer, parameter, public deriv_laplace_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
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
Calculates the exchange energy based on the Becke-Roussel exchange hole. Takes advantage of an analyt...
subroutine, public x_br_lsd_y_gt_0(rho, ndrho, tau, laplace_rho, e_0, e_rho, e_ndrho, e_tau, e_laplace_rho, sx, gamma, grad_deriv)
Full range evaluation for y > 0.
subroutine, public x_br_lsd_y_gt_0_cutoff(rho, ndrho, tau, laplace_rho, e_0, e_rho, e_ndrho, e_tau, e_laplace_rho, sx, R, gamma, grad_deriv)
Truncated long range part for y > 0.
subroutine, public x_br_lsd_y_lte_0(rho, ndrho, tau, laplace_rho, e_0, e_rho, e_ndrho, e_tau, e_laplace_rho, sx, gamma, grad_deriv)
full range evaluation for y <= 0
subroutine, public x_br_lsd_y_lte_0_cutoff(rho, ndrho, tau, laplace_rho, e_0, e_rho, e_ndrho, e_tau, e_laplace_rho, sx, R, gamma, grad_deriv)
Truncated long range part for y <= 0.
This functional is a combination of three different exchange hole models. The ingredients are:
subroutine, public xbr_pbe_lda_hole_tc_lr_lsd_eval(rho_set, deriv_set, grad_deriv, params)
Intermediate routine that gets grids, derivatives and some params.
subroutine, public xbr_pbe_lda_hole_tc_lr_lda_eval(rho_set, deriv_set, grad_deriv, params)
Intermediate routine that gets grids, derivatives and some params.
subroutine, public xbr_pbe_lda_hole_tc_lr_lda_info(reference, shortform, needs, max_deriv)
return various information on the functional
subroutine, public xbr_pbe_lda_hole_tc_lr_lsd_info(reference, shortform, needs, max_deriv)
return various information on the functional
Calculates the lda exchange hole in a truncated coulomb potential. Can be used as longrange correctio...
subroutine, public xlda_hole_t_c_lr_lda_calc_0(order, rho, e_0, e_rho, sx, R)
low level routine
Calculates the exchange energy for the pbe hole model in a truncated coulomb potential,...
elemental subroutine, public xpbe_hole_t_c_lr_lda_calc_2(e_0, e_rho, e_ndrho, rho, ndrho, sscale, sx, R, order)
low level routine that calculates the energy derivatives in one point
elemental subroutine, public xpbe_hole_t_c_lr_lda_calc_1(e_0, e_rho, e_ndrho, rho, ndrho, sscale, sx, R, order)
low level routine that calculates the energy derivatives in one point