(git:e7e05ae)
xc_hcth.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief calculate the Hamprecht, Cohen, Tozer, and Handy (HCTH) exchange
10 !> functional
11 !> \author fawzi
12 ! **************************************************************************************************
13 MODULE xc_hcth
14 
15  USE cp_log_handling, ONLY: cp_to_string
16  USE kinds, ONLY: dp
17  USE mathconstants, ONLY: pi
19  deriv_rho
20  USE xc_derivative_set_types, ONLY: xc_derivative_set_type,&
23  xc_derivative_type
24  USE xc_rho_cflags_types, ONLY: xc_rho_cflags_type
25  USE xc_rho_set_types, ONLY: xc_rho_set_get,&
26  xc_rho_set_type
27 #include "../base/base_uses.f90"
28 
29  IMPLICIT NONE
30  PRIVATE
31 
32  LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
33  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_hcth'
34 
35  PUBLIC :: hcth_lda_info, hcth_lda_eval
36 CONTAINS
37 
38 ! **************************************************************************************************
39 !> \brief return various information on the functional
40 !> \param iparset ...
41 !> \param reference string with the reference of the actual functional
42 !> \param shortform string with the shortform of the functional name
43 !> \param needs the components needed by this functional are set to
44 !> true (does not set the unneeded components to false)
45 !> \param max_deriv ...
46 !> \author fawzi
47 ! **************************************************************************************************
48  SUBROUTINE hcth_lda_info(iparset, reference, shortform, needs, max_deriv)
49  INTEGER, INTENT(in) :: iparset
50  CHARACTER(LEN=*), INTENT(OUT), OPTIONAL :: reference, shortform
51  TYPE(xc_rho_cflags_type), INTENT(inout), OPTIONAL :: needs
52  INTEGER, INTENT(out), OPTIONAL :: max_deriv
53 
54  SELECT CASE (iparset)
55  CASE (93)
56  IF (PRESENT(reference)) THEN
57  reference = "F. A. Hamprecht, A. J. Cohen, D. J. Tozer, and N. C. Handy, J. Chem. Phys. 109, 6264 (1998);"// &
58  " HCTH/93 xc functional {LDA version}"
59  END IF
60  IF (PRESENT(shortform)) THEN
61  shortform = "HCTH/93 xc energy functional (LDA)"
62  END IF
63  CASE (120)
64  IF (PRESENT(reference)) THEN
65  reference = "A. D. Boese, N. L. Doltsinis, N. C. Handy, and M. Sprik, J. Chem. Phys. 112, 1670 (2000);"// &
66  " HCTH/120 xc functional {LDA version}"
67  END IF
68  IF (PRESENT(shortform)) THEN
69  shortform = "HCTH/120 xc energy functional (LDA)"
70  END IF
71  CASE (147)
72  IF (PRESENT(reference)) THEN
73  reference = "A. D. Boese, N. L. Doltsinis, N. C. Handy, and M. Sprik, J. Chem. Phys. 112, 1670 (2000);"// &
74  " HCTH/147 xc functional {LDA Version}"
75  END IF
76  IF (PRESENT(shortform)) THEN
77  shortform = "HCTH/147 xc energy functional (LDA)"
78  END IF
79  CASE (407)
80  IF (PRESENT(reference)) THEN
81  reference = "A. D. Boese and N. C. Handy, J. Chem. Phys. 114, 5497 (2001); "// &
82  "HCTH/407 xc functional {LDA version}"
83  END IF
84  IF (PRESENT(shortform)) THEN
85  shortform = "HCTH/407 xc energy functional (LDA)"
86  END IF
87  CASE (408)
88  IF (PRESENT(reference)) THEN
89  reference = "P. Verma and D. G. Truhlar, J. Phys. Chem. Lett. 8, 380 (2016); "// &
90  "HLE16 xc functional {LDA version}"
91  END IF
92  IF (PRESENT(shortform)) THEN
93  shortform = "HLE16 xc energy functional (LDA)"
94  END IF
95  CASE default
96  cpabort("Invalid HCTH parameter set requested ("//cp_to_string(iparset)//")")
97  END SELECT
98  IF (PRESENT(needs)) THEN
99  needs%rho = .true.
100  needs%norm_drho = .true.
101  END IF
102  IF (PRESENT(max_deriv)) max_deriv = 1
103 
104  END SUBROUTINE hcth_lda_info
105 
106 ! **************************************************************************************************
107 !> \brief evaluates the hcth functional for lda
108 !> \param iparset the parameter set that should be used (93,120,147,407)
109 !> \param rho_set the density where you want to evaluate the functional
110 !> \param deriv_set place where to store the functional derivatives (they are
111 !> added to the derivatives)
112 !> \param grad_deriv degree of the derivative that should be evaluated,
113 !> if positive all the derivatives up to the given degree are evaluated,
114 !> if negative only the given degree is calculated
115 !> \author fawzi
116 ! **************************************************************************************************
117  SUBROUTINE hcth_lda_eval(iparset, rho_set, deriv_set, grad_deriv)
118  INTEGER, INTENT(in) :: iparset
119  TYPE(xc_rho_set_type), INTENT(IN) :: rho_set
120  TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set
121  INTEGER, INTENT(in) :: grad_deriv
122 
123  INTEGER :: npoints
124  INTEGER, DIMENSION(2, 3) :: bo
125  REAL(kind=dp) :: epsilon_rho
126  REAL(kind=dp), CONTIGUOUS, DIMENSION(:, :, :), &
127  POINTER :: e_0, e_ndrho, e_rho, norm_drho, rho
128  TYPE(xc_derivative_type), POINTER :: deriv
129 
130  NULLIFY (e_0, e_ndrho, e_rho, norm_drho, rho)
131 
132  CALL xc_rho_set_get(rho_set, rho=rho, &
133  norm_drho=norm_drho, local_bounds=bo, rho_cutoff=epsilon_rho)
134  npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
135 
136  IF (grad_deriv >= 0) THEN
137  deriv => xc_dset_get_derivative(deriv_set, [INTEGER::], &
138  allocate_deriv=.true.)
139  CALL xc_derivative_get(deriv, deriv_data=e_0)
140  END IF
141  deriv => xc_dset_get_derivative(deriv_set, [deriv_rho], &
142  allocate_deriv=.true.)
143  CALL xc_derivative_get(deriv, deriv_data=e_rho)
144  deriv => xc_dset_get_derivative(deriv_set, [deriv_norm_drho], &
145  allocate_deriv=.true.)
146  CALL xc_derivative_get(deriv, deriv_data=e_ndrho)
147  IF (grad_deriv > 1 .OR. grad_deriv < -1) THEN
148  cpabort("derivatives bigger than 1 not implemented")
149  END IF
150 
151  CALL hcth_lda_calc(iparset=iparset, rho=rho, norm_drho=norm_drho, &
152  e_0=e_0, e_rho=e_rho, e_ndrho=e_ndrho, &
153  npoints=npoints, epsilon_rho=epsilon_rho)
154  END SUBROUTINE hcth_lda_eval
155 
156 ! **************************************************************************************************
157 !> \brief Calculate the gradient-corrected xc energy and potential
158 !> of Hamprecht, Cohen, Tozer, and Handy (HCTH) for a closed shell
159 !> density.
160 !> \param iparset the parameter set that should be used (93,120,147,407)
161 !> \param rho the density
162 !> \param norm_drho the norm of the gradient of the density
163 !> \param e_0 the value of the functional in that point
164 !> \param e_rho the derivative of the functional wrt. rho
165 !> \param e_ndrho the derivative of the functional wrt. norm_drho
166 !> \param epsilon_rho the cutoff on rho
167 !> \param npoints ...
168 !> \author fawzi (copying from the routine of Matthias Krack in functionals.F)
169 !> \note
170 !> Literature:- F. A. Hamprecht, A. J. Cohen, D. J. Tozer, and N. C. Handy,
171 !> J. Chem. Phys. 109, 6264 (1998) -> HCTH/93
172 !> - A. D. Boese, N. L. Doltsinis, N. C. Handy, and M. Sprik,
173 !> J. Chem. Phys. 112, 1670 (2000) -> HCTH/120 and HCTH/147
174 !> - A. D. Boese and N. C. Handy,
175 !> J. Chem. Phys. 114, 5497 (2001) -> HCTH/407
176 !> - J. P. Perdew and Y. Wang,
177 !> Phys. Rev. B 45, 13244 (1992) -> PW92
178 ! **************************************************************************************************
179  SUBROUTINE hcth_lda_calc(iparset, rho, norm_drho, e_0, e_rho, e_ndrho, &
180  epsilon_rho, npoints)
181  INTEGER, INTENT(IN) :: iparset
182  REAL(kind=dp), DIMENSION(*), INTENT(IN) :: rho, norm_drho
183  REAL(kind=dp), DIMENSION(*), INTENT(INOUT) :: e_0, e_rho, e_ndrho
184  REAL(kind=dp), INTENT(in) :: epsilon_rho
185  INTEGER, INTENT(IN) :: npoints
186 
187  REAL(kind=dp), DIMENSION(4), PARAMETER :: &
188  beta0 = (/7.59570_dp, 3.58760_dp, 1.63820_dp, 0.49294_dp/), &
189  beta1 = (/14.11890_dp, 6.19770_dp, 3.36620_dp, 0.62517_dp/)
190  REAL(kind=dp), PARAMETER :: a0 = 0.031091_dp, a1 = 0.015545_dp, alpha0 = 0.21370_dp, &
191  alpha1 = 0.20548_dp, f13 = 1.0_dp/3.0_dp, f43 = 4.0_dp*f13, f83 = 8.0_dp*f13, &
192  gamma_cab = 0.006_dp, gamma_css = 0.200_dp, gamma_xss = 0.004_dp
193 
194  INTEGER :: ii
195  REAL(kind=dp) :: cx_vwn_e, cx_vwn_v, dgcabddrho, dgcabdrho, dgcabds, dgcssddrho, dgcssdrho, &
196  dgcssds, dgdrs, dgxssddrho, dgxssdrho, dgxssds, drho, drhos, drsdrho, ecab, ecss, exss, &
197  g, gcab, gcss, gs2, gxss, my_rho, p, q, rho13, rho43, rhos, rhos13, rhos43, rs, rs12, &
198  rsfac, s, s2, two13, u, vcab, vcss, vxss, x, y
199  REAL(kind=dp), DIMENSION(0:4) :: ccab, ccss, cxss
200 
201  cx_vwn_e = -0.75_dp*(3.0_dp/pi)**f13
202  cx_vwn_v = f43*cx_vwn_e
203  rsfac = (f43*pi)**(-f13)
204  two13 = 2.0_dp**f13
205 
206  ! *** LSDA correlation parametrisation (PW92) ***
207  ! *** GGA parametrisation (HCTH/iparset) ***
208 
209  ! *** Load the HCTH parameter set HCTH/iparset ***
210 
211  SELECT CASE (iparset)
212  CASE (93)
213  cxss(0) = 0.109320e+01_dp
214  ccss(0) = 0.222601e+00_dp
215  ccab(0) = 0.729974e+00_dp
216  cxss(1) = -0.744056e+00_dp
217  ccss(1) = -0.338622e-01_dp
218  ccab(1) = 0.335287e+01_dp
219  cxss(2) = 0.559920e+01_dp
220  ccss(2) = -0.125170e-01_dp
221  ccab(2) = -0.115430e+02_dp
222  cxss(3) = -0.678549e+01_dp
223  ccss(3) = -0.802496e+00_dp
224  ccab(3) = 0.808564e+01_dp
225  cxss(4) = 0.449357e+01_dp
226  ccss(4) = 0.155396e+01_dp
227  ccab(4) = -0.447857e+01_dp
228  CASE (120)
229  cxss(0) = 0.109163e+01_dp
230  ccss(0) = 0.489508e+00_dp
231  ccab(0) = 0.514730e+00_dp
232  cxss(1) = -0.747215e+00_dp
233  ccss(1) = -0.260699e+00_dp
234  ccab(1) = 0.692982e+01_dp
235  cxss(2) = 0.507833e+01_dp
236  ccss(2) = 0.432917e+00_dp
237  ccab(2) = -0.247073e+02_dp
238  cxss(3) = -0.410746e+01_dp
239  ccss(3) = -0.199247e+01_dp
240  ccab(3) = 0.231098e+02_dp
241  cxss(4) = 0.117173e+01_dp
242  ccss(4) = 0.248531e+01_dp
243  ccab(4) = -0.113234e+02_dp
244  CASE (147)
245  cxss(0) = 0.109025e+01_dp
246  ccss(0) = 0.562576e+00_dp
247  ccab(0) = 0.542352e+00_dp
248  cxss(1) = -0.799194e+00_dp
249  ccss(1) = 0.171436e-01_dp
250  ccab(1) = 0.701464e+01_dp
251  cxss(2) = 0.557212e+01_dp
252  ccss(2) = -0.130636e+01_dp
253  ccab(2) = -0.283822e+02_dp
254  cxss(3) = -0.586760e+01_dp
255  ccss(3) = 0.105747e+01_dp
256  ccab(3) = 0.350329e+02_dp
257  cxss(4) = 0.304544e+01_dp
258  ccss(4) = 0.885429e+00_dp
259  ccab(4) = -0.204284e+02_dp
260  CASE (407)
261  cxss(0) = 0.108184e+01_dp
262  ccss(0) = 0.118777e+01_dp
263  ccab(0) = 0.589076e+00_dp
264  cxss(1) = -0.518339e+00_dp
265  ccss(1) = -0.240292e+01_dp
266  ccab(1) = 0.442374e+01_dp
267  cxss(2) = 0.342562e+01_dp
268  ccss(2) = 0.561741e+01_dp
269  ccab(2) = -0.192218e+02_dp
270  cxss(3) = -0.262901e+01_dp
271  ccss(3) = -0.917923e+01_dp
272  ccab(3) = 0.425721e+02_dp
273  cxss(4) = 0.228855e+01_dp
274  ccss(4) = 0.624798e+01_dp
275  ccab(4) = -0.420052e+02_dp
276 ! DMB all-in-one HLE16 and applying 5/4 scaling
277 ! to all exchange terms and 1/2 to all correlation terms
278  CASE (408)
279  cxss(0) = 0.108184e+01_dp*1.25_dp
280  ccss(0) = 0.118777e+01_dp*0.5_dp
281  ccab(0) = 0.589076e+00_dp*0.5_dp
282  cxss(1) = -0.518339e+00_dp*1.25_dp
283  ccss(1) = -0.240292e+01_dp*0.5_dp
284  ccab(1) = 0.442374e+01_dp*0.5_dp
285  cxss(2) = 0.342562e+01_dp*1.25_dp
286  ccss(2) = 0.561741e+01_dp*0.5_dp
287  ccab(2) = -0.192218e+02_dp*0.5_dp
288  cxss(3) = -0.262901e+01_dp*1.25_dp
289  ccss(3) = -0.917923e+01_dp*0.5_dp
290  ccab(3) = 0.425721e+02_dp*0.5_dp
291  cxss(4) = 0.228855e+01_dp*1.25_dp
292  ccss(4) = 0.624798e+01_dp*0.5_dp
293  ccab(4) = -0.420052e+02_dp*0.5_dp
294  CASE DEFAULT
295  cpabort("Invalid HCTH parameter set requested ("//cp_to_string(iparset)//")")
296  END SELECT
297 
298 !$OMP PARALLEL DO DEFAULT(NONE) SHARED(rho,norm_drho,cxss,ccss,&
299 !$OMP ccab,cx_vwn_e, cx_vwn_v, rsfac, two13,epsilon_rho,npoints, &
300 !$OMP e_0,e_rho,e_ndrho)&
301 !$OMP PRIVATE(ii, dgcabddrho, dgcabdrho, dgcabds, dgcssddrho, &
302 !$OMP dgcssdrho, dgcssds, dgdrs, dgxssddrho, dgxssdrho, dgxssds,&
303 !$OMP drhos, drsdrho, ecab, ecss, exss, g, gcab, gcss, gs2, &
304 !$OMP gxss, p, q, rho13, rho43, rhos, rhos13, rhos43, rs, rs12,&
305 !$OMP s, s2, u, vcab, vcss, vxss, x, y, my_rho, drho)
306  DO ii = 1, npoints
307  ! *** rho_sigma = rho/2 = rho_alpha = rho_beta (same for |nabla rho|) ***
308 
309  IF (rho(ii) > epsilon_rho) THEN
310  my_rho = max(rho(ii), epsilon_rho)
311  drho = norm_drho(ii)
312  rhos = 0.5_dp*my_rho
313  drhos = 0.5_dp*drho
314 
315  rhos13 = rhos**f13
316  rhos43 = rhos13*rhos
317 
318  rho13 = two13*rhos13
319  rho43 = rho13*my_rho
320 
321  ! *** LSDA exchange part (VWN) ***
322 
323  exss = cx_vwn_e*rho43
324  vxss = cx_vwn_v*rho13
325 
326  ! *** LSDA correlation part (PW92) ***
327 
328  ! *** G(rho_sigma,0) => spin polarisation zeta = 1 ***
329 
330  rs = rsfac/rhos13
331  rs12 = sqrt(rs)
332  q = 2.0_dp*a1*(beta1(1) + (beta1(2) + (beta1(3) + &
333  beta1(4)*rs12)*rs12)*rs12)*rs12
334  p = 1.0_dp + 1.0_dp/q
335  x = -2.0_dp*a1*(1.0_dp + alpha1*rs)
336  y = log(p)
337  g = x*y
338  dgdrs = -2.0_dp*a1*alpha1*y - &
339  x*a1*(beta1(1)/rs12 + 2.0_dp*beta1(2) + &
340  3.0_dp*beta1(3)*rs12 + 4.0_dp*beta1(4)*rs)/(p*q*q)
341  drsdrho = -f13*rs/my_rho
342  ecss = my_rho*g
343  vcss = g + my_rho*dgdrs*drsdrho
344 
345  ! *** G(rho_alpha,rho_beta) => spin polarisation zeta = 0 ***
346 
347  rs = rsfac/rho13
348  rs12 = sqrt(rs)
349  q = 2.0_dp*a0*(beta0(1) + (beta0(2) + (beta0(3) + &
350  beta0(4)*rs12)*rs12)*rs12)*rs12
351  p = 1.0_dp + 1.0_dp/q
352  x = -2.0_dp*a0*(1.0_dp + alpha0*rs)
353  y = log(p)
354  g = x*y
355  dgdrs = -2.0_dp*a0*alpha0*y - &
356  x*a0*(beta0(1)/rs12 + 2.0_dp*beta0(2) + &
357  3.0_dp*beta0(3)*rs12 + 4.0_dp*beta0(4)*rs)/(p*q*q)
358  drsdrho = -f13*rs/my_rho
359  ecab = my_rho*g - ecss
360  vcab = g + my_rho*dgdrs*drsdrho - vcss
361 
362  ! *** GGA part (HCTH) ***
363 
364  s = drhos/rhos43
365  s2 = s*s
366  x = -f83/my_rho
367  y = 2.0_dp/(drho*drho)
368 
369  ! *** g_x(rho_sigma,rho_sigma) ***
370 
371  gs2 = gamma_xss*s2
372  q = 1.0_dp/(1.0_dp + gs2)
373  u = gs2*q
374  gxss = cxss(0) + (cxss(1) + (cxss(2) + (cxss(3) + cxss(4)*u)*u)*u)*u
375  dgxssds = q*(cxss(1) + (2.0_dp*cxss(2) + (3.0_dp*cxss(3) + &
376  4.0_dp*cxss(4)*u)*u)*u)*u
377  dgxssdrho = x*dgxssds
378  dgxssddrho = y*dgxssds
379 
380  ! *** g_c(rho_sigma,rho_sigma) ***
381 
382  gs2 = gamma_css*s2
383  q = 1.0_dp/(1.0_dp + gs2)
384  u = gs2*q
385  gcss = ccss(0) + (ccss(1) + (ccss(2) + (ccss(3) + ccss(4)*u)*u)*u)*u
386  dgcssds = q*(ccss(1) + (2.0_dp*ccss(2) + (3.0_dp*ccss(3) + &
387  4.0_dp*ccss(4)*u)*u)*u)*u
388  dgcssdrho = x*dgcssds
389  dgcssddrho = y*dgcssds
390 
391  ! *** g_c(rho_alpha,rho_beta) ***
392 
393  gs2 = gamma_cab*s2
394  q = 1.0_dp/(1.0_dp + gs2)
395  u = gs2*q
396  gcab = ccab(0) + (ccab(1) + (ccab(2) + (ccab(3) + ccab(4)*u)*u)*u)*u
397  dgcabds = q*(ccab(1) + (2.0_dp*ccab(2) + (3.0_dp*ccab(3) + &
398  4.0_dp*ccab(4)*u)*u)*u)*u
399  dgcabdrho = x*dgcabds
400  dgcabddrho = y*dgcabds
401 
402  ! *** Finally collect all contributions ***
403 
404  e_0(ii) = e_0(ii) + exss*gxss + ecss*gcss + ecab*gcab
405  e_rho(ii) = e_rho(ii) + vxss*gxss + exss*dgxssdrho + &
406  vcss*gcss + ecss*dgcssdrho + &
407  vcab*gcab + ecab*dgcabdrho
408  e_ndrho(ii) = e_ndrho(ii) + (exss*dgxssddrho + ecss*dgcssddrho + ecab*dgcabddrho)*drho
409  END IF
410  END DO
411 
412  END SUBROUTINE hcth_lda_calc
413 
414 END MODULE xc_hcth
various routines to log and control the output. The idea is that decisions about where to log should ...
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
Definition of mathematical constants and functions.
Definition: mathconstants.F:16
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_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
calculate the Hamprecht, Cohen, Tozer, and Handy (HCTH) exchange functional
Definition: xc_hcth.F:13
subroutine, public hcth_lda_info(iparset, reference, shortform, needs, max_deriv)
return various information on the functional
Definition: xc_hcth.F:49
subroutine, public hcth_lda_eval(iparset, rho_set, deriv_set, grad_deriv)
evaluates the hcth functional for lda
Definition: xc_hcth.F:118
contains the structure
contains the structure
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