Multidip 1.0
Multi-photon matrix elements
Loading...
Searching...
No Matches
multidip_integ.f90
Go to the documentation of this file.
1! Copyright 2020
2!
3! For a comprehensive list of the developers that contributed to these codes
4! see the UK-AMOR website.
5!
6! This file is part of UKRmol-out (UKRmol+ suite).
7!
8! UKRmol-out is free software: you can redistribute it and/or modify
9! it under the terms of the GNU General Public License as published by
10! the Free Software Foundation, either version 3 of the License, or
11! (at your option) any later version.
12!
13! UKRmol-out is distributed in the hope that it will be useful,
14! but WITHOUT ANY WARRANTY; without even the implied warranty of
15! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16! GNU General Public License for more details.
17!
18! You should have received a copy of the GNU General Public License
19! along with UKRmol-out (in source/COPYING). Alternatively, you can also visit
20! <https://www.gnu.org/licenses/>.
21!
22!> \brief Special integrals needed by MULTIDIP
23!> \author J Benda
24!> \date 2020 - 2023
25!>
26!> Module containing routines for calculation of the multi-dimensional dipole integrals used in outer correction
27!> of transition dipole elements in MULTIDIP.
28!>
30
31 use iso_fortran_env, only: error_unit
33 use phys_const_gbl, only: pi, imu
34 use precisn_gbl, only: wp
35
36 implicit none
37
38contains
39
40 !> \brief Multi-dimensional triangular integral of exponentials and powers
41 !> \author J Benda
42 !> \date 2020 - 2023
43 !>
44 !> Evaluate the nested many-dimensional triangular integral
45 !> \f[
46 !> \int\limits_a^{+\infty} \dots \int\limits_{r_3}^{+\infty} \mathrm{e}^{\mathrm{i}s_4 \theta_4(r_2)}
47 !> r_2^{m_2} \mathrm{e}^{\mathrm{i}s_3 \theta_3(r_2)} \int\limits_{r_2}^{+\infty}
48 !> \mathrm{e}^{\mathrm{i}s_2 \theta_2(r_1)} r_1^{m_1} \mathrm{e}^{\mathrm{i}s_1 \theta_1(r_1)}
49 !> \mathrm{d}r_1 \mathrm{d}r_2 \mathrm{d}r_3 \dots
50 !> \f]
51 !> where
52 !> \f[
53 !> \theta_1(r_1) = k_1 r_1 + \log(2 k_1 r_1)/k_1 - \pi l_1/2 + \sigma_{l_1}(k_1)
54 !> \f]
55 !> is the asymptotic phase of a Coulomb function. The arrays passed to this function
56 !> need to be ordered from the inner-most (right-most) integral outward. The function
57 !> result does not contain the overall phase and damp factor, which needs to be added
58 !> manually.
59 !>
60 !> \param Z Residual ion charge
61 !> \param a Lower bound
62 !> \param c Damping factor (additional exp(-c*r) added to all r^m functions)
63 !> \param N Dimension (number of integration variables)
64 !> \param m Array of integer powers of length N
65 !> \param s Array of integer signs (+1 or -1) in exponents of length 2*N
66 !> \param k Array of linear momenta of length 2*N
67 !>
68 complex(wp) function nested_exp_integ (Z, a, c, N, m, s, k) result (val)
69
70 use multidip_params, only: ntermsppt
71
72 integer, intent(in) :: n, m(0:n-1), s(0:2*n-1)
73 real(wp), intent(in) :: z, a, c
74 complex(wp), intent(in) :: k(0:2*n-1)
75
76 integer, parameter :: npp = ntermsppt
77
78 complex(wp) :: i(0:n*(npp+1)), f(0:n*(npp+1)-1), fg(0:n*(npp+1)-1), g(0:(n+1)*(npp+1)-1), j(0:n*(npp+1)-1)
79 complex(wp) :: t(0:npp, 0:n*(npp + 1)-1)
80
81 real(wp) :: b(0:n*(npp+1)-1, 0:n*(npp+1))
82
83 complex(wp) :: u, v
84 integer :: o, p, q, lvl
85
86 if (n < 1) then
87 val = 0
88 return
89 end if
90
91 ! For a given expansion depth of the integral (Npp) we need that many
92 ! derivatives of the base function (here of the coordinate power r^m).
93 ! With N levels of nesting, this combines to N * Npp derivatives in total
94 ! for the first base function. Further base functions are not needed
95 ! to such high orders.
96
97 i = 0
98 f = 0
99 fg = 0
100 g = 0
101 j = 0
102 t = 0
103
104 ! Construct Pascal triangle of binomial coefficients.
105
106 b = 0
107 do p = lbound(b, 1), ubound(b, 1)
108 b(p, 0) = 1
109 do q = 1, p - 1
110 b(p, q) = b(p - 1, q - 1) + b(p - 1, q)
111 end do
112 b(p, p) = 1
113 end do
114
115 ! Constants of the phase function. This accumulates all phases along the nested dimensions.
116
117 u = 0.
118 v = 0.
119
120 ! Initialize the "deepest-nested" integral, so that f*I = f.
121
122 i(0) = 1.
123
124 ! Recursively evaluate levels.
125
126 do lvl = 0, n - 1
127
128 ! 1. Evaluate the base function for this level, including all its derivatives.
129 ! The base function is simply a coordinate power, r^m[lvl], so its
130 ! derivatives can be calculated directly.
131
132 f(0) = a**m(lvl)
133
134 do p = 1, (n - lvl)*(npp + 1) - 1
135 f(p) = (m(lvl) + 1 - p) * f(p - 1) / a
136 end do
137
138 ! 2. Combine the base function with the integral from the previous level,
139 ! resulting in the effective base function fg for this level.
140
141 do p = 0, (n - lvl)*(npp + 1) - 1
142 fg(p) = 0
143 do q = 0, p
144 fg(p) = fg(p) + b(p,q) * f(p - q) * i(q)
145 end do
146 end do
147
148 ! 3. Evaluate the phase function at this level. This is required for construction
149 ! of the individual terms of the asymptotic expansion, as well as for finalization
150 ! of the integral after the terms are summer. The highest derivative degree
151 ! needed is Npp plus the number of derivatives of the resulting integral that
152 ! we are calculating at this level.
153
154 u = u + s(2*lvl+1)*k(2*lvl+1) + s(2*lvl+0)*k(2*lvl+0) + imu*c
155 v = v + z*s(2*lvl+1)/abs(k(2*lvl+1)) + z*s(2*lvl+0)/abs(k(2*lvl+0))
156
157 g(0) = imu*a / (u*a + v)
158 g(1) = imu*v / ((u*a + v)*(u*a + v))
159
160 do p = 2, (n - lvl + 1)*(npp + 1) - 1
161 g(p) = g(p - 1) * (-p) * u / (u*a + v)
162 end do
163
164 ! 4. Evaluate all terms of the asymptotic expansion of the integral, as well as their
165 ! derivatives up to the order required for the integral itself, that is (N - lvl)*(Npp + 1).
166
167 do p = 0, (n - lvl)*(npp + 1) - 1
168 t(0, p) = fg(p)
169 end do
170
171 do o = 1, npp
172 do p = 0, (n - lvl)*(npp + 1) - o - 1
173 t(o, p) = 0
174 do q = 0, p + 1
175 t(o, p) = t(o, p) + b(p + 1, q) * g(p + 1 - q) * t(o - 1, q)
176 end do
177 end do
178 end do
179
180 ! 5. Sum the terms of the asymptotic expansion to get the reduced integral J (and its derivatives).
181
182 do p = 0, (n - lvl - 1)*(npp + 1)
183 j(p) = 0
184 do o = 0, npp
185 j(p) = j(p) + t(o, p)
186 end do
187 end do
188
189 ! 5. Evaluate the resulting integral (and derivatives) at this level.
190
191 do p = 0, (n - lvl - 1)*(npp + 1)
192 i(p) = 0
193 do q = 0, p
194 i(p) = i(p) + b(p, q) * g(p - q) * j(q)
195 end do
196 end do
197
198 end do
199
200 val = i(0)
201
202 end function nested_exp_integ
203
204
205 !> \brief Multi-dimensional triangular integral of Coulomb-Hankel functions and powers
206 !> \author J Benda
207 !> \date 2020 - 2023
208 !>
209 !> Evaluate the nested many-dimensional triangular integral
210 !> \f[
211 !> \int\limits_a^{+\infty} \dots \int\limits_{r_3}^{+\infty} H_4(r_2) r_2^{m_2} H_3(r_2)
212 !> \int\limits_{r_2}^{+\infty} H_2(r_1) r_1^{m_1} H_1(r_1) \mathrm{d}r_1 \mathrm{d}r_2 \mathrm{d}r_3 \dots
213 !> \f]
214 !> using the asymptotic form of Coulomb-Hankel functions. The arrays passed to this function
215 !> need to be ordered from the inner-most (right-most) integral outward. For each term, use
216 !> \ref nested_exp_integ.
217 !>
218 !> \param Z Residual ion charge
219 !> \param a Lower bound
220 !> \param c Damping factor (additional exp(-c*r) added to all r^m functions)
221 !> \param N Dimension (number of integration variables)
222 !> \param m Array of integer powers of length N
223 !> \param s Array of integer signs (+1 or -1) in exponents of length 2*N
224 !> \param l Array of angular momenta of length 2*N
225 !> \param k Array of linear momenta of length 2*N
226 !>
227 complex(wp) function nested_coul_integ (Z, a, c, N, m, s, l, k) result (val)
228
229 use multidip_params, only: ntermsasy
231
232 integer, intent(in) :: n, m(1:n), s(1:2*n), l(1:2*n)
233 real(wp), intent(in) :: z, a, c
234 complex(wp), intent(in) :: k(1:2*n)
235
236 integer :: nn(2*n), ms(n), p
237 complex(wp) :: an(2*n), bn(2*n), factor(2*n)
238
239 logical :: at_end
240 real(wp) :: total_phase, total_exponent, kr, ki
241 complex(wp) :: integ, err
242
243 at_end = .false.
244 val = 0
245 err = 0
246 factor = 1.
247 nn = 0
248
249 ! initial values of the Pochhammer symbols in the asymptotic series for the Coulomb-Hankel (or real Whittaker) functions
250 do p = 1, 2*n
251 an(p) = 1 + l(p) - z*s(p)*imu/k(p)
252 bn(p) = -l(p) - z*s(p)*imu/k(p)
253 end do
254
255 ! sum all terms of the Cartesian product of all Coulomb-Hankel (or real Whittaker) functions expansions
256 do while (.not. at_end)
257
258 ! total power in r^m
259 do p = 1, n
260 ms(p) = m(p) - nn(2*p-1) - nn(2*p-0)
261 end do
262
263 ! radial integral
264 integ = nested_exp_integ(z, a, c, n, ms, s, k)
265
266 ! combine all coefficients from the expansions of all Coulomb-Hankel (or real Whittaker) functions
267 do p = 1, 2*n
268 integ = integ * factor(p)
269 end do
270
271 ! add the integral value using the floating-point-error compensating routine
272 call kahan_add(val, integ, err)
273
274 ! pick up the next single term from the product of expansions of all Coulomb-Hankel (or real Whittaker) functions
275 do p = 1, 2*n
276 nn(p) = nn(p) + 1
277 if (nn(p) == ntermsasy) then
278 nn(p) = 0
279 factor(p) = 1.
280 at_end = .true.
281 else
282 factor(p) = factor(p) * (an(p) + nn(p) - 1) * (bn(p) + nn(p) - 1) / (2 * imu * s(p) * nn(p) * k(p))
283 at_end = .false.
284 exit
285 end if
286 end do
287
288 end do
289
290 ! calculate the overall exponential and phase factor
291 total_phase = 0
292 total_exponent = 0
293 do p = 1, 2*n
294 kr = real(k(p), wp)
295 ki = aimag(k(p))
296 if (ki == 0) then
297 ! positive energy solution -> Coulomb-Hankel function
298 total_phase = total_phase + s(p)*(kr*a + z*log(2*kr*a)/kr - pi*l(p)/2 + cphase(z, l(p), kr))
299 else
300 ! negative energy solution -> Whittaker function
301 total_exponent = total_exponent + s(p)*(-ki*a + z*log(2*ki*a)/ki)
302 end if
303 end do
304
305 ! multiply the sum of expansion terms with the combined exponential factor
306 val = val * cmplx(cos(total_phase), sin(total_phase), wp) * exp(total_exponent - n*c*a)
307
308 end function nested_coul_integ
309
310
311 !> \brief Multi-dimensional integral of Coulomb-Hankel and Coulomb-Green functions and powers
312 !> \author J Benda
313 !> \date 2020 - 2024
314 !>
315 !> Evaluate the many-dimensional integral
316 !> \f[
317 !> \int\limits_a^{+\infty} \dots \int\limits_a^{+\infty} H_N(r_N) \dots g_3(r_3, r_2) r_2^{m_2}
318 !> g_2(r_2, r_1) r_1^{m_1} H_1(r_1) \mathrm{d}r_1 \dots
319 !> \f]
320 !> using the asymptotic form of Coulomb-Hankel functions. The arrays passed to this function
321 !> need to be ordered from the right-most integral to the right. This function iterates over
322 !> all possible orderings of \f$ (r_1, r_2, \dots, r_N) \f$ and for each of these it splits the
323 !> integral into (hyper-)triangular integrals and integrates those using \ref nested_coul_integ.
324 !>
325 !> For small values of "a" it may increase the accuracy if the leading interval (a,r0) (or more specifically the set
326 !> Q = (a,+∞)^N \ (b,+∞)^N) is integrated numerically. For such use, provide r0 > a. Otherwise set r0 to zero.
327 !>
328 !> When the global paramter `coulomb_check` is on, the integral is not attempted if any of the Coulomb functions
329 !> in the integrand is not sufficiently well approximated by the asymptotic form at the R-matrix radius (or at the
330 !> asymptotic radius if given). In such a case, the function returns the NaN constant.
331 !>
332 !> The one-dimensional case with c = 0, m = 0, l1 = l2 and real momenta is treated in a special way using a closed-form
333 !> formula from the article: *H. F. Arnoldus, T. F. George: Analytical evaluation of elastic Coulomb integrals,
334 !> J. Math. Phys. 33 (1992) 578–583*.
335 !>
336 !> The (adapted) formula reads:
337 !> \f[
338 !> \lim_{c \rightarrow 0+} \int\limits_a^{+\infty} X_l(k_2; r) Y_l(k_1; r) \exp(-cr) dr
339 !> = \frac{X_l'(k_2; a) Y_l(k_1; a) - X_l(k_2; a) Y_l'(k_1; a)}{k_2^2 - k_1^2} \,,
340 !> \f]
341 !> where \f$ X_l \f$ and \f$ Y_l \f$ stand for arbitrary Coulomb functions and primes denote derivatives with respect
342 !> to the radius.
343 !>
344 !> \param Z Residual ion charge
345 !> \param a Lower bound of the integration
346 !> \param r0 Optional radius from which to apply asymptotic integrals
347 !> \param c Damping factor (additional exp(-c*r) added to all r^m functions)
348 !> \param N Dimension (number of integration variables)
349 !> \param sa Sign of the right-most Coulomb-Hankel function
350 !> \param sb Sign of the left-most Coulomb-Hankel function
351 !> \param m Array of integer powers of length N
352 !> \param l Array of angular momenta of length N + 1
353 !> \param k Array of linear momenta of length N + 1
354 !>
355 complex(wp) function nested_cgreen_integ (Z, a, r0, c, N, sa, sb, m, l, k) result (val)
356
357 use ieee_arithmetic, only: ieee_value, ieee_quiet_nan
358 use mpi_gbl, only: mpi_xermsg
362 use multidip_special, only: next_permutation, kahan_add, coul, coulh, coulh_asy
363
364 integer, intent(in) :: n, sa, sb, m(:), l(:)
365 real(wp), intent(in) :: z, a, c, r0
366 complex(wp), intent(in) :: k(:)
367
368 logical :: acc(n)
369 integer :: order(n), mp(n), lp(2*n), sp(2*n), p, signs
370 real(wp) :: b, rs(n), f(2, 2), g(2, 2)
371 complex(wp) :: kp(2*n), err, integ, ix, ia, h(2, 2)
372
373 character(len=100) :: msg
374
375 val = 0
376 err = 0
377 b = a
378
379 ! integrate the ion-ion transition analytically
380 if (ion_ion_analytic .and. n == 1 .and. m(1) == 0 .and. l(1) == l(2) .and. aimag(k(1)) == 0 .and. aimag(k(2)) == 0) then
381 call coul(z, l(1), real(k(1))**2/2, a, f(1,1), f(2,1), g(1,1), g(2,1))
382 call coul(z, l(2), real(k(2))**2/2, a, f(1,2), f(2,2), g(1,2), g(2,2))
383 h(:, 1) = cmplx(g(:, 1), sa*f(:, 1), wp)
384 h(:, 2) = cmplx(g(:, 2), sb*f(:, 2), wp)
385 val = (h(2,2)*h(1,1) - h(1,2)*h(2,1))/(real(k(2))**2 - real(k(1))**2)
386 return
387 end if
388
389 ! test the accuracy of the integrand at the R-matrix radius "a" (NOTE: numerical correction implemented only for N = 1)
390 if (a < r0 .and. n == 1) then
391 rs = a
392 ix = nested_cgreen_eval(z, c, n, sa, sb, m, l, k, rs, .false.)
393 ia = nested_cgreen_eval(z, c, n, sa, sb, m, l, k, rs, .true.)
394 if (abs(ix) > 1e-10 .and. abs(ia - ix) > coultol * abs(ix)) then
395 ! R-matrix radius too small, prefer the user-given asymptotic radius "r0"
396 b = r0
397 end if
398 end if
399
400 ! test the accuracy of the integrand at the asymptotic radius "b" (NOTE: nested_cgreen_eval implemented only for N = 1)
401 if (coulomb_check .and. n == 1) then
402 rs = b
403 ix = nested_cgreen_eval(z, c, n, sa, sb, m, l, k, rs, .false.)
404 ia = nested_cgreen_eval(z, c, n, sa, sb, m, l, k, rs, .true.)
405 if (abs(ix) > 1e-10 .and. abs(ia - ix) > abs(ix)) then
406 if (print_warnings) then
407 ! asymptotic radius too small, do not bother to evaluate the integrals at all
408 !$omp critical (print_warning)
409 write (*, '(5x,A,3(I0,1x))', advance = 'no') 'Warning: Giving up Coul-Green integ '
410 write (*, '(3(A,I0,SP))', advance = 'no') 'm = ', m, ', sa = ', sa, ', sb = ', sb
411 write (*, '(A,*(I0,","))', advance = 'no') ', l = ', l
412 write (*, '(A,SP,*(F0.4,","))', advance = 'no') ' E = ', real(k**2/2, wp)
413 write (*, '(SP,2(A,2E10.4),A)') ' Ix = ', ix, 'i, Ia = ', ia, 'i'
414 !$omp end critical (print_warning)
415 end if
416 return
417 end if
418 end if
419
420 ! initial ordering of coordinates, rN < ... < r2 < r1 (order(1) = index of the largest coordinate)
421 order = -1
422
423 ! for all orderings of the coordinates { rN, ..., r2, r1 }
424 do while (next_permutation(order))
425
426 ! reorder quantum numbers according to coordinate order
427 do p = 1, n
428 mp(p) = m(order(p))
429 end do
430
431 ! for all regular Coulomb function splittings, F = (H⁺ - H⁻)/2i
432 do signs = 0, 2**(n - 1) - 1
433
434 ! Each bit of 'signs' (starting from the least significant one) corresponds to the sign of the Coulomb-Hankel
435 ! function H arising from the F function in the corresponding Coulomb-Green's function. If 'j' is the position
436 ! of the bit (starting from 0 for the least significant one), then the sign belongs to the Coulomb-Green's
437 ! function g(r(j+1), r(j)). There are N-1 Coulomb-Green's functions in total in the integrand, so we are iterating
438 ! only over all combinations of the first N-1 bits.
439
440 ! these (original) coordinate indices have been processed already
441 acc = .false.
442
443 ! assemble quantum numbers for coordinates sorted from largest to smallest
444 do p = 1, n
445
446 ! For each coordinate, there are two Coulomb-Hankel functions. For r0, one of the Coulomb-Hankel functions
447 ! is H[sa]. For rN one of them is H[sb]. Others come from separation of g(r(j+1), r(j)). Here we are processing
448 ! coordinate r(j), where j = order[n]. This coordinate is connected by the Coulomb-Green's functions to the
449 ! previous coordinate r(j-1) and to the next coordinate r(j+1). The former connection is realized by (j-1)-th
450 ! Coulomb-Green's function, while the latter by the j-th one. We compare the current coordinate r(j) to its
451 ! neighbours r(j-1) and r(j+1) simply by checking whether we have already processed them, because we are
452 ! processing the coordinates in order of the descending order. Based on this comparison, either the appropriate
453 ! F sign (if this coordinate is smaller than neighbour) or the +1 sign for H+ (if the this coordinate is greater
454 ! then the neighbour) is used.
455
456 sp(2*p - 1) = sa
457 sp(2*p - 0) = sb
458
459 if (order(p) > 1) sp(2*p - 1) = merge(merge(-1, +1, btest(signs, order(p) - 2)), +1, acc(order(p) - 1))
460 if (order(p) < n) sp(2*p - 0) = merge(merge(-1, +1, btest(signs, order(p) - 1)), +1, acc(order(p) + 1))
461
462 acc(order(p)) = .true.
463
464 kp(2*p - 1) = k(order(p) - 0)
465 kp(2*p - 0) = k(order(p) + 1)
466
467 lp(2*p - 1) = l(order(p) - 0)
468 lp(2*p - 0) = l(order(p) + 1)
469
470 end do
471
472 ! evaluate integral for this hyper-triangle
473 integ = (-1)**popcnt(signs) * nested_coul_integ(z, b, c, n, mp, sp, lp, kp)
474
475 ! add the integral value using the floating-point-error compensating routine
476 call kahan_add(val, integ, err)
477
478 end do
479
480 end do
481
482 ! add the Green's function factors
483 do p = 2, n
484 val = val * imu / k(p)
485 end do
486
487 ! integrate over Q = (a,+∞)^N \ (b,+∞)^N numerically
488 if (a < b) then
489 select case (num_integ_algo)
490 case (1)
491 call nested_cgreen_correct_romberg(z, a, b, c, n, sa, sb, m, l, k, val)
492 case (2)
493 call nested_cgreen_correct_levin(z, a, b, c, n, sa, sb, m, l, k, val)
494 case default
495 write (msg, '(a,i0)') 'Unknown numerical integration algorithm ', num_integ_algo
496 call mpi_xermsg('multidip_integ', 'nested_cgreen_integ', trim(msg), 1, 1)
497 end select
498 end if
499
500 end function nested_cgreen_integ
501
502end module multidip_integ
Special integrals needed by MULTIDIP.
complex(wp) function nested_cgreen_integ(z, a, r0, c, n, sa, sb, m, l, k)
Multi-dimensional integral of Coulomb-Hankel and Coulomb-Green functions and powers.
complex(wp) function nested_coul_integ(z, a, c, n, m, s, l, k)
Multi-dimensional triangular integral of Coulomb-Hankel functions and powers.
complex(wp) function nested_exp_integ(z, a, c, n, m, s, k)
Multi-dimensional triangular integral of exponentials and powers.
Levin quadrature for numerical integration.
subroutine nested_cgreen_correct_levin(z, a, b, c, n, sa, sb, m, l, k, v)
Numerically correct asymptotic approximation of the Coulomb-Green integral (Levin integration)
Hard-coded parameters of MULTIDIP.
integer, parameter ntermsppt
Number of terms in expansion of the exponential integral.
real(wp), parameter pi
integer num_integ_algo
Numerical integration mode (1 = Romberg, 2 = Levin)
logical cache_integrals
Cache Coulomb-Green integrals in memory (but disables some threading)
complex(wp), parameter imu
logical coulomb_check
Skip integrals that cannot be asymptotically approximated well.
real(wp) coultol
Coulomb matching relative tolerance (decides whether to use asym. forms)
logical print_warnings
Print warnings about non-converged integrals.
logical ion_ion_analytic
Integrate one-dimensional ion-ion integrals using a closed-form formula.
integer, parameter ntermsasy
Number of terms in expansion of the Coulomb-Hankel functions.
Romberg quadrature for numerical integration.
complex(wp) function nested_cgreen_eval(z, c, n, sa, sb, m, l, k, rs, asy)
Evaluate the Coulomb-Green's integrand.
subroutine nested_cgreen_correct_romberg(z, a, b, c, n, sa, sb, m, l, k, v)
Numerically correct asymptotic approximation of the Coulomb-Green integral (Romberg integration)
Special functions and objects used by MULTIDIP.
subroutine kahan_add(x, dx, err)
Compensated summation.
real(wp) function cphase(z, l, k)
Coulomb phase.
subroutine coul(z, l, ek, r, f, fp, g, gp)
Coulomb functions.
logical function next_permutation(p)
Construct or advance permutation.
Auxiliary routines.