Multidip 1.0
Multi-photon matrix elements
Loading...
Searching...
No Matches
multidip_asy.f90
Go to the documentation of this file.
1! Copyright 2024
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 Asymptotic approximation of multi-photon matrix elements
23!> \author J Benda
24!> \date 2024
25!>
27
28 use precisn_gbl, only: wp
29
30 implicit none
31
32contains
33
34 !> \brief Hydrogen 1s one-photon ionization
35 !> \author J Benda
36 !> \date 2024
37 !>
38 !> Evaluate the radial factor in the one-photon ionization amplitude of H(1s). This can be expressed as
39 !> \f[
40 !> M^{(1)} = \int_0^\infty F_l(k, r) r P_{10}(r) dr \,.
41 !> \f]
42 !>
43 real(wp) function m1_h1s (l, k) result (m1)
44
45 use multidip_params, only: pi
47
48 integer, intent(in) :: l
49 real(wp), intent(in) :: k
50
51 real(wp) :: cl, nu
52
53 nu = 2
54
55 cl = 2**l * exp(0.5*pi/k) * abs(complex_gamma(l, -1/k)) / real(complex_gamma(2*l + 1, 0._wp))
56 m1 = 2*(nu - 1._wp/(l + 1))*gamma(2*l + 3._wp)*cl*k**(l + 1)/(nu*nu + k*k)**(l + 2) * exp(-2/k * atan(k/nu))
57
58 end function m1_h1s
59
60
61 !> \brief Near-field part of the continuum-continuum transition integral
62 !> \authors J Benda
63 !> \date 2024
64 !>
65 !> Numerically evaluates the integral
66 !> \f[
67 !> I_{cc}(a) = \int\limits_0^a F_l(k,r) r^b H_\lambda^+(\kappa,r) dr \,.
68 !> \f]
69 !>
70 !> This function splits the integral to two pieces at the classical turning point \f$ a_0 \f$ of the Coulomb functions.
71 !> The non-oscillatory, classically forbidden part \f$ (0, a_0) \f$ is integrated using Romberg quadrature, while
72 !> the remainder \f$ (a_0, a) \f$ is integrated using Levin quadrature.
73 !>
74 complex(wp) function icca (Z, a, b, k, l, kappa, lambda) result (val)
75
77 use multidip_params, only: imu, pi
78 use multidip_special, only: coul
79
80 integer, intent(in) :: lambda, l, b
81 real(wp), intent(in) :: z, a, kappa, k
82
83 integer, parameter :: mmax = 15
84 logical, parameter :: use_levin = .true.
85 real(wp), parameter :: epsrel = 1e-6
86
87 integer :: i, m, n
88 real(wp) :: ff, ffp, gf, gfp, fn, fnp, gn, gnp, r, dr, a0
89 complex(wp) :: romb(0:mmax, 0:mmax), res
90
91 a0 = a ! Romberg quadrature endpoint
92 val = 0 ! value to be returned
93
94 ! optionally restrict Romberg to the classically forbidden region
95 if (use_levin) then
96
97 if (lambda == 0 .and. l == 0) then
98 a0 = pi/(2*min(kappa, k))
99 else
100 a0 = (sqrt(kappa**2*max(lambda, l)*max(lambda + 1, l + 1) + z**2) - z)/kappa**2
101 end if
102
103 if (a0 >= a) then
104 a0 = a
105 else
106 val = levin_adapt(z, a0, a, 0._wp, b, 0, +1, l, lambda, cmplx(k, 0, wp), cmplx(kappa, 0, wp))
107 end if
108
109 end if
110
111 ! use Romberg quadrature in the classically forbidden region (if any)
112 if (a0 > 0) then
113
114 ! evaluate Coulomb functions at r = a0
115 call coul(z, lambda, kappa**2/2, a0, fn, fnp, gn, gnp)
116 call coul(z, l, k**2/2, a0, ff, ffp, gf, gfp)
117
118 ! initialize using endpoints (r = 0 and r = a0)
119 res = ff * a0**b * (gn + imu*fn)/2
120 romb = 0
121 romb(0, 0) = res*a0
122
123 ! integrate numerically up to r = a0 using Romberg method
124 richardson_iterations: do m = 1, mmax
125
126 ! define grid spacing at this subdivision level
127 n = 2**m
128 dr = a0/n
129
130 ! apply nested trapezoidal quadrature rule
131 do i = 1, n, 2
132 r = i*dr
133 call coul(z, lambda, kappa**2/2, r, fn, fnp, gn, gnp)
134 call coul(z, l, k**2/2, r, ff, ffp, gf, gfp)
135 res = res + r**b * ff * (gn + imu*fn)
136 end do
137
138 ! update Richardson extrapolation table
139 romb(m, 0) = val + res*dr
140 do n = 1, m
141 do i = n, m
142 romb(i, n) = (4**n*romb(i, n - 1) - romb(i - 1, n - 1))/(4**n - 1)
143 end do
144 end do
145
146 ! exit if converged
147 if (m >= 5) then
148 if (abs(romb(m, m) - romb(m - 1, m - 1)) < epsrel*abs(romb(m, m))) then
149 val = romb(m, m)
150 exit richardson_iterations
151 end if
152 end if
153
154 ! exit if non-converged
155 if (m == mmax) then
156 print '(a,i0,a)', 'Warning: Romberg quadrature failed to converge in ', mmax, ' subdivisions.'
157 val = romb(m, m)
158 end if
159
160 end do richardson_iterations
161
162 end if
163
164 end function icca
165
166
167 !> \brief Near-field part of the double continuum-continuum transition integral
168 !> \authors J Benda
169 !> \date 2024
170 !>
171 !> Numerically evaluate the integral
172 !> \f[
173 !> I = \int\limits_0^a \int\limits_0^a F_{l_f}(k_f,r) r g_{l_n}^{(+)}(k_n; r, r') r' H_{l_i}^+(r') dr' \,.
174 !> \f]
175 !>
176 complex(wp) function i2cca (Z, a, kf, lf, kn, ln, ki, li) result (val)
177
178 use multidip_special, only: coulh
179
180 real(wp), intent(in) :: z, a, ki, kn, kf
181 integer, intent(in) :: li, ln, lf
182
183 real(wp), parameter :: c = 0 ! damping factor
184 integer, parameter :: mmax = 13 ! log2 of the maximal number of 2D quadrature points in each dimension
185
186 real(wp), allocatable :: ff(:), fn(:)
187 complex(wp), allocatable :: hn(:), hi(:)
188
189 integer :: i, j, qi, qj, m, n, stride
190 complex(wp) :: hlf, hln, hli, romb(0:mmax, 0:mmax)
191 real(wp) :: dr, ri, rj, wt
192
193 ! allocate workspaces for the double integral
194 ! - the zeroth index corresponds to left boundary of the integration domain where the integrand is zero, so it is not used
195 ! neither allocated
196 ! - the last index corresponds to the right boundary
197 allocate (ff(2**mmax), fn(2**mmax), hn(2**mmax), hi(2**mmax))
198
199 ! obtain all needed function values
200 do i = 1, 2**mmax
201 ri = i*a/2**mmax
202 hlf = coulh(z, +1, lf, kf*kf/2, ri)
203 hln = coulh(z, +1, ln, kn*kn/2, ri)
204 hli = coulh(z, +1, li, ki*ki/2, ri)
205 ff(i) = aimag(hlf)
206 fn(i) = aimag(hln)
207 hn(i) = hln
208 hi(i) = hli
209 end do
210
211 ! loop over all subdivision levels for the double integral
212 val = 0
213 romb = 0
214 do m = 0, mmax
215
216 ! define grid spacing at this subdivision level
217 n = 2**m
218 stride = 2**(mmax - m)
219 dr = a/n
220
221 ! apply nested 2D trapezoidal quadrature rule
222 do i = 1, n
223 ri = i*dr
224 qi = i*stride
225 do j = i, n
226 rj = j*dr
227 qj = j*stride
228 if (mod(i, 2) /= 0 .or. mod(j, 2) /= 0) then
229 wt = 1._wp/(1 + merge(1, 0, i == n) + merge(1, 0, j == n))
230 val = val + wt*ff(qi)*ri*fn(qi)*hn(qj)*rj*hi(qj)
231 if (i /= j) then
232 val = val + wt*ff(qj)*rj*hn(qj)*fn(qi)*ri*hi(qi)
233 end if
234 end if
235 end do
236 end do
237
238 ! update Richardson extrapolation table
239 romb(m, 0) = val*dr*dr
240 do n = 1, m
241 do i = n, m
242 romb(i, n) = (4**n*romb(i, n - 1) - romb(i - 1, n - 1))/(4**n - 1)
243 end do
244 end do
245
246 end do
247
248 val = -2/kn*romb(mmax, mmax)
249
250 end function i2cca
251
252
253 !> \brief Far-field part of the continuum-continuum transition integral
254 !> \authors J Benda
255 !> \date 2024
256 !>
257 !> Asymptotically evaluates the integral
258 !> \f[
259 !> A_{cc}(a) = \int\limits_a^{+\infty} F_l(k,r) r^b H_\lambda^+(\kappa,r) dr \,.
260 !> \f]
261 !>
262 complex(wp) function acca (Z, a, b, k, l, kappa, lambda) result (val)
263
265 use multidip_params, only: imu
266
267 integer, intent(in) :: lambda, l, b
268 real(wp), intent(in) :: z, a, kappa, k
269
270 real(wp), parameter :: c = 0
271
272 val = (nested_coul_integ(z, a, c, 1, [ b ], [+1, +1], [l, lambda], [cmplx(k, 0, wp), cmplx(kappa, 0, wp)]) &
273 - nested_coul_integ(z, a, c, 1, [ b ], [-1, +1], [l, lambda], [cmplx(k, 0, wp), cmplx(kappa, 0, wp)])) / (2*imu)
274
275 end function acca
276
277
278 !> \brief Far-field part of the double continuum-continuum transition integral
279 !> \authors J Benda
280 !> \date 2024
281 !>
282 !> Asymptotically evaluates the integral
283 !> \f[
284 !> A_{cc}(a) = \int\limits_a^{+\infty} \int\limits_a^{+\infty}
285 !> F_{l_f}(k_f,r) r g_{l_n}^{(+)}(k_n; r, r') r' H_{l_i}^+(k_i,r') dr dr' \,.
286 !> \f]
287 !>
288 complex(wp) function a2cca (Z, a, kf, lf, kn, ln, ki, li) result (val)
289
291 use multidip_params, only: imu
292
293 integer, intent(in) :: li, ln, lf
294 real(wp), intent(in) :: z, ki, kn, kf, a
295
296 real(wp), parameter :: c = 0
297
298 integer :: ls(3)
299 complex(wp) :: ks(3)
300
301 ks(1) = cmplx(ki, 0, wp); ls(1) = li
302 ks(2) = cmplx(kn, 0, wp); ls(2) = ln
303 ks(3) = cmplx(kf, 0, wp); ls(3) = lf
304
305 val = (nested_cgreen_integ(z, a, a, c, 2, +1, +1, [ 1, 1 ], ls, ks) &
306 - nested_cgreen_integ(z, a, a, c, 2, +1, -1, [ 1, 1 ], ls, ks)) / (2*imu)
307
308 end function a2cca
309
310
311 !> \brief Continuum-continuum transition integral
312 !> \authors J Benda
313 !> \date 2024
314 !>
315 !> Calculate integral of regular Coulomb function times r^b times the outgoing Coulomb-Hankel function:
316 !> \f[
317 !> I_{cc} = \int\limits_0^{+\infty} F_l(k,r) r^b H_\lambda^+(\kappa,r) dr \,.
318 !> \f]
319 !>
320 complex(wp) function icc (Z, b, k, l, kappa, lambda) result (val)
321
322 use multidip_params, only: imu
323
324 integer, intent(in) :: lambda, l, b
325 real(wp), intent(in) :: z, kappa, k
326
327 real(wp), parameter :: a = 200
328
329 val = icca(z, a, b, k, l, kappa, lambda) + acca(z, a, b, k, l, kappa, lambda)
330
331 end function icc
332
333
334 !> \brief Two-dimensional continuum-continuum transition integral
335 !> \authors J Benda
336 !> \date 2024
337 !>
338 !> Calculate the integral
339 !> \f[
340 !> I_{cc} = \int\limits_0^{+\infty}\int\limits_0^{+\infty}
341 !> F_{l_f}(k_f,r) r g_{l_n}^{(+)}(k_n;r,r') r' H_{l_i}^+(k_i,r') dr dr' = I_1 + I_2 + I_3 + I_4
342 !> \f]
343 !> by separation into four contributions. The near-field region (\f$ r < a, r' < a \f$) is integrated numerically,
344 !> \f[
345 !> I_1 = \int\limits_0^a \int\limits_0^a F_{l_f}(k_f,r) r g_{l_n}^{(+)}(k_n;r,r') r' H_{l_i}^+(k_i,r') dr dr' \,,
346 !> \f]
347 !> the far-field region is integrated asymptotically,
348 !> \f[
349 !> I_2 = \int\limits_a^{+\infty} \int\limits_a^{+\infty} F_{l_f}(k_f,r)rg_{l_n}^{(+)}(k_n;r,r')r'H_{l_i}^+(k_i,r') drdr'\,,
350 !> \f]
351 !> and the mixed regions factorize into one-dimensional integrals
352 !> \f[
353 !> I_3 = -\frac{2}{k_n} \int\limits_a^{+\infty} F_{l_f}(k_f,r) r H_{l_n}^+(k_n,r) dr
354 !> \int\limits_0^a F_{l_n}(k_n,r') r' H_{l_i}^+(k_n,r') dr' \,,
355 !> \f]
356 !> \f[
357 !> I_4 = -\frac{2}{k_n} \int\limits_0^a F_{l_f}(k_f,r) r F_{l_n}(k_n,r) dr
358 !> \int\limits_0^{+\infty} H_{l_n}^+(k_n,r') r' H_{l_i}^+(k_n,r') dr' \,.
359 !> \f]
360 !>
361 complex(wp) function i2cc (Z, kf, lf, kn, ln, ki, li) result (val)
362
364 use multidip_params, only: imu
365
366 integer, intent(in) :: li, ln, lf
367 real(wp), intent(in) :: z, ki, kn, kf
368
369 real(wp), parameter :: a = 200, b = 250, c = 0
370 logical, parameter :: debug = .false.
371
372 complex(wp) :: i2cca_fni, a2cca_fni, icca_fn, iccb_fn, icca_ni, iccb_ni, acca_fn, acca_ni, a2ccb_fni, accb_fn, accb_ni
373 complex(wp) :: i1, i2, i3, i4
374
375 i2cca_fni = i2cca(z, a, kf, lf, kn, ln, ki, li)
376 a2cca_fni = a2cca(z, a, kf, lf, kn, ln, ki, li)
377
378 icca_fn = aimag(icca(z, a, 1, kf, lf, kn, ln))
379 icca_ni = icca(z, a, 1, kn, ln, ki, li)
380
381 acca_fn = (nested_coul_integ(z, a, c, 1, [ 1 ], [+1, +1], [ln, lf], [cmplx(kn, 0, wp), cmplx(kf, 0, wp)]) &
382 - nested_coul_integ(z, a, c, 1, [ 1 ], [+1, -1], [ln, lf], [cmplx(kn, 0, wp), cmplx(kf, 0, wp)])) / (2*imu)
383 acca_ni = nested_coul_integ(z, a, c, 1, [ 1 ], [+1, +1], [li, ln], [cmplx(ki, 0, wp), cmplx(kn, 0, wp)])
384
385 i1 = i2cca_fni
386 i2 = a2cca_fni
387 i3 = -2/kn*acca_fn*icca_ni
388 i4 = -2/kn*icca_fn*acca_ni
389
390 if (debug) then
391 iccb_fn = aimag(icca(z, b, 1, kf, lf, kn, ln))
392 iccb_ni = icca(z, b, 1, kn, ln, ki, li)
393 a2ccb_fni = a2cca(z, b, kf, lf, kn, ln, ki, li)
394 accb_fn = (nested_coul_integ(z, b, c, 1, [ 1 ], [+1, +1], [ln, lf], [cmplx(kn, 0, wp), cmplx(kf, 0, wp)]) &
395 - nested_coul_integ(z, b, c, 1, [ 1 ], [+1, -1], [ln, lf], [cmplx(kn, 0, wp), cmplx(kf, 0, wp)])) / (2*imu)
396 accb_ni = nested_coul_integ(z, b, c, 1, [ 1 ], [+1, +1], [li, ln], [cmplx(ki, 0, wp), cmplx(kn, 0, wp)])
397 i2 = a2cca_fni - a2ccb_fni + 2/kn*(iccb_fn - icca_fn)*accb_ni + 2/kn*(iccb_ni - icca_ni)*accb_fn
398 i3 = -2/kn*(acca_fn - accb_fn)*icca_ni
399 i4 = -2/kn*icca_fn*(acca_ni - accb_ni)
400 end if
401
402 val = i1 + i2 + i3 + i4
403
404 if (debug) then
405 print '(a)', 'Calculating I2cc'
406 print '(4x,f7.4,i4)', ki, li
407 print '(4x,f7.4,i4)', kn, ln
408 print '(4x,f7.4,i4)', kf, lf
409 print '(4x,a,*(e25.15))', 'I1 ', i1
410 print '(4x,a,*(e25.15))', 'I2 ', i2
411 print '(4x,a,*(e25.15))', 'I3 ', i3
412 print '(4x,a,*(e25.15))', 'I4 ', i4
413 print '(4x,a,*(e25.15))', 'val ', val
414 end if
415
416 end function i2cc
417
418
419 !> \brief Partial-wave-dependent asymptotic correction
420 !> \authors J Benda
421 !> \date 2024
422 !>
423 !> Approximate correcting factor for calculation of two-photon matrix element from a one-photon matrix element.
424 !>
425 complex(wp) function akkl (kappa, lambda, k, l, b)
426
427 use multidip_params, only: imu
428 use multidip_special, only: cphase
429
430 integer, intent(in) :: lambda, l, b
431 real(wp), intent(in) :: kappa, k
432
433 real(wp) :: sigma, z = 1
434
435 sigma = cphase(z, l, k) - cphase(z, lambda, kappa)
436 akkl = 2/sqrt(kappa*k) * imu**(lambda - l) * exp(imu*sigma) * icc(z, b, k, l, kappa, lambda)
437
438 end function akkl
439
440
441 !> \brief Third-order asymptotic correction
442 !> \authors J Benda
443 !> \date 2024
444 !>
445 complex(wp) function akkl3 (ki, li, kn, ln, kf, lf)
446
447 use multidip_params, only: imu
448 use multidip_special, only: cphase
449
450 integer, intent(in) :: li, ln, lf
451 real(wp), intent(in) :: ki, kn, kf
452
453 real(wp) :: sigma, z = 1
454
455 sigma = cphase(z, lf, kf) - cphase(z, li, ki)
456 akkl3 = 2/sqrt(kf*ki) * imu**(li - lf) * exp(imu*sigma) * i2cc(z, kf, lf, kn, ln, ki, li)
457
458 end function akkl3
459
460
461 !> \brief Prefactor in asymptotic 2-photon matrix element
462 !> \author J Benda
463 !> \date 2021 - 2024
464 !>
465 !> Target-independent complex prefactor in the 2-photon ionization matrix element as obtained
466 !> in the asymptotic theory of Dahlström et al (2013), including the long-range amplitude correction.
467 !>
468 complex(wp) function akk (kappa, k, l, cc)
469
470 use multidip_params, only: imu, pi
472
473 real(wp), intent(in) :: kappa, k
474 integer, intent(in) :: l, cc
475
476 complex(wp) :: g
477 real(wp) :: eta, z = 1
478
479 if (cc == 2) then
480 ! hydrogen s-p-s correction (or s-p-p if l = 0)
481 akk = 2/kappa * m2_h1s(l, 1, kappa, 1 - l, k) / (exp(imu*cphase(z, 1, kappa)) * m1_h1s(1, kappa))
482 return
483 end if
484
485 if (cc == 3) then
486 ! exact continuum-continuum transition integral for p-s pathway
487 akk = akkl(kappa, 1, k, 0, l)
488 return
489 end if
490
491 eta = z/kappa - z/k
492 g = complex_gamma(l, eta)
493
494 akk = exp(-eta*pi/2)/sqrt(kappa*k) * (imu/(kappa - k))**(l + 1) &
495 * (2*kappa)**(imu/kappa)/(2*k)**(imu/k) * g / (kappa - k)**(imu*eta)
496
497 if (cc == 1) then
498 ! long-range amplitude correction
499 akk = akk * (1 + imu/2*(1/kappa**2 + 1/k**2)*(kappa - k)/cmplx(1, 1/kappa - 1/k, wp))
500 end if
501
502 end function akk
503
504
505 !> \brief Two-photon ionization of hydrogen atom
506 !> \authors J Benda
507 !> \date 2024
508 !>
509 !> Evaluate the full partial amplitude of two-photon ionization of hydrogen atom from the ground state via the
510 !> s→p→lf angular momentum pathway. The result is proportional to a double indefinite integral, but one of the
511 !> integrations is effectively definite due to the exponential decay of the hydrogen bound state wave function.
512 !> Disregarding some normalization factors we have
513 !> \f[
514 !> M_l^{(2)} = i^{-l} e^{i\sigma_l} \int_0^\infty \int_0^\infty F_l(r) r^b F_1(r_<) H_1^+(r_>) r' P_{10}(r') dr dr'.
515 !> \f]
516 !> The integral can be decomposed into two contributions, the finite-range double integral
517 !> \f[
518 !> I = \int_0^a \int_0^a F_l(r) r^b F_1(r_<) H_1^+(r_>) r' P_{10}(r') dr dr',
519 !> \f]
520 !> which is integrated by means of a two-dimensional Romberg quadrature, and the product of two one-dimensional
521 !> integrals
522 !> \f[
523 !> J = \int_a^\infty F_l(r) r^b H_1^+(r) dr \int_0^\infty F_1(r) r P_{10}(r) dr ,
524 !> \f]
525 !> of which the first is integrated by asymptotic integration routine from MULTIDIP and the second has a closed
526 !> form. The radius "a" has to be sufficiently large so that the electron density of the bound state vanishes and
527 !> also to make sure that the asymptotic integration gives meaningful results. In the present implementation it
528 !> is set to 100 atomic units.
529 !>
530 complex(wp) function m2_h1s (b, ln, kn, lf, kf) result (M2)
531
533 use multidip_params, only: imu
534 use multidip_special, only: coulh, cphase
535
536 real(wp), intent(in) :: kn, kf
537 integer, intent(in) :: b, ln, lf
538
539 real(wp), parameter :: a = 200 ! inner region size
540 real(wp), parameter :: c = 0 ! damping factor
541 integer, parameter :: mmax = 13 ! log2 of the maximal number of 2D quadrature points in each dimension
542
543 real(wp), allocatable :: flf(:), f1n(:), g1n(:), p1s(:)
544
545 integer :: i, j, qi, qj, m, n, stride
546 complex(wp) :: ia, ii, ij, hlf, h1n, romb(0:mmax, 0:mmax)
547 real(wp) :: ib, dr, ri, rj, wt, nu, z = 1
548
549 nu = 2
550
551 ! evaluate the separated part
552 ia = (nested_coul_integ(z, a, c, 1, [ b ], [+1, +1], [lf, ln], [cmplx(kf, 0, wp), cmplx(kn, 0, wp)]) &
553 - nested_coul_integ(z, a, c, 1, [ b ], [-1, +1], [lf, ln], [cmplx(kf, 0, wp), cmplx(kn, 0, wp)])) / (2*imu)
554 ib = m1_h1s(ln, kn)
555 ij = ia*ib
556
557 ! allocate workspaces for the double integral
558 ! - the zeroth index corresponds to left boundary of the integration domain where the integrand is zero, so it is not used
559 ! neither allocated
560 ! - the last index corresponds to the right boundary
561 allocate (flf(2**mmax), f1n(2**mmax), g1n(2**mmax), p1s(2**mmax))
562
563 ! obtain all needed function values
564 do i = 1, 2**mmax
565 ri = i*a/2**mmax
566 hlf = coulh(z, +1, lf, kf*kf/2, ri)
567 h1n = coulh(z, +1, ln, kn*kn/2, ri)
568 flf(i) = aimag(hlf)
569 f1n(i) = aimag(h1n)
570 g1n(i) = real(h1n)
571 p1s(i) = 2 * ri**ln * exp(-nu*ri)
572 end do
573
574 ! loop over all subdivision levels for the double integral
575 ii = 0
576 romb = 0
577 do m = 0, mmax
578
579 ! define grid spacing at this subdivision level
580 n = 2**m
581 stride = 2**(mmax - m)
582 dr = a/n
583
584 ! apply nested 2D trapezoidal quadrature rule
585 do i = 1, n
586 ri = i*dr
587 qi = i*stride
588 do j = i, n
589 rj = j*dr
590 qj = j*stride
591 if (mod(i, 2) /= 0 .or. mod(j, 2) /= 0) then
592 wt = 1._wp/(1 + merge(1, 0, i == n) + merge(1, 0, j == n))
593 ii = ii + wt*flf(qi)*ri**b*f1n(qi)*(g1n(qj) + imu*f1n(qj))*rj*p1s(qj)
594 if (i /= j) then
595 ii = ii + wt*flf(qj)*rj**b*(g1n(qj) + imu*f1n(qj))*f1n(qi)*ri*p1s(qi)
596 end if
597 end if
598 end do
599 end do
600
601 ! update Richardson extrapolation table
602 romb(m, 0) = ii*dr*dr
603 do n = 1, m
604 do i = n, m
605 romb(i, n) = (4**n*romb(i, n - 1) - romb(i - 1, n - 1))/(4**n - 1)
606 end do
607 end do
608
609 end do
610
611 ii = romb(mmax, mmax)
612 m2 = imu**(-lf) * exp(imu*cphase(z, lf, kf)) * (ii + ij)
613
614 end function m2_h1s
615
616end module multidip_asy
Asymptotic approximation of multi-photon matrix elements.
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.
Levin quadrature for numerical integration.
complex(wp) function levin_adapt(z, ra, rb, c, m, s1, s2, l1, l2, k1, k2)
One-dimensional adaptive Levin integration.
Hard-coded parameters of MULTIDIP.
real(wp), parameter pi
real(wp) epsrel
Romberg integration relative tolerance for convergence.
complex(wp), parameter imu
Special functions and objects used by MULTIDIP.
recursive complex(wp) function complex_gamma(l, x)
Complex Gamma function.
real(wp) function cphase(z, l, k)
Coulomb phase.
subroutine coul(z, l, ek, r, f, fp, g, gp)
Coulomb functions.