28 use,
intrinsic :: iso_c_binding, only: c_double, c_int, c_f_pointer
29 use,
intrinsic :: iso_fortran_env, only: input_unit, int32, int64, real64, output_unit
31 #ifdef HAVE_NO_FINDLOC
33 use algorithms,
only: findloc
37 use blas_lapack_gbl,
only: blasint
38 use phys_const_gbl,
only: pi, imu, to_ev
39 use precisn_gbl,
only: wp
63 real(wp),
allocatable :: ck(:, :, :)
69 real(wp),
allocatable :: ap(:, :, :)
77 real(wp),
allocatable :: dip(:, :, :)
103 use,
intrinsic :: iso_c_binding, only: c_ptr
105 use mpi_gbl,
only: comm_rank => myrank, comm_size => nprocs, mpi_mod_finalize, mpi_mod_start, mpi_xermsg
115 type(
kmatrix),
allocatable :: km(:)
118 character(len=256) :: arg, rmt_data, raw, msg
121 integer :: order, nirr, lusct(8), lukmt(8), lubnd, nkset(8), iarg, narg, input, i, erange(2)
122 logical :: verbose, mpiio
123 real(wp) :: omega(nMaxPhotons), first_IP, rasym
124 complex(wp) :: polar(3, nMaxPhotons)
126 call print_ukrmol_header(output_unit)
128 print
'(/,A)',
'Program MULTIDIP: Calculation of multi-photon ionization'
131 narg = command_argument_count()
135 dummy = gsl_set_error_handler_off()
138 do while (iarg <= narg)
139 call get_command_argument(iarg, arg)
140 if (arg ==
'--test')
then
143 else if (arg ==
'--input')
then
145 call get_command_argument(iarg, arg)
146 open (input, file = trim(arg), action =
'read', form =
'formatted')
147 else if (arg ==
'--help')
then
148 print
'(/,A,/)',
'Available options:'
149 print
'(A)',
' --help display this help and exit'
150 print
'(A)',
' --input FILE use FILE as the input file (instead of standard input)'
151 print
'(A)',
' --test run internal sanity checks and exit'
155 write (msg,
'(3a)')
'Unknown command line argument "', trim(arg),
'"'
156 call mpi_xermsg(
'multidip_routines',
'multidip_main', trim(msg), 1, 1)
161 call read_input_namelist(input, order, lusct, lukmt, lubnd, nkset, polar, omega, verbose, rmt_data, first_ip, rasym, raw, &
164 if (input /= input_unit)
close (input)
170 print
'(/,A,I0,A,I0)',
'Parallel mode; image ',
myproc,
' of ',
nprocs
172 print
'(/,A,/)',
'Absorbed photons'
174 print
'(2x,A,I0,3x,A,SP,2F6.3,A,2F6.3,A,2F6.3,A,F0.3,A)', &
175 '#', i,
'eX: ', polar(1, i),
'i, eY: ', polar(2, i),
'i, eZ: ', polar(3, i),
'i, energy: ', omega(i) * to_ev,
' eV'
178 if (first_ip > 0)
then
179 print
'(/,A,F0.5,A)',
'Override first IP to ', first_ip * to_ev,
' eV'
181 print
'(/,A)',
'Use calculated IP'
184 nirr = count(lukmt > 0)
188 if (any(lusct > 0))
then
196 if (any(erange /= 0))
then
197 if (erange(1) < 1 .or. erange(1) > erange(2) .or. erange(2) > minval(km % nescat))
then
198 print
'(/,A,I0)',
'Error: Energy range must satisfy 1 <= erange(1) <= erange(2) <= ', minval(km % nescat)
202 erange(2) = minval(km % nescat)
205 if (rasym > moldat % rmatr)
then
207 write (*,
'(/,A,F0.1,A,F0.1,A)', advance =
'no')
'Interval ', moldat % rmatr,
' to ', rasym, &
208 ' will be integrated numerically using '
210 case (1); print
'(a)',
'Romberg quadrature'
211 case (2); print
'(a)',
'Levin quadrature'
214 call mpi_xermsg(
'multidip_routines',
'multidip_main', &
215 'Error: Numerical integration (rasym) is currently only implemented for the second order.', 1, 1)
219 call multidip_driver(order, moldat, km, ak, lubnd, omega(1:order), polar(:, 1:order), verbose, first_ip, rasym, raw, erange)
221 call mpi_mod_finalize
257 subroutine multidip_driver (order, moldat, km, ak, lubnd, omega, polar, verbose, first_IP, r0, raw, erange)
263 integer,
intent(in) :: order, erange(2), lubnd
264 logical,
intent(in) :: verbose
266 type(
kmatrix),
allocatable,
intent(in) :: km(:)
268 real(wp),
intent(in) :: omega(:), first_IP, r0
269 complex(wp),
intent(in) :: polar(:, :)
270 character(len=*),
intent(in) :: raw
274 integer,
allocatable :: iidip(:), ifdip(:)
275 real(wp),
allocatable :: escat(:)
277 integer :: j, s, mgvni, mgvnn, mgvn1, mgvn2, nesc, irri, iki, icomp, nstati, nchani, max_dim
281 mgvni = km(iki) % mgvn
282 nesc = erange(2) - erange(1) + 1
283 irri = findloc(moldat % mgvns, mgvni, 1)
284 nstati = moldat % mnp1(irri)
285 nchani = moldat % nchan(irri)
288 allocate (states % ck(nstati, 2, (nesc +
nprocs - 1) /
nprocs))
289 allocate (states % ap(nchani, 2, (nesc +
nprocs - 1) /
nprocs))
303 print
'(/,2(A,I0))',
'Photon ', j,
' of ', order
311 do s = 1,
size(iidip)
318 do while (
associated(state))
321 if (state % order + 1 == j)
then
327 if ((mgvnn == mgvn1 .or. mgvnn == mgvn2) .and. &
328 any(km(:) % mgvn == mgvn1) .and. &
329 any(km(:) % mgvn == mgvn2))
then
334 mgvn1, mgvn2, km, state, verbose, ei, first_ip, r0, erange)
337 mgvn1, mgvn2, km, ak, state, verbose, ei, first_ip, r0, erange)
345 state => state % next
356 escat = km(iki) % escat(erange(1):erange(2))
363 do while (
associated(state % next))
364 state => state % next
365 deallocate (state % prev)
393 integer,
intent(in) :: irr, lubnd
394 real(wp),
intent(out) :: Ei
396 complex(wp),
allocatable :: ap(:)
397 real(wp),
allocatable :: Ek(:), bnd(:, :), wbnd(:, :), fc(:), gc(:), fcp(:), gcp(:)
399 integer :: mye, nmye, nchan, nstat, ichan, stot, mgvn, nbnd
401 nmye =
size(states % ck, 3)
402 mgvn = moldat % mgvns(irr)
403 stot = moldat % stot(irr)
404 nchan = moldat % nchan(irr)
405 nstat = moldat % mnp1(irr)
408 ei = moldat % eig(1, irr)
415 allocate (bnd(nstat, nbnd))
425 states % ck(:, 1, mye) = bnd(:, 1)
426 states % ck(:, 2, mye) = 0
429 print
'(/,a,/)',
'Bound state information'
430 print
'(4x,a,e25.15)',
'First R-matrix pole = ', moldat % eig(1, irr)
431 print
'(4x,a,e25.15)',
'Calculated initial energy = ', ei
436 allocate (wbnd(nchan, nbnd), fc(nchan), gc(nchan), fcp(nchan), gcp(nchan), ap(nchan))
441 ek = ei - moldat % etarg(moldat % ichl(: , irr))
449 states % ap(:, 1, mye) = real(ap)
450 states % ap(:, 2, mye) = aimag(ap)
453 print
'(4x,a,e25.15)',
'Total inner norm = ', norm2(bnd(:, 1))
454 print
'(/,a,/)',
'Bound state outer region channel coefficients and amplitudes'
455 print
'(4x,a,4x,a,23x,a,20x,a,20x,a)',
'chan',
'Ek',
'Re ap',
'Im ap',
'f_p'
457 print
'(i6,a,4e25.15)', ichan,
': ', ek(ichan), ap(ichan), wbnd(ichan, 1)
462 states % ap(:, :, :) = 0
467 call test_outer_expansion(
'initial-state.txt', moldat, irr, states % ck(:, :, 1), states % ap(:, :, 1), ei)
500 km, state, verbose, calc_Ei, first_IP, r0, erange)
509 type(
kmatrix),
intent(in) :: km(:)
514 integer,
intent(in) :: order, icomp, s, mgvnn, mgvn1, mgvn2, erange(2)
515 logical,
intent(in) :: verbose
516 real(wp),
intent(in) :: Ephoton(:), calc_Ei, first_IP, r0
518 integer :: nstatn, nstatf, nchann, nchanf, nopen, mgvnf, irrn, irrf, ikn, ikf, ipw, nesc, ie, mye, t, dt, i
519 real(wp) :: Ei, Etotf
520 character(len=1) :: transp
521 character(len=1024) :: filename
523 complex(wp),
allocatable :: beta(:), app(:), H(:, :), lambda(:), hc(:), hcp(:)
524 real(wp),
allocatable :: fc(:), fcp(:), gc(:), gcp(:)
526 integer,
allocatable :: lf(:)
527 real(wp),
allocatable :: Ef(:), P(:), rhs(:, :), omega(:), echl(:)
528 real(wp),
allocatable :: Pw(:, :), wPw(:, :), wPD(:, :), IwPD(:, :), wckp(:, :), Dpsi(:, :, :), corr(:, :), ckp(:, :)
530 if (mgvnn == mgvn1)
then
538 irrn = findloc(moldat % mgvns, mgvnn, 1)
539 irrf = findloc(moldat % mgvns, mgvnf, 1)
541 ikn = findloc(km(:) % mgvn, mgvnn, 1)
542 ikf = findloc(km(:) % mgvn, mgvnf, 1)
544 nstatn = moldat % mnp1(irrn)
545 nstatf = moldat % mnp1(irrf)
547 nchann = moldat % nchan(irrn)
548 nchanf = moldat % nchan(irrf)
550 nesc = erange(2) - erange(1) + 1
554 allocate (pw(nstatf, nchanf), wpd(nchanf, 2), iwpd(nchanf, 2), wpw(nchanf, nchanf), wckp(nchanf, 2), omega(order), &
555 dpsi(nstatf, 2, (nesc +
nprocs - 1) /
nprocs), fc(nchanf), gc(nchanf), fcp(nchanf), gcp(nchanf), &
556 hc(nchanf), hcp(nchanf), corr(nchanf, 2), echl(nchanf), &
557 ef(nchanf), lf(nchanf), ckp(nstatf, 2), h(nchanf, nchanf), lambda(nchanf), beta(nchanf), &
560 echl(1:nchanf) = moldat % etarg(moldat % ichl(1:nchanf, irrf)) - moldat % etarg(1)
564 do while (
associated(last % next))
567 allocate (last % next)
568 last % next % prev => last
570 last % order = state % order + 1
573 last % parent => state
574 allocate (last % ck(nstatf, 2, (nesc +
nprocs - 1) /
nprocs))
575 allocate (last % ap(nchanf, 2, (nesc +
nprocs - 1) /
nprocs))
583 print
'(4x,A,I0,A)',
'inner dipoles applied in ', dt,
' s'
595 etotf = ei + sum(omega(1 : last % order))
596 ef = km(ikf) % escat(ie) - echl - sum(omega(last % order + 1 :))
597 lf = moldat % l2p(1:nchanf, irrf)
600 print
'(4x,A,*(I0,A))',
'energy ', ie,
' of ', km(ikf) % nescat, &
601 ' (', count(ef > 0),
' open / ', nopen,
' open + weakly closed channels of ', nchanf,
')'
604 fc = 0; fcp = 0; gc = 0; gcp = 0; hc = 0; hcp = 0; lambda = 0
607 hc(ipw) = gc(ipw) + imu*fc(ipw)
608 hcp(ipw) = gcp(ipw) + imu*fcp(ipw)
609 lambda(ipw) = hcp(ipw) / hc(ipw)
613 rhs = dpsi(:, :, mye)
616 call multiint(moldat, r0, ei, km(ikf) % escat(ie) - sum(omega(last % order + 1 :)), omega, mye, last, +1, beta)
617 beta = -2 * beta / sqrt(2*abs(ef))
618 where (ef < 0) beta = beta / imu
619 corr(:, 1) = real(beta * (fcp - lambda * fc), wp)
620 corr(:, 2) = aimag(beta * (fcp - lambda * fc))
622 rhs = rhs - 0.5 * dpsi(:, :, mye)
625 p = 1 / (etotf - moldat % eig(1:nstatf, irrf))
626 ckp(:, 1) = p * rhs(:, 1)
627 ckp(:, 2) = p * rhs(:, 2)
635 h(1:nopen, 1:nopen) = wpw(1:nopen, 1:nopen)
637 h(i, i) = h(i, i) + 2/lambda(i)
639 do i = nopen + 1, nchanf
650 ckp(:, 1) = p * (rhs(:, 1) - ckp(:, 1))
651 ckp(:, 2) = p * (rhs(:, 2) - ckp(:, 2))
657 app = cmplx(wckp(:, 1), wckp(:, 2), wp)
659 app = (app - beta*fc) / hc
666 wckp(:, 1) = real(app)
667 wckp(:, 2) = aimag(app)
668 write (filename,
'(a,i0,a,i0,a)')
'intermediate-state-', irrf,
'-', ie,
'.txt'
669 call test_outer_expansion(trim(filename), moldat, irrf, ckp, wckp, etotf)
672 if (verbose) print
'(4x,A,*(E25.15))',
' - beta: ', beta(1:nopen)
673 if (verbose) print
'(4x,A,*(E25.15))',
' - ap: ', app(1:nopen)
675 last % ck(:, 1, mye) = ckp(:, 1)
676 last % ck(:, 2, mye) = ckp(:, 2)
678 last % ap(:, 1, mye) = real(app, wp)
679 last % ap(:, 2, mye) = aimag(app)
684 print
'(4x,A,I0,A)',
'intermediate states solved in ', dt,
' s'
714 km, ak, state, verbose, calc_Ei, first_IP, r0, erange)
724 type(
kmatrix),
intent(in) :: km(:)
729 integer,
intent(in) :: order, icomp, s, mgvnn, mgvn1, mgvn2, erange(2)
730 logical,
intent(in) :: verbose
731 real(wp),
intent(in) :: Ephoton(:), calc_Ei, first_IP, r0
733 character(len=1) :: transp
734 character(len=1024) :: filename
736 complex(wp),
allocatable :: Af(:, :), dm(:), dp(:), Sm(:, :), tmat(:, :)
737 real(wp),
allocatable :: Dpsi(:, :, :), Ef(:), echlf(:), d_inner(:, :), d_outer(:, :), Re_Af(:, :), Im_Af(:, :)
738 real(wp),
allocatable :: omega(:), d_total(:, :), kmat(:, :), Sf(:), Cf(:), Sfp(:), Cfp(:)
739 integer,
allocatable :: lf(:)
741 real(wp) :: Etotf, Ei, Ek
742 integer :: mgvnf, irrn, irrf, ikn, ikf, nstatn, nstatf, nchann, nchanf, nesc, ie, nopen, nochf, mye, nene, maxchan, i
745 integer(blasint) :: m, n, lds, inc = 1
747 if (mgvnn == mgvn1)
then
755 irrn = findloc(moldat % mgvns, mgvnn, 1)
756 irrf = findloc(moldat % mgvns, mgvnf, 1)
758 ikn = findloc(km(:) % mgvn, mgvnn, 1)
759 ikf = findloc(km(:) % mgvn, mgvnf, 1)
761 nstatn = moldat % mnp1(irrn)
762 nstatf = moldat % mnp1(irrf)
764 nchann = km(ikn) % nchan
765 nchanf = km(ikf) % nchan
767 nesc = erange(2) - erange(1) + 1
774 maxchan = count(moldat % ichl(1:nchanf, irrf) <=
maxtarg)
777 allocate (dpsi(nstatf, 2, nene), omega(order), ef(nchanf), lf(nchanf), echlf(nchanf), &
778 re_af(nstatf, maxchan), im_af(nstatf, maxchan), af(nstatf, maxchan), sm(nchanf, nchanf), &
779 d_inner(maxchan, 2), d_outer(maxchan, 2), d_total(maxchan, 2), dm(maxchan), dp(nchanf), &
780 sf(nchanf), cf(nchanf), sfp(nchanf), cfp(nchanf), kmat(nchanf, nchanf), tmat(nchanf, nchanf))
782 echlf(1:nchanf) = moldat % etarg(moldat % ichl(1:nchanf, irrf)) - moldat % etarg(1)
786 do while (
associated(last % next))
789 allocate (last % next)
790 last % next % prev => last
795 last % parent => state
796 allocate (last % dip(maxchan, 2, nene))
804 print
'(4x,A,I0,A)',
'inner dipoles applied in ', dt,
' s'
807 call km(ikf) % reset_kmatrix_position(skip =
myproc - 1)
808 if (
allocated(ak))
call ak(ikf) % reset_wfncoeffs_position(skip =
myproc - 1)
814 call km(ikf) % get_kmatrix(kmat, skip =
nprocs - 1)
815 if (
allocated(ak))
call ak(ikf) % get_wfncoeffs(ek, re_af, im_af, skip =
nprocs - 1)
816 if (ie < erange(1)) cycle
819 last % dip(:, :, mye) = 0
826 etotf = ei + sum(omega)
827 ef = km(ikf) % escat(ie) - echlf
828 lf = moldat % l2p(1:nchanf, irrf)
829 nopen = count(ef > 0)
830 nochf = min(nopen, maxchan)
832 print
'(4x,A,*(I0,A))',
'energy ', ie,
' of ', km(ikf) % nescat,
' (', nopen,
' open channels of ', nchanf,
')'
844 if (.not.
allocated(ak))
then
846 sfp, cfp, kmat, tmat, .true.)
854 call multiint(moldat, r0, ei, km(ikf) % escat(ie), omega, mye, last, -1, dm(1:nochf))
855 call multiint(moldat, r0, ei, km(ikf) % escat(ie), omega, mye, last, +1, dp(1:nopen))
856 dm(1:nochf) = dm(1:nochf) * imu / sqrt(2*pi*sqrt(2*ef(1:nochf)))
857 dp(1:nopen) = dp(1:nopen) * imu / sqrt(2*pi*sqrt(2*ef(1:nopen)))
858 if (verbose) print
'(5x,A,1x,*(1x,E25.15))',
'dm = ', dm(1:nochf)
859 if (verbose) print
'(5x,A,1x,*(1x,E25.15))',
'dp = ', dp(1:nopen)
861 m = int(nopen, blasint)
862 n = int(nochf, blasint)
863 lds = int(nchanf, blasint)
865 call blas_zgemv(
'T', m, n, -
cone, sm, lds, dp, inc,
cone, dm, inc)
867 d_outer(:, 1) = real(dm)
868 d_outer(:, 2) = aimag(dm)
872 write (filename,
'(a,i0,a,i0,a)')
'final-state-', irrf,
'-', ie,
'.txt'
877 d_total = d_inner + d_outer
878 last % dip(:, :, mye) = d_total
880 if (verbose) print
'(5x,A,1x,*(1x,E25.15))',
'd_inner = ', (d_inner(i, 1), d_inner(i, 2), i = 1, nochf)
881 if (verbose) print
'(5x,A,1x,*(1x,E25.15))',
'd_outer = ', (d_outer(i, 1), d_outer(i, 2), i = 1, nochf)
882 if (verbose) print
'(5x,A,1x,*(1x,E25.15))',
'd_total = ', (d_total(i, 1), d_total(i, 2), i = 1, nochf)
887 print
'(4x,A,I0,A)',
'matrix elements calculated in ', dt,
' s'
908 integer,
allocatable :: irreds(:), compts(:)
911 order = state % order
913 allocate (irreds(order + 1), compts(order))
916 irreds(order + 1) = ptr % mgvn
917 do while (
associated(ptr % parent))
918 compts(order) = ptr % dcomp
920 irreds(order) = ptr % mgvn
924 write (*,
'(2x,a)', advance =
'no')
'Transition'
925 do i = 1, state % order
926 write (*,
'(1x,i0,1x,3a)', advance =
'no') irreds(i),
'-[',
compt(compts(i)),
']->'
928 write (*,
'(1x,i0)') irreds(state % order + 1)
949 real(wp),
intent(in) :: psi(:, :), ReAk(:, :), ImAk(:, :)
950 real(wp),
intent(inout) :: Apsi(:, :)
952 integer(blasint) :: m, n, inc = 1
954 m = int(
size(reak, 1), blasint)
955 n = int(
size(reak, 2), blasint)
957 call blas_dgemv(
'T', m, n,
rone, reak, m, psi(:, 1), inc,
rzero, apsi(:, 1), inc)
958 call blas_dgemv(
'T', m, n, +
rone, imak, m, psi(:, 2), inc, +
rone, apsi(:, 1), inc)
959 call blas_dgemv(
'T', m, n,
rone, reak, m, psi(:, 2), inc,
rzero, apsi(:, 2), inc)
960 call blas_dgemv(
'T', m, n, -
rone, imak, m, psi(:, 1), inc, +
rone, apsi(:, 2), inc)
1003 subroutine apply_ak_coefficients_multidip (psi, Apsi, moldat, nopen, irr, Etot, Sp, Cp, kmat, tmat, conj)
1009 real(wp),
intent(in) :: psi(:, :), Etot
1010 real(wp),
intent(inout) :: Apsi(:, :)
1011 integer,
intent(in) :: nopen, irr
1012 real(wp),
intent(in) :: Sp(:), Cp(:), kmat(:, :)
1013 complex(wp),
intent(in) :: tmat(:, :)
1014 logical,
intent(in) :: conj
1016 real(wp),
allocatable :: tmps(:, :), tmpc(:, :)
1017 complex(wp),
allocatable :: tmpo(:)
1019 integer(blasint) :: n, ldk, one = 1
1021 integer :: nchan, nstat, i, j
1025 nstat = moldat % mnp1(irr)
1026 nchan = moldat % nchan(irr)
1030 allocate (tmps(nstat, 2), tmpc(nchan, 2), tmpo(nopen))
1033 tmps(:, 1) = psi(:, 1) / (moldat % eig(1:nstat, irr) - etot)
1034 tmps(:, 2) = psi(:, 2) / (moldat % eig(1:nstat, irr) - etot)
1043 fij = (merge(sp(i),
rzero, i == j) + cp(i)*kmat(i, j)) / sqrt(2*pi)
1044 tmpo(j) = tmpo(j) + cmplx(tmpc(i, 1), tmpc(i, 2), wp)*fij
1049 do j = 1, min(nopen,
size(apsi, 1))
1053 t = merge(1, 0, i == j) + conjg(tmat(i, j))/2
1054 if (conj) t = conjg(t)
1056 apsi(j, 1) = apsi(j, 1) + real(z)
1057 apsi(j, 2) = apsi(j, 2) + aimag(z)
1062 do j = nopen + 1, min(nchan,
size(apsi, 1))
1083 character(len=*),
intent(in) :: filename
1085 integer,
intent(in) :: irr, nopen
1086 real(wp),
intent(in) :: Etot, Ek(:), Sp(:), Cp(:), kmat(:, :)
1087 complex(wp),
intent(in) :: tmat(:, :)
1089 real(wp),
allocatable :: psi(:, :), Apsi(:, :), S(:), C(:), dSdr(:), dCdr(:)
1090 complex(wp),
allocatable :: Fqp(:, :), Hp(:), Hm(:)
1093 integer :: i, nfdm, u, nchan, p, q, nstat
1095 nfdm =
size(moldat % r_points) - 1
1096 nchan = moldat % nchan(irr)
1097 nstat = moldat % mnp1(irr)
1100 allocate (fqp(nchan, nopen), psi(nstat, 2), apsi(nchan, 2), s(nchan), c(nchan), hp(nchan), hm(nchan), dsdr(nchan), &
1103 open (newunit = u, file = filename, action =
'write', form =
'formatted')
1107 write (u,
'(e25.15)', advance =
'no') moldat % r_points(i)
1109 if (.not.
associated(moldat % wmat2(i, irr) % mat))
then
1110 print
'(a)',
'Error: wmat2 has not been read from molecular_data'
1112 else if (moldat % wmat2(i, irr) % distributed)
then
1113 print
'(a)',
'Error: test_outer_expansion not implemented in MPI-IO mode'
1117 psi(:, 1) = moldat % wmat2(i, irr) % mat(q, :)
1120 call apply_ak_coefficients_multidip(psi, apsi, moldat, nopen, irr, etot, sp, cp, kmat, tmat, .false.)
1122 fqp(q, 1:nopen) = cmplx(apsi(1:nopen, 1), apsi(1:nopen, 2), wp)
1124 write (u,
'(*(e25.15))') fqp(1:nchan, 1:nopen)
1128 do i = 0, nint(moldat % rmatr/dr)
1129 r = moldat % rmatr + i*dr
1130 write (u,
'(e25.15)', advance =
'no') r
1132 hp = (c + imu*s) * (-imu) / sqrt(2*pi)
1133 hm = (c - imu*s) * (-imu) / sqrt(2*pi)
1136 if (q == p) fqp(q, p) = hp(q)
1137 if (q /= p) fqp(q, p) = 0
1138 fqp(q, p) = fqp(q, p) - hm(q) * conjg(1 + tmat(q, p))
1139 write (u,
'(*(e25.15))', advance =
'no') fqp(q, p)
1162 use mpi_gbl,
only: mpi_mod_barrier
1164 integer,
intent(inout) :: t
1165 integer,
intent(out) :: dt
1166 integer :: clk_now, clk_rate, clk_max, ierr
1168 call mpi_mod_barrier(ierr)
1170 call system_clock(clk_now, clk_rate, clk_max)
1172 if (t < clk_now)
then
1173 dt = (clk_now - t) / clk_rate
1177 dt = ((clk_max - t) + clk_now) / clk_rate
1204 real(wp),
intent(in) :: first_IP, escat, etarg, Ephoton(:)
1205 real(wp),
intent(inout) :: Ei
1206 real(wp),
allocatable,
intent(inout) :: omega(:)
1216 if (first_ip > 0)
then
1217 ip = first_ip + escat
1222 where (ephoton /= 0)
1225 omega = (ip - sum(ephoton)) / (
size(omega) - count(ephoton /= 0))
1250 subroutine multiint (moldat, r0, Ei, esc, omega, ie, state, sb, dip)
1252 use mpi_gbl,
only: mpi_xermsg
1260 complex(wp),
intent(inout) :: dip(:)
1261 real(wp),
allocatable,
intent(inout) :: omega(:)
1262 real(wp),
intent(in) :: Ei, esc, r0
1263 integer,
intent(in) :: ie, sb
1265 complex(wp),
allocatable :: k(:)
1266 integer,
allocatable :: l(:), m(:)
1268 real(wp) :: c, a, Ekf, ebase, echl, etarg
1269 integer :: nphot, mgvn, ichan, irr, ichl
1275 if (.not.
associated(state % parent))
then
1276 call mpi_xermsg(
'multidip_routines',
'multiint',
'Runtime error: unexpected parent state', 1, 1)
1281 nphot = state % order
1283 irr = findloc(moldat % mgvns, mgvn, 1)
1284 ebase = moldat % etarg(1)
1290 allocate (k(nphot + 1), l(nphot + 1), m(nphot))
1294 do ichan = 1,
size(dip)
1297 ichl = moldat % ichl(ichan, irr)
1298 etarg = moldat % etarg(ichl)
1299 echl = etarg - ebase
1303 k(1) = sqrt(2*abs(ekf));
if (ekf < 0) k(1) = k(1) * imu
1304 l(1) = moldat % l2p(ichan, irr)
1307 dip(ichan) =
multiint_chain(moldat, r0, ei, esc - omega(nphot), omega, ie, c, 1, state, ichan, sb, k, l, m)
1345 recursive complex(wp) function multiint_chain (moldat, r0, Ei, esc, omega, ie, c, N, state, ichanf, sb, k, l, m)
result (integ)
1355 complex(wp),
allocatable,
intent(inout) :: k(:)
1356 real(wp),
allocatable,
intent(inout) :: omega(:)
1357 integer,
allocatable,
intent(inout) :: l(:), m(:)
1358 real(wp),
intent(in) :: r0, ei, esc
1359 integer,
intent(in) :: ie, sb, n, ichanf
1361 complex(wp) :: ap, kr(n + 1)
1362 real(wp) :: z, c, a, ek, qion, qpws, ebase, etarg, echl
1363 integer :: mgvni, mgvnf, nchani, irri, irrf, ichani, ichl, nphot, dcomp, lr(n + 1), mr(n)
1368 if (.not.
associated(state % parent))
return
1370 parent => state % parent
1371 nphot = parent % order
1372 ebase = moldat % etarg(1)
1374 z = moldat % nz - moldat % nelc
1375 dcomp = state % dcomp
1376 mgvnf = state % mgvn
1377 mgvni = parent % mgvn
1378 irrf = findloc(moldat % mgvns, mgvnf, 1)
1379 irri = findloc(moldat % mgvns, mgvni, 1)
1380 nchani = moldat % nchan(irri)
1383 do ichani = 1, nchani
1386 ichl = moldat % ichl(ichani, irri)
1387 etarg = moldat % etarg(ichl)
1388 echl = etarg - ebase
1392 k(n + 1) = sqrt(2*abs(ek));
if (ek < 0) k(n + 1) = k(n + 1) * imu
1393 l(n + 1) = moldat % l2p(ichani, irri)
1394 kr(1 : n + 1) = k(n + 1 : 1 : -1)
1395 lr(1 : n + 1) = l(n + 1 : 1 : -1)
1402 ap = cmplx(parent % ap(ichani, 1, ie), parent % ap(ichani, 2, ie), wp)
1408 if (ap /= 0) integ = integ + qion * ap *
nested_cgreen_integ(z, a, r0, c, n, +1, sb, mr, lr, kr)
1409 if (nphot > 0) integ = integ + qion *
multiint_chain(moldat, r0, ei, esc - omega(nphot), &
1410 omega, ie, c, n + 1, parent, ichani, sb, k, l, m)
1417 if (ap /= 0) integ = integ + qpws * ap *
nested_cgreen_integ(z, a, r0, c, n, +1, sb, mr, lr, kr)
1418 if (nphot > 0) integ = integ + qpws *
multiint_chain(moldat, r0, ei, esc - omega(nphot), &
1419 omega, ie, c, n + 1, parent, ichani, sb, k, l, m)
1448 integer,
intent(in) :: dcomp, irrf, irri, ichanf, ichani
1450 integer :: itargi, itargf, li, lf, mi, mf
1452 lf = moldat % l2p(ichanf, irrf); mf = moldat % m2p(ichanf, irrf); itargf = moldat % ichl(ichanf, irrf)
1453 li = moldat % l2p(ichani, irri); mi = moldat % m2p(ichani, irri); itargi = moldat % ichl(ichani, irri)
1455 if (lf /= li .or. mf /= mi)
then
1458 qion = moldat % crlv(itargf, itargi,
carti(dcomp))
1484 integer,
intent(in) :: dcomp, irrf, irri, ichanf, ichani
1486 integer :: itargi, itargf, li, lf, mi, mf, ipwi, ipwf
1488 itargf = moldat % ichl(ichanf, irrf)
1489 itargi = moldat % ichl(ichani, irri)
1491 if (itargf /= itargi)
then
1494 lf = moldat % l2p(ichanf, irrf); mf = moldat % m2p(ichanf, irrf); ipwf = lf*(lf + 1) + mf + 1
1495 li = moldat % l2p(ichani, irri); mi = moldat % m2p(ichani, irri); ipwi = li*(li + 1) + mi + 1
1496 qpws = sqrt(4*pi/3) * moldat % gaunt(ipwf, ipwi,
cartm(dcomp))
1542 integer,
intent(in) :: order, erange(2)
1543 real(wp),
intent(in) :: escat(:), calc_Ei, first_IP, Ephoton(:)
1544 complex(wp),
intent(in) :: polar(:, :)
1545 integer :: nesc, ntarg, nchan, mxchan, lf, ichan, itarg, ie, irr, mgvn, mye, nirr, nene
1546 real(wp) :: Z, Ef, Ei, kf, sigma, Q
1547 complex(wp) :: d, ej
1548 complex(wp),
allocatable :: M(:, :, :)
1549 real(wp),
allocatable :: cs(:, :), omega(:)
1551 z = moldat % nz - moldat % nelc
1552 nirr =
size(moldat % mgvns)
1554 mxchan = maxval(moldat % nchan)
1555 ntarg =
size(moldat % etarg)
1562 nchan = moldat % nchan(irr)
1563 mxchan = max(mxchan, count(moldat % ichl(1:nchan, irr) <=
maxtarg))
1569 allocate (omega(order), m(mxchan, nene, 0:7), cs(2 + ntarg, nene))
1578 do while (
associated(ptr))
1579 if (ptr % order == order)
then
1582 ej = polar(ptr % dcomp, ptr % order)
1583 parent => ptr % parent
1584 do while (
associated(parent % parent))
1585 ej = ej * polar(parent % dcomp, parent % order)
1586 parent => parent % parent
1593 do ichan = 1,
size(ptr % dip, 1)
1594 d = ej * cmplx(ptr % dip(ichan, 1, mye), ptr % dip(ichan, 2, mye), wp)
1595 m(ichan, mye, ptr % mgvn) = m(ichan, mye, ptr % mgvn) + q * d
1616 mgvn = moldat % mgvns(irr)
1617 nchan = min(int(moldat % nchan(irr)), mxchan)
1619 lf = moldat % l2p(ichan, irr)
1620 ef = escat(ie) - moldat % etarg(moldat % ichl(ichan, irr)) + moldat % etarg(1)
1623 sigma =
cphase(z, lf, kf)
1624 m(ichan, mye, mgvn) = m(ichan, mye, mgvn) * imu**(-lf) * (cos(sigma) + imu*sin(sigma))
1630 cs(1, mye) = omega(1) * to_ev
1632 cs(2 + itarg, mye) = 0
1634 mgvn = moldat % mgvns(irr)
1635 nchan = min(int(moldat % nchan(irr)), mxchan)
1637 if (itarg == moldat % ichl(ichan, irr))
then
1638 d = m(ichan, mye, mgvn)
1639 cs(2 + itarg, mye) = cs(2 + itarg, mye) + real(d * conjg(d))
1644 cs(2, mye) = sum(cs(3:, mye))
1645 cs(2:, mye) = cs(2:, mye) * 2*pi * (2*pi*
alpha)**order * product(omega)
1685 character(len=*),
intent(in) :: raw
1690 integer,
intent(in) :: order, erange(2)
1691 real(wp),
intent(in) :: escat(:), calc_Ei, first_IP, Ephoton(:)
1693 integer :: nesc, ii, li, mi, nchain, ichain
1694 integer :: ntarg, ichan, ie, mye, irr, L, nene, maxl, pw
1695 integer,
allocatable :: chains(:, :)
1696 real(wp),
allocatable :: omega(:), cs(:, :)
1697 complex(wp),
allocatable :: M_xyz(:, :, :, :), M_sph(:, :, :, :), beta(:, :)
1699 real(wp) :: Z, Ek, k, sigma, Ei, Q
1700 character(len=50) :: filename
1702 z = moldat % nz - moldat % nelc
1705 maxl = maxval(moldat % l2p)
1706 ntarg =
size(moldat % etarg)
1711 maxl = maxval(moldat % l2p, moldat % ichl <=
maxtarg)
1717 do while (
associated(ptr))
1718 if (ptr % order == order)
then
1724 allocate (omega(order), chains(order, nchain), cs(ntarg, nene), beta(2 + ntarg, nesc), &
1725 m_xyz(nene, (maxl + 1)**2, nchain, ntarg), &
1726 m_sph(nene, (maxl + 1)**2, nchain, ntarg))
1738 do while (
associated(ptr))
1739 if (ptr % order == order)
then
1742 irr = findloc(moldat % mgvns, ptr % mgvn, 1)
1747 do while (
associated(parent % parent))
1748 chains(parent % order, ichain) = mod(1 + parent % dcomp, 3) - 1
1749 parent => parent % parent
1753 do ichan = 1,
size(ptr % dip, 1)
1754 ii = moldat % ichl(ichan, irr)
1755 li = moldat % l2p(ichan, irr)
1756 mi = moldat % m2p(ichan, irr)
1757 pw = li*li + li + mi + 1
1761 ek = escat(ie) - moldat % etarg(ii) + moldat % etarg(1)
1765 d = cmplx(ptr % dip(ichan, 1, mye), ptr % dip(ichan, 2, mye), wp)
1766 if (.not. d == d) d = 0
1767 m_xyz(mye, pw, ichain, ii) = imu**(-li) * (cos(sigma) + imu*sin(sigma)) * q * d
1776 if (raw ==
'xyz' .or. raw ==
'both')
then
1783 if (raw ==
'sph' .or. raw ==
'both')
then
1790 print
'(/,A,I0)',
'Evaluating asymmetry parameter for L = ', l
1801 beta(1, mye) = omega(1) * to_ev
1802 beta(2:, mye) = beta(2:, mye) * 2*pi * (2*pi*
alpha)**order * product(abs(omega))
1804 cs(:, mye) = real(beta(3:, mye))
1805 beta(2, mye) = sum(cs(:, mye))
1807 where (cs(:, mye) > 0)
1808 beta(3:, mye) = beta(3:, mye) / cs(:, mye)
1815 write (filename,
'(A,I0,A,I0,A)')
'gen_', order,
'photo_beta_', l,
'.txt'
1832 use dipelm_special_functions,
only: sph_basis_transform_elm
1834 complex(wp),
allocatable,
intent(in) :: M_xyz(:, :, :, :)
1835 complex(wp),
allocatable,
intent(inout) :: M_sph(:, :, :, :)
1836 integer,
intent(in) :: maxl, chains(:, :)
1838 integer :: order, ntarg, nchain, i, ii, l, mi, mj, pwi, pwj, ichain, jchain
1841 order =
size(chains, 1)
1842 nchain =
size(chains, 2)
1843 ntarg =
size(m_xyz, 4)
1848 do ichain = 1, nchain
1849 do jchain = 1, nchain
1853 cpl = conjg(sph_basis_transform_elm(l, mj, mi,
'Slm'))
1855 cpl = cpl * sph_basis_transform_elm(1, chains(i, jchain), chains(i, ichain),
'Slm')
1857 pwi = l*l + l + mi + 1
1858 pwj = l*l + l + mj + 1
1859 m_sph(:, pwj, jchain, ii) = m_sph(:, pwj, jchain, ii) + cpl * m_xyz(:, pwi, ichain, ii)
1880 use mpi_gbl,
only: mpi_reduceall_inplace_sum_wp
1884 complex(wp),
allocatable,
intent(inout) :: beta(:, :)
1885 complex(wp),
allocatable,
intent(in) :: M1(:, :, :, :), M2(:, :, :, :)
1886 integer,
intent(in) :: L, maxl, chains1(:, :), chains2(:, :), ntarg, nesc
1889 real(wp),
allocatable :: T(:, :, :, :), buffer(:)
1890 integer :: ie, mye, itarg, idx, li, mi, lj, mj, pwi, pwj, ichain, jchain, nchain1, nchain2, order1, order2
1891 integer :: qi(size(chains1, 1)), qj(size(chains2, 1)), p(size(chains1, 1))
1895 order1 =
size(chains1, 1); nchain1 =
size(chains1, 2)
1896 order2 =
size(chains2, 1); nchain2 =
size(chains2, 2)
1898 if (order1 /= order2)
then
1899 print
'(A)',
'WARNING: calculate_quadratic_dipole_sph is implemented only equal absorption orders'
1903 allocate (t((maxl + 1)**2, (maxl + 1)**2, nchain1, nchain2))
1907 do jchain = 1, nchain2
1908 do ichain = 1, nchain1
1909 do pwj = 1, (maxl + 1)**2
1910 do pwi = 1, (maxl + 1)**2
1911 t(pwi, pwj, ichain, jchain) = 0
1920 do idx =
myproc, (maxl + 1)**4 * nchain1 * nchain2,
nprocs
1923 pwi = 1 + (idx - 1) / (nchain2 * nchain1 * (maxl + 1)**2)
1924 pwj = 1 + mod((idx - 1) / (nchain2 * nchain1), (maxl + 1)**2)
1925 ichain = 1 + mod((idx - 1) / nchain2, nchain1)
1926 jchain = 1 + mod( idx - 1, nchain2)
1929 li = floor(sqrt(pwi - 1._wp))
1930 mi = pwi - li*li - li - 1
1931 qi = chains1(:, ichain)
1934 lj = floor(sqrt(pwj - 1._wp))
1935 mj = pwj - lj*lj - lj - 1
1936 qj = chains2(:, jchain)
1938 t(pwi, pwj, ichain, jchain) =
beta_contraction_tensor(l, order1, p, li, mi, qi, lj, mj, qj)
1943 buffer = reshape(t, [
size(t)])
1944 call mpi_reduceall_inplace_sum_wp(buffer,
size(buffer))
1945 t = reshape(buffer, shape(t))
1950 do idx = 1, ntarg * (maxl + 1)**4 * nchain1 * nchain2
1953 itarg = 1 + (idx - 1) / (nchain2 * nchain1 * (maxl + 1)**4)
1954 pwi = 1 + mod((idx - 1) / (nchain2 * nchain1 * (maxl + 1)**2), (maxl + 1)**2)
1955 pwj = 1 + mod((idx - 1) / (nchain2 * nchain1), (maxl + 1)**2)
1956 ichain = 1 + mod((idx - 1) / nchain2, nchain1)
1957 jchain = 1 + mod( idx - 1, nchain2)
1960 li = floor(sqrt(pwi - 1._wp))
1961 mi = pwi - li*li - li - 1
1964 lj = floor(sqrt(pwj - 1._wp))
1965 mj = pwj - lj*lj - lj - 1
1970 mm = conjg(m1(mye, pwi, ichain, itarg)) * m2(mye, pwj, jchain, itarg)
1971 beta(2 + itarg, mye) = beta(2 + itarg, mye) + t(pwi, pwj, ichain, jchain) * mm
1994 complex(wp),
allocatable,
intent(inout) :: beta(:, :)
1995 complex(wp),
allocatable,
intent(in) :: M1(:, :, :, :), M2(:, :, :, :)
1996 integer,
intent(in) :: L, maxl, chains1(:, :), chains2(:, :), ntarg, nesc
2000 integer :: ie, mye, itarg, li, mi, lj, mj, pwi, pwj, qi(size(chains1, 1)), qj(size(chains2, 1)), ichain, jchain
2005 print
'(A)',
'WARNING: calculate_quadratic_dipole_xyz is implemented only for L = 0'
2012 do ichain = 1,
size(chains1, 2)
2013 do jchain = 1,
size(chains2, 2)
2014 qi = chains1(:, ichain)
2015 qj = chains2(:, jchain)
2017 do pwi = 1, (maxl + 1)**2
2022 mm = conjg(m1(mye, pwi, ichain, itarg)) * m2(mye, pwi, jchain, itarg)
2023 beta(2 + itarg, mye) = beta(2 + itarg, mye) + t * mm
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.
type(nested_cgreen_integ_cache_t) nested_cgreen_integ_cache
I/O routines used by MULTIDIP.
subroutine read_bndcoeffs(bnd, Ei, lubnd, mgvn0, stot0)
Read inner bound wave function coefficients.
subroutine write_raw_dipoles(M, chains, nesc, stem)
Write raw transition dipole moments.
subroutine read_wfncoeffs(ak, lusct)
Read wave function coefficients from files.
subroutine write_partial_wave_moments(moldat, M, nesc, suffix)
Write partial wave moments.
subroutine scale_boundary_amplitudes(moldat, irr, v, vw)
Scale boundary amplitudes matrix by a diagonal matrix.
subroutine get_diptrans(moldat, I, iidip, ifdip)
Return dipole transition descriptors.
subroutine write_cross_section(cs, nesc, erange, filename)
Write cross sections to a file.
subroutine apply_dipole_matrix(moldat, component, irrpair, transp, nf, nn, X, Y)
Multiply by dipole matrix.
subroutine apply_boundary_amplitudes(moldat, irr, transp, X, Y)
Multiply by boundary amplitudes.
subroutine read_molecular_data(moldat, filename, mpiio, read_wmat2)
Read RMT molecular_data file.
subroutine read_kmatrices(km, lukmt, nkset)
Read K-matrix files.
subroutine write_energy_grid(escat)
Write photoelectron energies to file.
Routines related to outer region asymptotic channels.
subroutine test_outer_expansion(filename, moldat, irr, ck, ap, Etot)
Evaluate wfn in channels for inside and outside of the R-matrix sphere.
subroutine evaluate_fundamental_solutions(moldat, r, irr, nopen, Ek, S, C, Sp, Cp, sqrtknorm)
Evaluate asymptotic solutions at boundary.
subroutine calculate_k_matrix(moldat, nopen, irr, Etot, S, C, Sp, Cp, Kmat)
Calculate (generalized) K-matrix.
Hard-coded parameters of MULTIDIP.
subroutine read_input_namelist(input, order, lusct, lukmt, lubnd, nkset, polar, omega, verbose, rmt_data, first_IP, rasym, raw, erange, mpiio)
logical extend_istate
Continue initial state from the known inner region expansion outwards.
logical closed_interm
Consider weakly closed channel in intermediate states (unfinished!)
logical custom_kmatrices
Ignore RSOLVE K-matrices and calculate them from scratch.
integer num_integ_algo
Numerical integration mode (1 = Romberg, 2 = Levin)
integer, dimension(3), parameter carti
Position of a Cartesian coordinate in the real spherical basis (y, z, x).
character(len=1), dimension(3), parameter compt
logical cache_integrals
Cache Coulomb-Green integrals in memory (but disables some threading)
complex(wp), parameter cone
real(wp) closed_range
Energy interval (a.u.) before threshold for inclusion of closed channels.
real(wp), parameter rzero
integer maxtarg
Maximal number of target states to calculate dipoles for (0 = all)
real(wp), parameter alpha
Fine structure constant.
integer, dimension(3), parameter cartm
Real spherical harmonic m-value corresponding to given a Cartesian coord.
complex(wp), parameter czero
integer, parameter nmaxphotons
The limit on number of photons is nested_cgreen_integ
real(wp) function channel_coupling_ion(moldat, dcomp, irrf, irri, ichanf, ichani)
Ion channel dipole coupling.
subroutine convert_xyz_to_sph(M_xyz, M_sph, maxl, chains)
Change coordiantes.
subroutine setup_initial_state(states, moldat, irr, lubnd, Ei)
Construct initial state.
subroutine solve_intermediate_state(moldat, order, Ephoton, icomp, s, mgvnn, mgvn1, mgvn2, km, state, verbose, calc_Ei, first_IP, r0, erange)
Calculate intermediate photoionisation state.
recursive complex(wp) function multiint_chain(moldat, r0, Ei, esc, omega, ie, c, N, state, ichanf, sb, k, l, m)
Calculate dipole correction integrals at given absorption depth.
subroutine reset_timer(t, dt)
Get current time stamp.
subroutine calculate_quadratic_dipole_sph(beta, L, maxl, chains1, chains2, ntarg, nesc, M1, M2)
Evaluate asymmetry parameter for given total L in the spherical basis.
subroutine calculate_pw_transition_elements(moldat, order, state, escat, calc_Ei, first_IP, Ephoton, polar, erange)
Calculate partial wave dipoles, oriented dipoles and cross sections.
logical, parameter test_expansion
subroutine calculate_photon_energies(first_IP, escat, etarg, Ei, Ephoton, omega)
Adjust ionization potential and calculate energy of each photon.
subroutine apply_ak_coefficients_multidip(psi, Apsi, moldat, nopen, irr, Etot, Sp, Cp, kmat, tmat, conj)
Multiply vector by the (complex-conjugated) wave function coefficients.
subroutine extract_dipole_elements(moldat, order, Ephoton, icomp, s, mgvnn, mgvn1, mgvn2, km, ak, state, verbose, calc_Ei, first_IP, r0, erange)
Calculate dipole elements from intermediate and final states.
real(wp) function channel_coupling_pws(moldat, dcomp, irrf, irri, ichanf, ichani)
Partial wave channel dipole coupling.
subroutine test_final_expansion(filename, moldat, irr, nopen, Etot, Ek, Sp, Cp, kmat, tmat)
Write radially sampled final wave-function to file.
subroutine print_transition_header(state)
Prints a one-line summary of the transition.
subroutine calculate_asymmetry_parameters(moldat, order, state, escat, calc_Ei, first_IP, Ephoton, raw, erange)
Calculate cross sections and asymmetry parameters.
subroutine calculate_quadratic_dipole_xyz(beta, L, maxl, chains1, chains2, ntarg, nesc, M1, M2)
Evaluate asymmetry parameter for given total L in the Cartesian basis.
subroutine apply_ak_coefficiens_compak(psi, Apsi, ReAk, ImAk)
Multiply vector by the (complex-conjugated) wave function coefficients.
subroutine multidip_driver(order, moldat, km, ak, lubnd, omega, polar, verbose, first_IP, r0, raw, erange)
Central computation routine.
subroutine multiint(moldat, r0, Ei, esc, omega, ie, state, sb, dip)
Evaluate the correction dipole integral for all orders.
subroutine multidip_main
MULTIDIP main subroutine.
Special functions and objects used by MULTIDIP.
subroutine solve_complex_system(n, A, X, Y)
Solve system of equations with complex matrix.
subroutine coul(Z, l, Ek, r, F, Fp, G, Gp)
Coulomb functions.
subroutine calculate_t_matrix(K, T, nopen)
Calculate T-matrix from K-matrix.
subroutine calculate_s_matrix(T, S, nopen)
Calculate S-matrix from T-matrix.
real(wp) recursive function cartesian_vector_component_product_average(q)
Return Cartesian invariant.
real(wp) function beta_contraction_tensor(J, n, p, li, mi, qi, lj, mj, qj)
Angular part of the beta parameters.
real(wp) function cphase(Z, l, k)
Coulomb phase.
subroutine run_tests
Numerical unit tests.
Photoionization wave function coefficients.