Multidip  1.0
Multi-photon matrix elements
multidip_tests.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 !
29 
30  use precisn_gbl, only: wp
31 
32  implicit none
33 
34 contains
35 
42  subroutine run_tests
43 
44  print '(/,A)', 'Running all tests'
45 
47  call test_coul
48  call test_1p_eint
49  call test_1p_cint
50  call test_2p_cint
51  call test_2p_gint
52 
53  end subroutine run_tests
54 
55 
63  subroutine test_permutations
64 
66 
67  integer :: i, order(4)
68 
69  order = -1
70 
71  print '(/,A,/)', 'Testing permutations of 4 elements...'
72 
73  i = 0
74  do while (next_permutation(order))
75  i = i + 1
76  print '(A,I2,A,*(1x,I0))', ' ', i, ':', order
77  end do
78 
79  end subroutine test_permutations
80 
81 
89  subroutine test_coul
90 
91  use multidip_params, only: ntermsasy
93 
94  real(wp) :: r = 100, f, fp, g1, g1p, g2, g2p, g3, g3p, k, a, b
95  real(wp) :: Ek(4) = [ -1.000, -0.100, -0.010, -0.001 ]
96  integer :: ls(3) = [ 0, 1, 2 ], ipw, ie, n, l
97 
98  print '(/,A)', 'Testing Whittaker functions'
99  print '(/,2x,A,3x,A,7x,A,20x,A,19x,A,17x,A,16x,A,20x,A)', 'l', 'Ek', 'GSL W', 'GSL W''', 'UKRmol W', 'UKRmol W''', &
100  'asy W', 'asy W'''
101 
102  do ie = 1, size(ek)
103  k = sqrt(-2*ek(ie))
104  do ipw = 1, size(ls)
105  l = ls(ipw)
106  call coul_gsl(l, ek(ie), r, f, fp, g1, g1p)
107  call coul_ukrmol(l, ek(ie), r, f, fp, g2, g2p)
108  f = 1; g3 = 0
109  do n = 0, ntermsasy
110  if (n > 0) f = f * (l + 1 - 1/k + n - 1) * (-l - 1/k + n - 1) / n / (-2*k*r)
111  g3 = g3 + f
112  g3p = g3p + (1/k - n)/r * f
113  end do
114  g3p = exp(-k*r) * (2*k*r)**(1/k) * (-k*g3 + g3p)
115  g3 = exp(-k*r) * (2*k*r)**(1/k) * g3
116  print '(I3,F8.3,6E25.15)', l, ek(ie), g1, g1p, g2, g2p, g3, g3p
117  end do
118  end do
119 
120  end subroutine test_coul
121 
122 
129  subroutine test_1p_eint
132 
133  real(wp) :: a = 150, c = 0
134  real(wp) :: k1(2) = [ 0.011080185297_wp, 0.680747949322_wp ]
135  real(wp) :: k2(2) = [ 1.069105413537_wp, 1.438602233160_wp ]
136 
137  integer :: ie, m, s2, ms(1), ss(2)
138 
139  complex(wp) :: ks(2), integ
140  complex(wp) :: reference(2,3,2) = reshape([(-4.772929e-01_wp, +8.885647e+01_wp), (-8.424650e-04_wp, +5.923864e-01_wp), &
141  (+9.979744e-06_wp, +3.949186e-03_wp), (+1.307372e+00_wp, +3.240230e+02_wp), &
142  (+3.965361e-02_wp, +2.158463e+00_wp), (+4.697322e-04_wp, +1.437268e-02_wp), &
143  (-2.211202e-01_wp, +7.029786e+01_wp), (-9.899674e-06_wp, +4.686525e-01_wp), &
144  (+9.695004e-06_wp, +3.124290e-03_wp), (-1.752969e+00_wp, +1.992839e+02_wp), &
145  (+8.061387e-05_wp, +1.328557e+00_wp), (+7.894722e-05_wp, +8.855647e-03_wp)], &
146  [2, 3, 2])
147 
148  print '(/,A)', 'Testing one-photon exponential integrals'
149  print '(/,2x,A,1x,A,1x,A,2x,A,12x,A,13x,A,2x,A,3x,A,4x,A)', 'm', 's2', 's1', 'k2', 'k1', &
150  're calculated', 'im calculated', 're reference', 'im reference'
151 
152  do ie = 1, size(k1)
153  do m = 0, 2
154  do s2 = 1, 2
155 
156  ms = [ 1 - m ]
157  ss = [ (-1)**(s2+1), +1 ]
158  ks = [ k1(ie), k2(ie) ]
159 
160  integ = nested_exp_integ(a, c, 1, ms, ss, ks)
161 
162  print '(SP,3I3,SS,2F14.10,SP,4E16.7)', ms(1), ss(2), ss(1), real(ks(2),wp), real(ks(1),wp), &
163  real(integ, wp), aimag(integ), real(reference(s2,m+1,ie), wp), aimag(reference(s2,m+1,ie))
164  end do
165  end do
166  end do
167 
168  end subroutine test_1p_eint
169 
170 
177  subroutine test_1p_cint
180 
181  real(wp) :: a = 150, c = 0
182  real(wp) :: k1(2) = [ 0.011080185297_wp, 0.680747949322_wp ]
183  real(wp) :: k2(2) = [ 1.069105413537_wp, 1.438602233160_wp ]
184 
185  integer :: ie, ipw, s2, ms(1), ss(2), ls(2)
186  integer :: l1(8) = [ 1, 1, 3, 1, 3, 3, 3, 3 ]
187  integer :: l2(8) = [ 0, 2, 2, 2, 2, 4, 2, 4 ]
188 
189  complex(wp) :: ks(2), integ
190  complex(wp) :: reference(2,8,2) = reshape([(-3.454030e+13_wp, +1.290212e+14_wp), (+4.518674e+14_wp, +1.770164e+14_wp), &
191  (-1.054015e+14_wp, -8.206518e+13_wp), (-3.390989e+14_wp, +3.473927e+14_wp), &
192  (-1.012103e+14_wp, -8.818320e+13_wp), (-3.209952e+14_wp, +3.673575e+14_wp), &
193  (-1.054015e+14_wp, -8.206518e+13_wp), (-3.390989e+14_wp, +3.473927e+14_wp), &
194  (-1.012103e+14_wp, -8.818320e+13_wp), (-3.209952e+14_wp, +3.673575e+14_wp), &
195  (+1.307948e+14_wp, +3.038993e+13_wp), (+1.111367e+14_wp, -4.753884e+14_wp), &
196  (-1.012103e+14_wp, -8.818320e+13_wp), (-3.209952e+14_wp, +3.673575e+14_wp), &
197  (+1.307948e+14_wp, +3.038993e+13_wp), (+1.111367e+14_wp, -4.753884e+14_wp), &
198  (-6.382646e+01_wp, +2.799838e+01_wp), (+7.071896e+01_wp, +1.844497e+02_wp), &
199  (+1.584632e+01_wp, -6.787748e+01_wp), (-1.900621e+02_wp, -5.395706e+01_wp), &
200  (+5.054597e+01_wp, +4.803432e+01_wp), (+4.962959e+01_wp, +1.911980e+02_wp), &
201  (+1.584632e+01_wp, -6.787748e+01_wp), (-1.900621e+02_wp, -5.395706e+01_wp), &
202  (+5.054597e+01_wp, +4.803432e+01_wp), (+4.962959e+01_wp, +1.911980e+02_wp), &
203  (-6.443654e+01_wp, -2.668020e+01_wp), (-1.150300e+02_wp, -1.606738e+02_wp), &
204  (+5.054597e+01_wp, +4.803432e+01_wp), (+4.962959e+01_wp, +1.911980e+02_wp), &
205  (-6.443654e+01_wp, -2.668020e+01_wp), (-1.150300e+02_wp, -1.606738e+02_wp)], &
206  [2, 8, 2])
207 
208  print '(/,A)', 'Testing one-photon Coulomb integrals'
209  print '(/,1x,A,1x,A,1x,A,2x,A,12x,A,13x,A,2x,A,3x,A,4x,A)', 's2', 'l2', 'l1', 'k2', 'k1', &
210  're calculated', 'im calculated', 're reference', 'im reference'
211 
212  do ie = 1, size(k1)
213  do ipw = 1, size(l1)
214  do s2 = 1, 2
215 
216  ms = [ 1 ]
217  ss = [ (-1)**(s2+1), +1 ]
218  ls = [ l1(ipw), l2(ipw) ]
219  ks = [ k1(ie), k2(ie) ]
220 
221  integ = nested_coul_integ(a, c, 1, ms, ss, ls, ks)
222 
223  print '(SP,I3,SS,2I3,2F14.10,SP,4E16.7)', (-1)**(s2+1), l2(ipw), l1(ipw), k2(ie), k1(ie), &
224  real(integ, wp), aimag(integ), real(reference(s2,ipw,ie), wp), aimag(reference(s2,ipw,ie))
225  end do
226  end do
227  end do
228 
229  end subroutine test_1p_cint
230 
231 
238  subroutine test_2p_cint
241 
242  real(wp) :: a = 150, c = 0
243 
244  real(wp) :: k1(2) = [ 0.011080185297_wp, 0.680747949322_wp ]
245  real(wp) :: k2(2) = [ 1.069105413537_wp, 1.438602233160_wp ]
246  real(wp) :: k3(2) = [ 1.511902774652_wp, 1.917220644579_wp ]
247 
248  integer :: l1(8) = [ 1, 1, 3, 1, 3, 3, 3, 3 ]
249  integer :: l2(8) = [ 0, 2, 2, 2, 2, 4, 2, 4 ]
250  integer :: l3(8) = [ 1, 1, 1, 3, 3, 3, 3, 3 ]
251 
252  integer :: ie, ipw, s4, ms(2), ss(4), ls(4)
253 
254  complex(wp) :: ks(4), integ1, integ2, integ
255  complex(wp) :: reference(2,8,2) = reshape([(-1.465883e+16_wp, -4.950701e+15_wp), (-3.842765e+16_wp, 8.620168e+16_wp), &
256  (-1.466146e+16_wp, -4.951551e+15_wp), (-3.843793e+16_wp, 8.623263e+16_wp), &
257  (-1.443664e+16_wp, -5.780723e+15_wp), (-3.378946e+16_wp, 8.865409e+16_wp), &
258  ( 1.520251e+16_wp, -2.902864e+15_wp), (-8.964058e+15_wp, -9.400575e+16_wp), &
259  ( 1.541476e+16_wp, -2.070261e+15_wp), (-1.420349e+16_wp, -9.382680e+16_wp), &
260  ( 1.542117e+16_wp, -2.071208e+15_wp), (-1.422236e+16_wp, -9.390101e+16_wp), &
261  ( 1.541476e+16_wp, -2.070261e+15_wp), (-1.420349e+16_wp, -9.382680e+16_wp), &
262  ( 1.542117e+16_wp, -2.071208e+15_wp), (-1.422236e+16_wp, -9.390101e+16_wp), &
263  (-4.322904e+03_wp, -4.890496e+03_wp), (-2.301503e+04_wp, 1.829823e+04_wp), &
264  (-4.323345e+03_wp, -4.890988e+03_wp), (-2.301886e+04_wp, 1.830140e+04_wp), &
265  ( 6.409175e+03_wp, -1.254518e+03_wp), ( 2.742317e+04_wp, 1.058896e+04_wp), &
266  ( 5.914821e+03_wp, 2.763232e+03_wp), ( 1.382079e+04_wp, -2.596191e+04_wp), &
267  (-5.378829e+03_wp, 3.705000e+03_wp), (-2.937519e+04_wp, 1.216512e+03_wp), &
268  (-5.380092e+03_wp, 3.705885e+03_wp), (-2.938678e+04_wp, 1.217206e+03_wp), &
269  (-5.378829e+03_wp, 3.705000e+03_wp), (-2.937519e+04_wp, 1.216512e+03_wp), &
270  (-5.380092e+03_wp, 3.705885e+03_wp), (-2.938678e+04_wp, 1.217206e+03_wp)], &
271  [2, 8, 2])
272 
273  print '(/,A)', 'Testing two-photon Coulomb integrals'
274  print '(/,4(1x,A),2x,A,12x,A,12x,A,12x,A,3x,A,3x,A,4x,A)', 's4', 'l3', 'l2', 'l1', 'k3', 'k2', 'k1', &
275  're calculated', 'im calculated', 're reference', 'im reference'
276 
277  do ie = 1, size(k1)
278  do ipw = 1, size(l1)
279  do s4 = 1, 2
280 
281  ms = [ 1, 1 ]
282 
283  ss = [ (-1)**(s4+1), +1, -1, +1 ]
284  ls = [ l1(ipw), l2(ipw), l2(ipw), l3(ipw) ]
285  ks = [ k1(ie), k2(ie), k2(ie), k3(ie) ]
286 
287  integ1 = nested_coul_integ(a, c, 2, ms, ss, ls, ks)
288 
289  ss = [ +1, +1, -1, (-1)**(s4+1) ]
290  ls = [ l3(ipw), l2(ipw), l2(ipw), l1(ipw) ]
291  ks = [ k3(ie), k2(ie), k2(ie), k1(ie) ]
292 
293  integ2 = nested_coul_integ(a, c, 2, ms, ss, ls, ks)
294 
295  integ = integ1 + integ2
296 
297  print '(SP,I3,SS,3I3,3F14.10,SP,4E16.7)', (-1)**(s4+1), l3(ie), l2(ipw), l1(ipw), k3(ie), k2(ie), k1(ie), &
298  real(integ, wp), aimag(integ), real(reference(s4,ipw,ie), wp), aimag(reference(s4,ipw,ie))
299  end do
300  end do
301  end do
302 
303  end subroutine test_2p_cint
304 
305 
312  subroutine test_2p_gint
315 
316  real(wp) :: a = 150, c = 0
317 
318  real(wp) :: k1(2) = [ 0.011080185297_wp, 0.680747949322_wp ]
319  real(wp) :: k2(2) = [ 1.069105413537_wp, 1.438602233160_wp ]
320  real(wp) :: k3(2) = [ 1.511902774652_wp, 1.917220644579_wp ]
321 
322  integer :: l1(8) = [ 1, 1, 3, 1, 3, 3, 3, 3 ]
323  integer :: l2(8) = [ 0, 2, 2, 2, 2, 4, 2, 4 ]
324  integer :: l3(8) = [ 1, 1, 1, 3, 3, 3, 3, 3 ]
325 
326  integer :: ie, ipw, s4, ms(2), ls(3)
327 
328  complex(wp) :: ks(3), integ1, integ2
329  complex(wp) :: reference(2,2,8,2) = reshape([(-8.310927e+15_wp, 7.523384e+15_wp), (-5.909915e+16_wp, 6.931934e+16_wp), &
330  ( 5.679523e+16_wp, 4.672527e+16_wp), ( 8.225897e+24_wp, 1.848188e+24_wp), &
331  (-6.506509e+15_wp, 2.066669e+16_wp), (-1.618385e+16_wp, 4.224605e+15_wp), &
332  ( 1.050096e+17_wp, 4.554189e+16_wp), (-4.312479e+24_wp, -7.240598e+24_wp), &
333  (-7.673705e+15_wp, 2.037601e+16_wp), (-1.647265e+16_wp, 3.342092e+15_wp), &
334  ( 1.078882e+17_wp, 3.987695e+16_wp), (-4.728274e+24_wp, -7.026109e+24_wp), &
335  (-4.503787e+15_wp, -2.119630e+16_wp), ( 1.619053e+16_wp, 4.287343e+15_wp), &
336  (-1.138495e+17_wp, 1.201762e+16_wp), ( 2.556995e+23_wp, 8.432496e+24_wp), &
337  (-3.344463e+15_wp, -2.151751e+16_wp), ( 1.600768e+16_wp, 5.199000e+15_wp), &
338  (-1.135684e+17_wp, 1.836697e+16_wp), ( 7.238276e+23_wp, 8.446832e+24_wp), &
339  (-8.612323e+15_wp, -1.723199e+16_wp), ( 3.535435e+16_wp, 4.008848e+16_wp), &
340  (-9.807095e+16_wp, 3.755844e+16_wp), ( 7.275593e+24_wp, 4.341652e+24_wp), &
341  (-3.344463e+15_wp, -2.151751e+16_wp), ( 1.600768e+16_wp, 5.199000e+15_wp), &
342  (-1.135684e+17_wp, 1.836697e+16_wp), ( 7.238276e+23_wp, 8.446832e+24_wp), &
343  (-8.612323e+15_wp, -1.723199e+16_wp), ( 3.535435e+16_wp, 4.008848e+16_wp), &
344  (-9.807095e+16_wp, 3.755844e+16_wp), ( 7.275593e+24_wp, 4.341652e+24_wp), &
345  (-1.247516e+03_wp, 3.118370e+03_wp), (-2.763140e+04_wp, 1.784564e+04_wp), &
346  ( 1.332880e+04_wp, 9.920923e+03_wp), ( 6.345060e+03_wp, 4.578023e+04_wp), &
347  (-3.896753e+03_wp, 9.080720e+02_wp), (-6.662204e+03_wp, 3.014237e+04_wp), &
348  ( 6.717303e+03_wp, 1.712697e+04_wp), ( 4.397613e+04_wp, -1.193480e+04_wp), &
349  ( 1.189054e+03_wp, -3.822275e+03_wp), (-2.263210e+04_wp, -2.099869e+04_wp), &
350  ( 1.136951e+04_wp, -1.445428e+04_wp), (-3.253996e+04_wp, -3.189015e+04_wp), &
351  ( 3.212357e+03_wp, -2.385969e+03_wp), ( 1.813020e+04_wp, -2.499891e+04_wp), &
352  (-1.298806e+04_wp, -1.303291e+04_wp), (-4.510261e+04_wp, -6.582287e+03_wp), &
353  ( 4.327121e+02_wp, 3.979850e+03_wp), ( 1.239242e+04_wp, 2.828936e+04_wp), &
354  (-4.667920e+03_wp, 1.779027e+04_wp), ( 1.713954e+04_wp, 4.222912e+04_wp), &
355  ( 1.147174e+03_wp, 5.355515e+03_wp), ( 1.429665e+04_wp, 1.753491e+04_wp), &
356  (-5.010378e+03_wp, 2.217364e+04_wp), ( 3.781810e+04_wp, 1.923663e+04_wp), &
357  ( 4.327121e+02_wp, 3.979850e+03_wp), ( 1.239242e+04_wp, 2.828936e+04_wp), &
358  (-4.667920e+03_wp, 1.779027e+04_wp), ( 1.713954e+04_wp, 4.222912e+04_wp), &
359  ( 1.147174e+03_wp, 5.355515e+03_wp), ( 1.429665e+04_wp, 1.753491e+04_wp), &
360  (-5.010378e+03_wp, 2.217364e+04_wp), ( 3.781810e+04_wp, 1.923663e+04_wp)], &
361  [2,2,8,2])
362 
363  print '(/,A)', 'Testing two-photon Green integrals'
364  print '(/,5(1x,A),2x,A,12x,A,12x,A,12x,A,3x,A,3x,A,4x,A)', 's4', 's1', 'l3', 'l2', 'l1', 'k3', 'k2', 'k1', &
365  're calculated', 'im calculated', 're reference', 'im reference'
366 
367  do ie = 1, size(k1)
368  do ipw = 1, size(l1)
369  do s4 = 1, 2
370 
371  ms = [ 1, 1 ]
372  ls = [ l1(ipw), l2(ipw), l3(ipw) ]
373  ks = [ k1(ie), k2(ie), k3(ie) ]
374 
375  integ1 = nested_cgreen_integ(a, c, 2, (-1)**(s4+1), +1, ms, ls, ks)
376  integ2 = nested_cgreen_integ(a, c, 2, (-1)**(s4+1), -1, ms, ls, ks)
377 
378  print '(SP,2I3,SS,3I3,3F14.10,SP,8E16.7)', (-1)**(s4+1), +1, l3(ipw), l2(ipw), l1(ipw), k3(ie), k2(ie), k1(ie),&
379  real(integ1, wp), aimag(integ1), real(reference(1,s4,ipw,ie), wp), aimag(reference(1,s4,ipw,ie))
380  print '(SP,2I3,SS,3I3,3F14.10,SP,8E16.7)', (-1)**(s4+1), -1, l3(ipw), l2(ipw), l1(ipw), k3(ie), k2(ie), k1(ie),&
381  real(integ2, wp), aimag(integ2), real(reference(2,s4,ipw,ie), wp), aimag(reference(2,s4,ipw,ie))
382  end do
383  end do
384  end do
385  end subroutine test_2p_gint
386 
387 end module multidip_tests
complex(wp) function nested_exp_integ(a, c, N, m, s, k)
Multi-dimensional triangular integral of exponentials and powers.
subroutine coul_gsl(l, Ek, r, F, Fp, G, Gp)
Coulomb functions (GSL)
complex(wp) function nested_coul_integ(a, c, N, m, s, l, k)
Multi-dimensional triangular integral of Coulomb-Hankel functions and powers.
subroutine test_2p_cint
Two-photon Coulomb integral unit tests.
subroutine run_tests
Numerical unit tests.
MULTIDIP unit tests.
subroutine coul_ukrmol(l, Ek, r, F, Fp, G, Gp)
Coulomb functions (UKRmol)
logical function next_permutation(p)
Construct or advance permutation.
subroutine test_1p_eint
One-photon exponential integral unit tests.
Hard-coded parameters of MULTIDIP.
Special integrals needed by MULTIDIP.
subroutine test_1p_cint
One-photon Coulomb integral unit tests.
Special functions and objects used by MULTIDIP.
subroutine test_2p_gint
Two-photon Green integral unit tests.
complex(wp) function nested_cgreen_integ(a, c, N, sa, sb, m, l, k)
Multi-dimensional integral of Coulomb-Hankel and Coulomb-Green functions and powers.
integer, parameter ntermsasy
Number of terms in expansion of the Coulomb-Hankel functions.
subroutine test_permutations
Permutations unit tests.
subroutine test_coul
Negative-energy Coulomb function tests.