(git:374b731)
Loading...
Searching...
No Matches
gamma.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 Calculation of the incomplete Gamma function F_n(t) for multi-center
10!> integrals over Cartesian Gaussian functions.
11!> \par History
12!> - restructured and cleaned (24.05.2004,MK)
13!> \author Matthias Krack (07.01.1999)
14! **************************************************************************************************
15MODULE gamma
16
17 USE kinds, ONLY: dp
18 USE mathconstants, ONLY: ifac,&
19 pi
20#include "../base/base_uses.f90"
21
22 IMPLICIT NONE
23
24 PRIVATE
25
26! *** Global parameters ***
27
28 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'gamma'
29 REAL(KIND=dp), PARAMETER :: teps = 1.0e-13_dp
30
31! *** Maximum n value of the tabulated F_n(t) function values ***
32
33 INTEGER, SAVE :: current_nmax = -1
34
35! *** F_n(t) table ***
36
37 REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE, SAVE :: ftable
38
39! *** Public subroutines ***
40
41 PUBLIC :: deallocate_md_ftable, &
42 fgamma_0, &
43 fgamma_ref, &
45
46CONTAINS
47
48! **************************************************************************************************
49!> \brief Build a table of F_n(t) values in the range tmin <= t <= tmax
50!> with a stepsize of tdelta up to n equal to nmax.
51!> \param nmax ...
52!> \param tmin ...
53!> \param tmax ...
54!> \param tdelta ...
55!> \date 11.01.1999
56!> \par Parameters
57!> - nmax : Maximum n value of F_n(t).
58!> - tdelta: Difference between two consecutive t abcissas (step size).
59!> - tmax : Maximum t value.
60!> - tmin : Minimum t value.
61!> \author MK
62!> \version 1.0
63! **************************************************************************************************
64 SUBROUTINE create_md_ftable(nmax, tmin, tmax, tdelta)
65
66 INTEGER, INTENT(IN) :: nmax
67 REAL(KIND=dp), INTENT(IN) :: tmin, tmax, tdelta
68
69 INTEGER :: itab, itabmax, itabmin, n
70 REAL(KIND=dp) :: t
71
72 IF (current_nmax > -1) THEN
73 CALL cp_abort(__location__, &
74 "An incomplete Gamma function table is already "// &
75 "allocated. Use the init routine for an update")
76 END IF
77
78 IF (nmax < 0) THEN
79 CALL cp_abort(__location__, &
80 "A negative n value for the initialization of the "// &
81 "incomplete Gamma function is invalid")
82 END IF
83
84! *** Check arguments ***
85
86 IF ((tmax < 0.0_dp) .OR. &
87 (tmin < 0.0_dp) .OR. &
88 (tdelta <= 0.0_dp) .OR. &
89 (tmin > tmax)) THEN
90 cpabort("Invalid arguments")
91 END IF
92
93 n = nmax + 6
94
95 itabmin = floor(tmin/tdelta)
96 itabmax = ceiling((tmax - tmin)/tdelta)
97
98 ALLOCATE (ftable(0:n, itabmin:itabmax))
99 ftable = 0.0_dp
100
101! *** Fill table ***
102
103 DO itab = itabmin, itabmax
104 t = real(itab, dp)*tdelta
105 ftable(0:n, itab) = fgamma_ref(n, t)
106 END DO
107
108! *** Save initialization status ***
109
110 current_nmax = nmax
111
112 END SUBROUTINE create_md_ftable
113
114! **************************************************************************************************
115!> \brief Deallocate the table of F_n(t) values.
116!> \date 24.05.2004
117!> \author MK
118!> \version 1.0
119! **************************************************************************************************
121
122 IF (current_nmax > -1) THEN
123
124 DEALLOCATE (ftable)
125
126 current_nmax = -1
127
128 END IF
129
130 END SUBROUTINE deallocate_md_ftable
131
132! **************************************************************************************************
133!> \brief Calculation of the incomplete Gamma function F(t) for multicenter
134!> integrals over Gaussian functions. f returns a vector with all
135!> F_n(t) values for 0 <= n <= nmax.
136!> \param nmax ...
137!> \param t ...
138!> \param f ...
139!> \date 08.01.1999,
140!> \par History
141!> 09.06.1999, MK : Changed from a FUNCTION to a SUBROUTINE
142!> \par Literature
143!> L. E. McMurchie, E. R. Davidson, J. Comp. Phys. 26, 218 (1978)
144!> \par Parameters
145!> - f : The incomplete Gamma function F_n(t).
146!> - nmax: Maximum n value of F_n(t).
147!> - t : Argument of the incomplete Gamma function.
148!> - kmax: Maximum number of iterations.
149!> - expt: Exponential term in the upward recursion of F_n(t).
150!> \author MK
151!> \version 1.0
152! **************************************************************************************************
153 SUBROUTINE fgamma_0(nmax, t, f)
154
155 INTEGER, INTENT(IN) :: nmax
156 REAL(kind=dp), INTENT(IN) :: t
157 REAL(kind=dp), DIMENSION(0:nmax), INTENT(OUT) :: f
158
159 INTEGER :: itab, k, n
160 REAL(kind=dp) :: expt, g, tdelta, tmp, ttab
161
162! *** Calculate F(t) ***
163
164 IF (t < teps) THEN
165
166! *** Special cases: t = 0 ***
167
168 DO n = 0, nmax
169 f(n) = 1.0_dp/real(2*n + 1, dp)
170 END DO
171
172 ELSE IF (t <= 12.0_dp) THEN
173
174! *** 0 < t < 12 -> Taylor expansion ***
175
176 tdelta = 0.1_dp
177
178! *** Pretabulation of the F_n(t) function ***
179! *** for the Taylor series expansion ***
180
181 IF (nmax > current_nmax) THEN
182 CALL init_md_ftable(nmax)
183 END IF
184
185 itab = nint(t/tdelta)
186 ttab = real(itab, dp)*tdelta
187
188 f(nmax) = ftable(nmax, itab)
189
190 tmp = 1.0_dp
191 DO k = 1, 6
192 tmp = tmp*(ttab - t)
193 f(nmax) = f(nmax) + ftable(nmax + k, itab)*tmp*ifac(k)
194 END DO
195
196 expt = exp(-t)
197
198! *** Use the downward recursion relation to ***
199! *** generate the remaining F_n(t) values ***
200
201 DO n = nmax - 1, 0, -1
202 f(n) = (2.0_dp*t*f(n + 1) + expt)/real(2*n + 1, dp)
203 END DO
204
205 ELSE
206
207! *** t > 12 ***
208 tmp = 1.0_dp/t ! reciprocal value
209
210 IF (t <= 15.0_dp) THEN
211
212! *** 12 < t <= 15 -> Four term polynom expansion ***
213
214 g = 0.4999489092_dp - 0.2473631686_dp*tmp + &
215 0.321180909_dp*tmp**2 - 0.3811559346_dp*tmp**3
216 f(0) = 0.5_dp*sqrt(pi*tmp) - g*exp(-t)*tmp
217
218 ELSE IF (t <= 18.0_dp) THEN
219
220! *** 15 < t <= 18 -> Three term polynom expansion ***
221
222 g = 0.4998436875_dp - 0.24249438_dp*tmp + 0.24642845_dp*tmp**2
223 f(0) = 0.5_dp*sqrt(pi*tmp) - g*exp(-t)*tmp
224
225 ELSE IF (t <= 24.0_dp) THEN
226
227! *** 18 < t <= 24 -> Two term polynom expansion ***
228
229 g = 0.499093162_dp - 0.2152832_dp*tmp
230 f(0) = 0.5_dp*sqrt(pi*tmp) - g*exp(-t)*tmp
231
232 ELSE IF (t <= 30.0_dp) THEN
233
234! *** 24 < t <= 30 -> One term polynom expansion ***
235
236 g = 0.49_dp
237 f(0) = 0.5_dp*sqrt(pi*tmp) - g*exp(-t)*tmp
238
239 ELSE
240
241! *** t > 30 -> Asymptotic formula ***
242
243 f(0) = 0.5_dp*sqrt(pi*tmp)
244
245 END IF
246
247 IF (t > real(2*nmax + 36, dp)) THEN
248 expt = 0.0_dp
249 ELSE
250 expt = exp(-t)
251 END IF
252
253! *** Use the upward recursion relation to ***
254! *** generate the remaining F_n(t) values ***
255
256 DO n = 1, nmax
257 f(n) = (0.5_dp*tmp)*(real(2*n - 1, dp)*f(n - 1) - expt)
258 END DO
259
260 END IF
261
262 END SUBROUTINE fgamma_0
263
264! **************************************************************************************************
265!> \brief Calculation of the incomplete Gamma function F(t) for multicenter
266!> integrals over Gaussian functions. f returns a vector with all
267!> F_n(t) values for 0 <= n <= nmax.
268!> \param nmax ...
269!> \param t ...
270!> \param f ...
271!> \date 08.01.1999
272!> \par Literature
273!> L. E. McMurchie, E. R. Davidson, J. Comp. Phys. 26, 218 (1978)
274!> \par Parameters
275!> - f : The incomplete Gamma function F_n(t).
276!> - nmax: Maximum n value of F_n(t).
277!> - t : Argument of the incomplete Gamma function.
278!> \author MK
279!> \version 1.0
280! **************************************************************************************************
281 SUBROUTINE fgamma_1(nmax, t, f)
282
283 INTEGER, INTENT(IN) :: nmax
284 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: t
285 REAL(kind=dp), DIMENSION(SIZE(t, 1), 0:nmax), &
286 INTENT(OUT) :: f
287
288 INTEGER :: i, itab, k, n
289 REAL(kind=dp) :: expt, g, tdelta, tmp, ttab
290
291 DO i = 1, SIZE(t, 1)
292
293! *** Calculate F(t) ***
294
295 IF (t(i) < teps) THEN
296
297! *** Special cases: t = 0 ***
298
299 DO n = 0, nmax
300 f(i, n) = 1.0_dp/real(2*n + 1, dp)
301 END DO
302
303 ELSE IF (t(i) <= 12.0_dp) THEN
304
305! *** 0 < t < 12 -> Taylor expansion ***
306
307 tdelta = 0.1_dp
308
309! *** Pretabulation of the F_n(t) function ***
310! *** for the Taylor series expansion ***
311
312 IF (nmax > current_nmax) THEN
313 CALL init_md_ftable(nmax)
314 END IF
315
316 itab = nint(t(i)/tdelta)
317 ttab = real(itab, dp)*tdelta
318
319 f(i, nmax) = ftable(nmax, itab)
320
321 tmp = 1.0_dp
322 DO k = 1, 6
323 tmp = tmp*(ttab - t(i))
324 f(i, nmax) = f(i, nmax) + ftable(nmax + k, itab)*tmp*ifac(k)
325 END DO
326
327 expt = exp(-t(i))
328
329! *** Use the downward recursion relation to ***
330! *** generate the remaining F_n(t) values ***
331
332 DO n = nmax - 1, 0, -1
333 f(i, n) = (2.0_dp*t(i)*f(i, n + 1) + expt)/real(2*n + 1, dp)
334 END DO
335
336 ELSE
337
338! *** t > 12 ***
339
340 IF (t(i) <= 15.0_dp) THEN
341
342! *** 12 < t <= 15 -> Four term polynom expansion ***
343
344 g = 0.4999489092_dp - 0.2473631686_dp/t(i) + &
345 0.321180909_dp/t(i)**2 - 0.3811559346_dp/t(i)**3
346 f(i, 0) = 0.5_dp*sqrt(pi/t(i)) - g*exp(-t(i))/t(i)
347
348 ELSE IF (t(i) <= 18.0_dp) THEN
349
350! *** 15 < t <= 18 -> Three term polynom expansion ***
351
352 g = 0.4998436875_dp - 0.24249438_dp/t(i) + 0.24642845_dp/t(i)**2
353 f(i, 0) = 0.5_dp*sqrt(pi/t(i)) - g*exp(-t(i))/t(i)
354
355 ELSE IF (t(i) <= 24.0_dp) THEN
356
357! *** 18 < t <= 24 -> Two term polynom expansion ***
358
359 g = 0.499093162_dp - 0.2152832_dp/t(i)
360 f(i, 0) = 0.5_dp*sqrt(pi/t(i)) - g*exp(-t(i))/t(i)
361
362 ELSE IF (t(i) <= 30.0_dp) THEN
363
364! *** 24 < t <= 30 -> One term polynom expansion ***
365
366 g = 0.49_dp
367 f(i, 0) = 0.5_dp*sqrt(pi/t(i)) - g*exp(-t(i))/t(i)
368
369 ELSE
370
371! *** t > 30 -> Asymptotic formula ***
372
373 f(i, 0) = 0.5_dp*sqrt(pi/t(i))
374
375 END IF
376
377 IF (t(i) > real(2*nmax + 36, dp)) THEN
378 expt = 0.0_dp
379 ELSE
380 expt = exp(-t(i))
381 END IF
382
383! *** Use the upward recursion relation to ***
384! *** generate the remaining F_n(t) values ***
385
386 DO n = 1, nmax
387 f(i, n) = 0.5_dp*(real(2*n - 1, dp)*f(i, n - 1) - expt)/t(i)
388 END DO
389
390 END IF
391
392 END DO
393
394 END SUBROUTINE fgamma_1
395
396! **************************************************************************************************
397!> \brief Calculation of the incomplete Gamma function F_n(t) using a
398!> spherical Bessel function expansion. fgamma_ref returns a
399!> vector with all F_n(t) values for 0 <= n <= nmax.
400!> For t values greater than 50 an asymptotic formula is used.
401!> This function is expected to return accurate F_n(t) values
402!> for any combination of n and t, but the calculation is slow
403!> and therefore the function may only be used for a pretabulation
404!> of F_n(t) values or for reference calculations.
405!> \param nmax ...
406!> \param t ...
407!> \return ...
408!> \date 07.01.1999
409!> \par Literature
410!> F. E. Harris, Int. J. Quant. Chem. 23, 1469 (1983)
411!> \par Parameters
412!> - expt : Exponential term in the downward recursion of F_n(t).
413!> - factor : Prefactor of the Bessel function expansion.
414!> - nmax : Maximum n value of F_n(t).
415!> - p : Product of the Bessel function quotients.
416!> - r : Quotients of the Bessel functions.
417!> - sumterm: One term in the sum over products of Bessel functions.
418!> - t : Argument of the incomplete Gamma function.
419!> \author MK
420!> \version 1.0
421! **************************************************************************************************
422 FUNCTION fgamma_ref(nmax, t) RESULT(f)
423
424 INTEGER, INTENT(IN) :: nmax
425 REAL(kind=dp), INTENT(IN) :: t
426 REAL(kind=dp), DIMENSION(0:nmax) :: f
427
428 INTEGER, PARAMETER :: kmax = 50
429 REAL(kind=dp), PARAMETER :: eps = epsilon(0.0_dp)
430
431 INTEGER :: j, k, n
432 REAL(kind=dp) :: expt, factor, p, sumterm, sumtot, term
433 REAL(kind=dp), DIMENSION(kmax+10) :: r
434
435! ------------------------------------------------------------------
436! *** Initialization ***
437
438 f(:) = 0.0_dp
439
440 IF (t < teps) THEN
441
442! *** Special case: t = 0 => analytic expression ***
443
444 DO n = 0, nmax
445 f(n) = 1.0_dp/real(2*n + 1, dp)
446 END DO
447
448 ELSE IF (t <= 50.0_dp) THEN
449
450! *** Initialize ratios of Bessel functions ***
451
452 r(kmax + 10) = 0.0_dp
453
454 DO j = kmax + 9, 1, -1
455 r(j) = -t/(real(4*j + 2, dp) - t*r(j + 1))
456 END DO
457
458 factor = 2.0_dp*sinh(0.5_dp*t)*exp(-0.5_dp*t)/t
459
460 DO n = 0, nmax
461
462! *** Initialize iteration ***
463
464 sumtot = factor/real(2*n + 1, dp)
465 term = 1.0_dp
466
467! *** Begin the summation and recursion ***
468
469 DO k = 1, kmax
470
471 term = term*real(2*n - 2*k + 1, dp)/real(2*n + 2*k + 1, dp)
472
473! *** Product of Bessel function quotients ***
474
475 p = 1.0_dp
476
477 DO j = 1, k
478 p = p*r(j)
479 END DO
480
481 sumterm = factor*term*p*real(2*k + 1, dp)/real(2*n + 1, dp)
482
483 IF (abs(sumterm) < eps) THEN
484
485! *** Iteration converged ***
486
487 EXIT
488
489 ELSE IF (k == kmax) THEN
490
491! *** No convergence with kmax iterations ***
492
493 cpabort("Maximum number of iterations reached")
494
495 ELSE
496
497! *** Add the current term to the sum and continue the iteration ***
498
499 sumtot = sumtot + sumterm
500
501 END IF
502
503 END DO
504
505 f(n) = sumtot
506
507 END DO
508
509 ELSE
510
511! *** Use asymptotic formula for t > 50 ***
512
513 f(0) = 0.5_dp*sqrt(pi/t)
514
515! *** Use the upward recursion relation to ***
516! *** generate the remaining F_n(t) values ***
517
518 expt = exp(-t)
519
520 DO n = 1, nmax
521 f(n) = 0.5_dp*(real(2*n - 1, dp)*f(n - 1) - expt)/t
522 END DO
523
524 END IF
525
526 END FUNCTION fgamma_ref
527
528! **************************************************************************************************
529!> \brief Initialize a table of F_n(t) values in the range 0 <= t <= 12 with
530!> a stepsize of 0.1 up to n equal to nmax for the Taylor series
531!> expansion used by McMurchie-Davidson (MD).
532!> \param nmax ...
533!> \date 10.06.1999
534!> \par Parameters
535!> - nmax : Maximum n value of F_n(t).
536!> \author MK
537!> \version 1.0
538! **************************************************************************************************
539 SUBROUTINE init_md_ftable(nmax)
540 INTEGER, INTENT(IN) :: nmax
541
542 IF (nmax < 0) THEN
543 CALL cp_abort(__location__, &
544 "A negative n value for the initialization of the "// &
545 "incomplete Gamma function is invalid")
546 END IF
547
548! *** Check, if the current initialization is sufficient ***
549
550 IF (nmax > current_nmax) THEN
551
553
554! *** Pretabulation of the F_n(t) function ***
555! *** for the Taylor series expansion ***
556
557 CALL create_md_ftable(nmax, 0.0_dp, 12.0_dp, 0.1_dp)
558
559 END IF
560
561 END SUBROUTINE init_md_ftable
562
563END MODULE gamma
Calculation of the incomplete Gamma function F_n(t) for multi-center integrals over Cartesian Gaussia...
Definition gamma.F:15
subroutine, public init_md_ftable(nmax)
Initialize a table of F_n(t) values in the range 0 <= t <= 12 with a stepsize of 0....
Definition gamma.F:540
real(kind=dp) function, dimension(0:nmax), public fgamma_ref(nmax, t)
Calculation of the incomplete Gamma function F_n(t) using a spherical Bessel function expansion....
Definition gamma.F:423
subroutine, public deallocate_md_ftable()
Deallocate the table of F_n(t) values.
Definition gamma.F:121
subroutine, public fgamma_0(nmax, t, f)
Calculation of the incomplete Gamma function F(t) for multicenter integrals over Gaussian functions....
Definition gamma.F:154
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
real(kind=dp), dimension(0:maxfac), parameter, public ifac