31 use,
intrinsic :: iso_c_binding, only: c_double, c_int, c_f_pointer
32 use,
intrinsic :: iso_fortran_env, only: input_unit, int32, int64, real64, output_unit
35 use blas_lapack_gbl,
only: blasint
37 use file_mapping_gbl,
only: file_mapping
39 use phys_const_gbl,
only: pi, imu, to_ev
40 use precisn_gbl,
only: wp, wp_bytes
47 real(wp),
parameter ::
alpha = 1/137.03599907_wp
49 character(len=1),
parameter ::
compt(3) = [
'x',
'y',
'z']
59 integer :: mgvn, stot, nescat, nchan, nopen, ndopen, nchsq
60 real(wp),
allocatable :: escat(:), kmat(:,:,:)
72 real(wp),
allocatable :: rea(:, :, :), ima(:, :, :), evchl(:), escat(:)
73 integer,
allocatable :: ichl(:), lvchl(:), mvchl(:)
74 integer :: mgvn, nesc, nchan, nstat
94 real(real64),
pointer :: dipx(:,:,:), dipy(:,:,:), dipz(:,:,:)
96 real(real64),
allocatable :: dipx(:,:,:), dipy(:,:,:), dipz(:,:,:)
98 integer(int32),
allocatable :: iidipx(:), iidipy(:), iidipz(:)
99 integer(int32),
allocatable :: ifdipx(:), ifdipy(:), ifdipz(:)
103 type(file_mapping) :: dipx_mmap, dipy_mmap, dipz_mmap
107 real(real64) :: rmatr
108 real(real64),
allocatable :: crlv(:,:,:), eig(:,:), wamp(:,:,:), rg(:), etarg(:), gaunt(:, :, :)
109 integer(int32),
allocatable :: mgvns(:), mnp1(:), nchan(:), l2p(:,:), m2p(:,:), ichl(:,:), lm_rg(:,:)
116 end type moleculardata
129 type(KMatrix),
allocatable,
intent(inout) :: km(:)
130 integer,
intent(in) :: lukmt(:), nkset(:)
132 integer :: i, k, n, ifail, u, key, nset, nrec, ninfo, ndata, ntarg, nvib, ndis, maxne, ie, gutot, ion
133 integer :: nopen, ndopen, nchsq, a, b, c, mye, nene
135 real(wp) :: dE1, dE2, r, rmass, en
136 real(wp),
allocatable :: kmat(:)
137 character(len=80) :: title
144 print
'(/,A,I0,A,I0,/)',
'Reading K-matrices from unit ', u,
', set ', nset
146 call getset(u, nset, 11,
'UNFORMATTED', ifail)
148 read (u) key, nset, nrec, ninfo, ndata
150 read (u) km(i) % mgvn, km(i) % stot, gutot, ion, r, rmass
151 read (u) ntarg, nvib, ndis, km(i) % nchan, maxne
153 print
'(2x,A,I0)',
'mgvn = ', km(i) % mgvn
154 print
'(2x,A,I0)',
'stot = ', km(i) % stot
155 print
'(2x,A,I0)',
'ntarg = ', ntarg
156 print
'(2x,A,I0)',
'nvib = ', nvib
157 print
'(2x,A,I0)',
'ndis = ', ndis
158 print
'(2x,A,I0)',
'nchan = ', km(i) % nchan
159 print
'(2x,A,I0)',
'maxne = ', maxne
161 print
'(/,2x,A,/)',
'Energy ranges:' 165 read (u) k, n, de1, de2
166 print
'(4x,I4,I8,F8.3,F8.3)', k, n, de1, de2
167 km(i) % nescat = km(i) % nescat + n
171 allocate (km(i) % kmat(km(i) % nchan, km(i) % nchan, nene), &
172 km(i) % escat(km(i) % nescat), &
173 kmat(km(i) % nchan * (km(i) % nchan + 1)))
178 do ie = 1, km(i) % nescat
179 read (u) nopen, ndopen, nchsq, en, kmat(1:nchsq)
180 km(i) % escat(ie) = en/2
187 km(i) % kmat(a, b, mye) = kmat(c)
188 km(i) % kmat(b, a, mye) = kmat(c)
191 if (iwarn .and. nopen < km(i) % nchan)
then 192 print
'(/,2x,A,I0,A)',
'WARNING: Unit ', u,
' contains only open-open subset of the full K-matrix.' 193 print
'(11x,A)',
'Use IKTYPE = 1 in RSOLVE to save full K-matrices.' 194 print
'(11x,A)',
'You may get spurious below-threshold noise.' 216 type(ScatAkCoeffs),
allocatable,
intent(inout) :: ak(:)
217 integer,
intent(in) :: lusct(:)
219 real(wp),
allocatable :: ReA(:), ImA(:)
220 integer :: i, j, u, keysc, nset, nrec, ninfo, ndata, stot, gutot, nscat, ich, ie, mye, nene
223 character(len=80) :: header
229 print
'(/,A,I0,/)',
'Reading wave function coefficients from unit ', u
231 open (u, status =
'old', action =
'read', form =
'unformatted')
233 read (u) keysc, nset, nrec, ninfo, ndata
235 read (u) nscat, ak(i) % mgvn, stot, gutot, ak(i) % nstat, ak(i) % nchan, ak(i) % nesc
237 print
'(2x,A,I0)',
'mgvn = ', ak(i) % mgvn
238 print
'(2x,A,I0)',
'stot = ', stot
239 print
'(2x,A,I0)',
'nstat = ', ak(i) % nstat
240 print
'(2x,A,I0)',
'nchan = ', ak(i) % nchan
241 print
'(2x,A,I0)',
'nesc = ', ak(i) % nesc
245 allocate (ak(i) % ichl(ak(i) % nchan), &
246 ak(i) % lvchl(ak(i) % nchan), &
247 ak(i) % mvchl(ak(i) % nchan), &
248 ak(i) % evchl(ak(i) % nchan))
250 read (u) ak(i) % ichl, ak(i) % lvchl, ak(i) % mvchl, ak(i) % evchl
252 print
'(/,2x,A)',
'channel table' 253 do j = 1, ak(i) % nchan
254 print
'(2x,4I6,F15.7)', j, ak(i) % ichl(j), ak(i) % lvchl(j), ak(i) % mvchl(j), ak(i) % evchl(j)
258 allocate (ak(i) % ReA(ak(i) % nstat, ak(i) % nchan, nene), &
259 ak(i) % ImA(ak(i) % nstat, ak(i) % nchan, nene), &
260 ak(i) % escat(ak(i) % nesc), &
261 rea(ak(i) % nstat), &
265 do ie = 1, ak(i) % nesc
267 do ich = 1, ak(i) % nchan
268 read (u) ak(i) % escat(ie), j, rea
269 read (u) ak(i) % escat(ie), j, ima
271 ak(i) % ReA(:, ich, mye) = rea
272 ak(i) % ImA(:, ich, mye) = ima
293 type(MolecularData),
intent(inout) :: moldat
295 integer(int32),
allocatable :: ltarg(:), starg(:), nconat(:)
296 real(real64),
allocatable :: r_points(:), cf(:, :, :), wmat2(:, :, :)
298 integer(int32) :: i, j, u, s, s1, s2, ntarg, nrg, nelc, nz, lrang2, lamax, inast, nchmx, nstmx, lmaxp1, nfdm
299 integer(int32) :: lrgl, nspn, npty
300 integer(int64) :: offset, length
301 real(real64) :: bbloch, delta_r
303 character(*),
parameter :: filename =
'molecular_data' 305 open (newunit = u, file = filename, access =
'stream', status =
'old', action =
'read')
307 print
'(/,A,/)',
'Reading file "molecular_data"' 310 length = s * int(s1, int64) * int(s2, int64) * wp_bytes
311 allocate (moldat % iidipy(s), moldat % ifdipy(s))
312 read (u) moldat % iidipy, moldat % ifdipy
313 inquire (u, pos = offset)
315 call moldat % dipy_mmap % init(filename, offset - 1, length)
316 call c_f_pointer(moldat % dipy_mmap % ptr, moldat % dipy, [s1, s2, s])
318 allocate (moldat % dipy(s1, s2, s))
319 read (u) moldat % dipy
321 offset = offset + length
322 print
'(2x,A,*(1x,I0))',
'[m = -1] iidip =', moldat % iidipy
323 print
'(2x,A,*(1x,I0))',
' ifdip =', moldat % ifdipy
325 read (u, pos = offset) s, s1, s2
326 length = s * int(s1, int64) * int(s2, int64) * wp_bytes
327 allocate (moldat % iidipz(s), moldat % ifdipz(s))
328 read (u) moldat % iidipz, moldat % ifdipz
329 inquire (u, pos = offset)
331 call moldat % dipz_mmap % init(filename, offset - 1, length)
332 call c_f_pointer(moldat % dipz_mmap % ptr, moldat % dipz, [s1, s2, s])
334 allocate (moldat % dipz(s1, s2, s))
335 read (u) moldat % dipz
337 offset = offset + length
338 print
'(2x,A,*(1x,I0))',
'[m = 0] iidip =', moldat % iidipz
339 print
'(2x,A,*(1x,I0))',
' ifdip =', moldat % ifdipz
341 read (u, pos = offset) s, s1, s2
342 length = s * int(s1, int64) * int(s2, int64) * wp_bytes
343 allocate (moldat % iidipx(s), moldat % ifdipx(s))
344 read (u) moldat % iidipx, moldat % ifdipx
345 inquire (u, pos = offset)
347 call moldat % dipx_mmap % init(filename, offset - 1, length)
348 call c_f_pointer(moldat % dipx_mmap % ptr, moldat % dipx, [s1, s2, s])
350 allocate (moldat % dipx(s1, s2, s))
351 read (u) moldat % dipx
353 offset = offset + length
354 print
'(2x,A,*(1x,I0))',
'[m = +1] iidip =', moldat % iidipx
355 print
'(2x,A,*(1x,I0))',
' ifdip =', moldat % ifdipx
357 read (u, pos = offset) ntarg
358 print
'(/,2x,A,I0)',
'ntarg = ', ntarg
359 allocate (moldat % crlv(ntarg, ntarg, 3))
360 read (u) moldat % crlv
363 allocate (moldat % rg(nrg), moldat % lm_rg(6, nrg))
364 read (u) moldat % rg, moldat % lm_rg
366 read (u) nelc, nz, lrang2, lamax, ntarg, inast, nchmx, nstmx, lmaxp1
367 read (u) moldat % rmatr, bbloch
368 allocate (moldat % etarg(ntarg), ltarg(ntarg), starg(ntarg))
369 read (u) moldat % etarg, ltarg, starg
370 read (u) nfdm, delta_r
371 allocate (r_points(nfdm + 1))
373 print
'(2x,A,*(1x,F8.3))',
'sampling radii:', r_points
375 print
'(/,2x,A)',
'number of inner eigenstates per symmetry' 377 allocate (nconat(ntarg), moldat % l2p(nchmx, inast), moldat % m2p(nchmx, inast), moldat % eig(nstmx, inast), &
378 moldat % wamp(nchmx, nstmx, inast), cf(nchmx, nchmx, lamax), moldat % ichl(nchmx, inast), &
379 moldat % mgvns(inast), moldat % nchan(inast), moldat % mnp1(inast))
383 read (u) lrgl, nspn, npty, moldat % nchan(i), moldat % mnp1(i)
384 moldat % mgvns(i) = lrgl - 1
385 print
'(4x,I3,I8)', moldat % mgvns(i), moldat % mnp1(i)
386 read (u) nconat, moldat % l2p(:, i), moldat % m2p(:, i)
387 read (u) moldat % eig(:, i), moldat % wamp(:, :, i), cf, moldat % ichl(:, i)
389 allocate (wmat2(s1, s2, nfdm))
396 print
'(/,2x,A,I0,A,I0,A)',
'channels in symmetry #', i,
' (IRR ', moldat % mgvns(i),
'):' 397 do j = 1, moldat % nchan(i)
398 print
'(2x,I3,A,I6,I3,SP,I6)', j,
':', moldat % ichl(j, i), moldat % l2p(j, i), moldat % m2p(j, i)
417 type(MolecularData),
intent(inout) :: moldat
420 call moldat % dipx_mmap % final
421 call moldat % dipy_mmap % final
422 call moldat % dipz_mmap % final
435 type(MolecularData),
intent(inout) :: moldat
437 integer :: maxl, i, l1, m1, l2, m2, l3, m3
439 maxl = maxval(moldat % lm_rg)
441 allocate (moldat % gaunt((maxl + 1)**2, (maxl + 1)**2, -1:1))
445 do i = 1,
size(moldat % rg)
446 l1 = moldat % lm_rg(1, i); m1 = moldat % lm_rg(2, i)
447 l2 = moldat % lm_rg(3, i); m2 = moldat % lm_rg(4, i)
448 l3 = moldat % lm_rg(5, i); m3 = moldat % lm_rg(6, i)
449 if (l3 /= 1 .or. abs(m3) > 1)
then 450 print
'(A)',
'Unexpected layout of the angular integral storage in molecular_data' 453 moldat % gaunt(l1*(l1+1) + m1 + 1, l2*(l2+1) + m2 + 1, m3) = moldat % rg(i)
469 type(MolecularData),
intent(in) :: moldat
470 integer,
intent(in) :: I
471 integer,
allocatable,
intent(inout) :: iidip(:), ifdip(:)
473 if (
allocated(iidip))
deallocate (iidip)
474 if (
allocated(ifdip))
deallocate (ifdip)
478 iidip = moldat % iidipx
479 ifdip = moldat % ifdipx
481 iidip = moldat % iidipy
482 ifdip = moldat % ifdipy
484 iidip = moldat % iidipz
485 ifdip = moldat % ifdipz
503 type(MolecularData),
intent(in) :: moldat
504 integer,
intent(in) :: I, s, nf, nn
505 character(len=1),
intent(in) :: transp
506 real(wp),
intent(inout) :: X(:, :, :), Y(:, :, :)
508 integer(blasint) :: lda, ldb, ldc, m, n, k
514 n =
size(x, 2) *
size(x, 3)
519 lda =
size(moldat % dipx, 1)
520 call blas_dgemm(transp,
'N', m, n, k,
rone, moldat % dipx(:,:,s), lda, x, ldb,
rzero, y, ldc)
522 lda =
size(moldat % dipy, 1)
523 call blas_dgemm(transp,
'N', m, n, k,
rone, moldat % dipy(:,:,s), lda, x, ldb,
rzero, y, ldc)
525 lda =
size(moldat % dipz, 1)
526 call blas_dgemm(transp,
'N', m, n, k,
rone, moldat % dipz(:,:,s), lda, x, ldb,
rzero, y, ldc)
545 type(MolecularData),
intent(in) :: moldat
546 integer,
intent(in) :: irr
547 character(len=1),
intent(in) :: transp
548 real(wp),
intent(inout) :: X(:,:), Y(:,:)
550 integer(blasint) :: m, n, k, lda, ldb, ldc
551 real(wp) :: alpha = 1, beta = 0
553 if (transp ==
'T')
then 554 m = moldat % mnp1(irr)
556 k = moldat % nchan(irr)
558 m = moldat % nchan(irr)
560 k = moldat % mnp1(irr)
563 lda =
size(moldat % wamp, 1)
567 call blas_dgemm(transp,
'N', m, n, k, alpha, moldat % wamp(:, :, irr), lda, x, ldb, beta, y, ldc)
581 type(MolecularData),
intent(in) :: moldat
582 integer,
intent(in) :: irr
583 real(wp),
allocatable,
intent(in) :: v(:)
584 real(wp),
allocatable,
intent(inout) :: vw(:, :)
586 integer :: k, nstat, p, nchan
588 nstat = moldat % mnp1(irr)
589 nchan = moldat % nchan(irr)
591 forall (p = 1:nchan, k = 1:nstat)
592 vw(k, p) = v(k) * moldat % wamp(p, k, irr)
606 type(MolecularData),
intent(in) :: moldat
608 complex(wp),
allocatable,
intent(inout) :: M(:, :, :)[:]
610 complex(wp),
allocatable,
intent(inout) :: M(:, :, :)
612 character(len=*),
intent(in) :: suffix
614 integer :: i, irr, mgvn, u, ichan, ichlf, lf, mf
615 character(len=100) :: filename
622 m(:, :, :) = m(:, :, :) + m(:, :, :)[i]
627 do irr = 1,
size(moldat % mgvns)
628 mgvn = moldat % mgvns(irr)
629 do ichan = 1, moldat % nchan(irr)
630 if (any(m(ichan, :, mgvn) /= 0))
then 631 ichlf = moldat % ichl(ichan, irr)
632 lf = moldat % l2p(ichan, irr)
633 mf = moldat % m2p(ichan, irr)
634 write (filename,
'(3(A,I0),A,SP,I0,3A)')
'pwdip-', mgvn,
'-(', ichlf,
',', lf,
',', mf,
')', suffix,
'.txt' 635 open (newunit = u, file = filename, action =
'write', form =
'formatted')
636 write (u,
'(2E25.15)') m(ichan, :, mgvn)
654 real(wp),
allocatable,
intent(inout) :: cs(:, :)[:]
656 real(wp),
allocatable,
intent(inout) :: cs(:, :)
665 cs(:, :) = cs(:, :) + cs(:, :)[i]
670 open (newunit = u, file =
'gen_photo_xsec.txt', action =
'write', form =
'formatted')
671 write (u,
'(2E25.15)') cs
subroutine write_cross_section(cs)
Write cross section to a file.
subroutine apply_boundary_amplitudes(moldat, irr, transp, X, Y)
Multiply by boundary amplitudes.
subroutine scale_boundary_amplitudes(moldat, irr, v, vw)
Scale boundary amplitudes matrix by a diagonal matrix.
I/O routines used by MULTIDIP.
subroutine read_molecular_data(moldat)
Read RMT molecular_data file.
subroutine get_diptrans(moldat, I, iidip, ifdip)
Return dipole transition descriptors.
real(wp), parameter rzero
subroutine apply_dipole_matrix(moldat, I, s, transp, nf, nn, X, Y)
Multiply by dipole matrix.
real(wp), parameter alpha
Fine structure constant.
Hard-coded parameters of MULTIDIP.
subroutine setup_angular_integrals(moldat)
Store the angular integrals in a more convenient shape.
subroutine read_kmatrices(km, lukmt, nkset)
Read K-matrix files.
subroutine read_wfncoeffs(ak, lusct)
Read wave function coefficients from file.
Special functions and objects used by MULTIDIP.
subroutine destruct_molecular_data(moldat)
Finalize the MolecularData object.
character(len=1), dimension(3), parameter compt
subroutine write_partial_wave_moments(moldat, M, suffix)
Write partial wave moments.