30 use precisn,
only: longint, wp
31 use const_gbl,
only: stdout
35 use global_utils,
only: indfunc
36 use integer_packing,
only: pack8ints, unpack8ints
37 use scatci_routines,
only: rdint, rdints
48 real(wp),
pointer :: one_electron_integral(:)
49 real(wp),
pointer :: two_electron_integral(:)
50 integer :: num_one_electron_integrals
51 integer :: num_two_electron_integrals
52 integer :: integral_ordering
53 integer :: use_scf = 0
56 integer :: num_unique_pairs
58 integer(longint),
allocatable :: pair_labels(:,:)
60 integer,
allocatable :: num_orbitals_sym(:)
62 integer :: max_number_pair_sets
63 integer,
allocatable :: num_two_electron_blocks(:)
64 integer,
allocatable :: num_one_electron_blocks(:)
65 integer,
allocatable :: one_electron_pointer(:)
66 integer,
allocatable :: two_electron_pointer(:)
68 integer :: num_pq, num_rs
69 integer :: num_pair_idx
72 integer,
allocatable :: pair_idx(:)
73 integer,
allocatable :: orbital_idx(:)
74 integer,
allocatable :: symmetry_idx(:)
104 integer :: pair_number, mdo, ndo, ido, jdo, nn(5), msym, begin, pass, istart, num_sym
106 num_sym = this % num_symmetries
107 msym = num_sym + num_sym - 1
110 if (this % use_SCF == 0)
then
115 do ndo = begin, num_sym
117 nn(3) = abs(ndo - mdo)
120 nn(5) = abs(ido - mdo)
130 do ndo = mdo / 2 + pass, num_sym
132 nn(3) = abs(ndo - mdo)
133 istart = ndo + 1 - pass
134 if (mdo /= 1 .and. pass == 1) begin = istart
135 do ido = begin, istart
137 nn(5) = abs(ido - mdo)
155 integer :: pair_number, npqrs, nn(5), mdo, ndo, ido, jdo, I, IBGN, IF, IPASS, J, K, M, MSYM, N, NBGN, begin, pass, num_sym
156 integer(longint) :: packed_label(2)
157 integer,
allocatable :: lpqrs(:,:)
159 num_sym = this % num_symmetries
160 msym = num_sym + num_sym - 1
162 allocate(lpqrs(5, this % num_unique_pairs))
166 if (this % use_SCF == 0)
then
171 do ndo = begin, num_sym
173 nn(3) = abs(ndo - mdo)
176 nn(5) = abs(ido - mdo)
177 pair_number = pair_number + 1
179 lpqrs(jdo,pair_number) = nn(jdo)
189 do n = m / 2 + ipass, num_sym
193 if (m /= 1 .and. ipass == 1) ibgn =
IF
197 pair_number = pair_number + 1
199 lpqrs(j,pair_number) = nn(j)
208 if (pair_number /= this % num_unique_pairs) stop
"Error in pair count"
210 do ido = 1, this % num_unique_pairs
211 call pack8ints(lpqrs(2,ido), lpqrs(3,ido), lpqrs(4,ido), lpqrs(5,ido), 0, 0, 0, 0, packed_label)
212 if (lpqrs(2,ido) + lpqrs(3,ido) /= lpqrs(1,ido)) packed_label(1) = -packed_label(1)
213 this % pair_labels(1,ido) = packed_label(1)
214 this % pair_labels(2,ido) = packed_label(2)
217 write (stdout,
"(' NMPRS=',I5//' LPQRS'/(2X,5(2X,I3)))") this % num_unique_pairs, &
218 ((lpqrs(ido,jdo), ido = 1, 5), jdo = 1, this % num_unique_pairs)
227 integer :: label(8), num_orbs(4), size_two_pointer
228 integer(longint) :: packed_label(2)
229 integer :: ido, jdo, nam1, nam2, num_pq, num_rs, num_pr
230 integer :: block_number, mvl, md, mm, m, mpa, mpb, mp
234 size_two_pointer = this % num_symmetries * (this % num_symmetries + 1) / 2
235 do ido = 2, this % num_symmetries
236 size_two_pointer = size_two_pointer + (this % num_symmetries - ido + 2) * (this % num_symmetries - ido + 1)
239 allocate(this % num_two_electron_blocks(2 * this % num_symmetries + 1))
241 this % num_two_electron_blocks(1) = 0
242 this % num_two_electron_blocks(2) = indfunc(this % num_symmetries + 1, 0)
244 mvl = 2 * this% num_symmetries - 1
248 mm = this % num_symmetries - md - 1
249 this% num_two_electron_blocks(ido + 1) = this % num_two_electron_blocks(ido) + indfunc(mm + 1, 0)
252 allocate(this % one_electron_pointer(this % num_symmetries + 1))
254 this % one_electron_pointer(1) = 1
256 do ido = 1, this % num_symmetries
257 this % one_electron_pointer(ido + 1) = this % one_electron_pointer(ido) + indfunc(this % num_orbitals_sym(ido) + 1, 0)
260 allocate(this % two_electron_pointer(this % num_two_electron_blocks(mvl + 1)))
262 do ido =1, this % num_two_electron_blocks(mvl + 1)
263 this % two_electron_pointer(ido) = 0
266 this % num_one_electron_integrals = this % one_electron_pointer(this % num_symmetries + 1) - 1
267 this % num_two_electron_integrals = 1
269 write (stdout,
"(//,5X,'Integral Storage Table follows : ',/)")
271 do ido = 1, this % num_unique_pairs
273 packed_label(1) = this % pair_labels(1,ido)
274 packed_label(2) = this % pair_labels(2,ido)
276 if (packed_label(1) > 0)
then
280 packed_label(1) = -packed_label(1)
283 call unpack8ints(packed_label, label)
286 num_orbs(jdo) = this % num_orbitals_sym(label(jdo) + 1)
290 m = label(1) + label(2)
292 m = abs(label(1) - label(2))
304 mp = (mpb * (mpb - 1)) / 2 + mpa + this % num_two_electron_blocks(m + 1)
307 mp = (mpa * (mpa - 1)) / 2 + mpb + this % num_two_electron_blocks(m + 1)
310 this % two_electron_pointer(mp) = this % num_two_electron_integrals
312 if (label(1) == label(2))
then
313 num_pq = indfunc(num_orbs(1) + 1, 0)
315 num_pq = num_orbs(1) * num_orbs(2)
318 if (label(3) == label(4))
then
319 num_rs = indfunc(num_orbs(3) + 1, 0)
321 num_rs = num_orbs(3) * num_orbs(4)
323 this % max_number_pair_sets = max(this % max_number_pair_sets, num_pq, num_rs)
324 if (label(1) == label(3) .and. label(2) == label(4))
then
325 this % num_two_electron_integrals = this % num_two_electron_integrals + indfunc(num_pq + 1, 0)
327 this % num_two_electron_integrals = this % num_two_electron_integrals + num_pq * num_rs
331 this % num_two_electron_integrals = this % num_two_electron_integrals - 1
333 write (stdout,
"('No of 1 electron integrals = ',i8)") this % num_one_electron_integrals
334 write (stdout,
"('No of 2 electron integrals = ',i8)") this % num_two_electron_integrals
341 integer :: total_num_orbitals, orbital, iorb, isym, max_orbitals, ifail
343 total_num_orbitals = sum(this % num_orbitals_sym(:))
345 allocate(this % orbital_idx(total_num_orbitals), &
346 this % symmetry_idx(total_num_orbitals), stat = ifail)
348 call master_memory % track_memory(kind(this % orbital_idx),
size(this % orbital_idx), ifail,
'SWEDEN::pair_idx')
349 call master_memory % track_memory(kind(this % symmetry_idx),
size(this % symmetry_idx), ifail,
'SWEDEN::symmetry_idx')
351 this % orbital_idx(:) = 0
352 this % symmetry_idx(:) = 0
357 do isym = 1,this % num_symmetries
358 max_orbitals = max(max_orbitals, this % num_orbitals_sym(isym)**2)
359 do iorb = 1, this % num_orbitals_sym(isym)
360 orbital = orbital + 1
361 this % orbital_idx(orbital) = iorb
362 this % symmetry_idx(orbital) = isym - 1
366 this % num_pair_idx = max((this% num_symmetries**2 + this % num_symmetries) / 2 + 1, &
367 this % max_number_pair_sets, &
376 integer :: ido, idx, ifail
378 allocate(this % pair_idx(0:this % num_pair_idx), stat = ifail)
380 call master_memory % track_memory(kind(this % pair_idx),
size(this % pair_idx), ifail,
'SWEDEN::pair_idx')
383 this % pair_idx(0) = 0
384 do ido = 1, this % num_pair_idx
385 this % pair_idx(ido) = idx
394 class(
options),
intent(in) :: option
397 write (stdout,
"('Using ALCHEMY integral')")
399 this % num_unique_pairs = 0
400 this % num_symmetries = option % num_syms
401 this % integral_ordering = option % integral_ordering
402 this % use_SCF = option % use_SCF
406 allocate(this % num_orbitals_sym(this % num_symmetries))
408 this % num_orbitals_sym(:) = option % num_electronic_orbitals_sym(:)
409 this % num_unique_pairs = this % count_num_pairs()
411 write (stdout, *)
'Number of pairs =',this % num_unique_pairs
413 allocate(this % pair_labels(2, this % num_unique_pairs))
415 write (stdout,*)
'ALCHEMY Integral -- Generating pairs'
418 call this % generate_pairs
419 call this % generate_orbital_index
420 call this % generate_pair_index
422 write (stdout,
"('1',/,10x,'D2h Two Electron Integral Box ','Information')")
423 write (stdout,
"( /,10x,'No. of Boxes = ',i4,/)") this % num_unique_pairs
424 write (stdout,
"( 10x,'Box Descriptions: ',/)")
425 write (stdout, *)
'ALCHEMY Integral -- Generating block pointers'
427 call this % generate_pointer_table
440 use params,
only: ctrans1, cpoly
441 use global_utils,
only: intape
442 use scatci_routines,
only: search, chn2e
445 integer,
intent(in) :: iounit
447 character(len=4),
dimension(4) :: LABEL
448 character(len=4),
dimension(33) :: NAM1
449 integer,
dimension(8) :: NAO, NCORE
450 integer,
dimension(20) :: NHE, NOB
451 real(wp),
allocatable :: xtempe(:), xtempp(:)
453 integer :: I, NSYM, IONEIN, NT, ND, LTRI, NNUC, N, IA, IAT, NALM
454 integer :: ifail, k, l, ind, IMAX, IMIN, NEND, IMAXP
455 real(wp) :: EN, SIGN, x1e
456 real(wp) :: vsmall = 1.e-10_wp
457 real(kind=wp),
dimension(20) :: charg, xnuc
459 write (stdout, *)
' Loading ALCHEMY Integrals into core'
463 allocate(this % one_electron_integral(2 * this % num_one_electron_integrals), stat = ifail)
464 if (ifail /= 0) stop
"could not allocate 1 electron integral"
467 allocate(this % two_electron_integral(this % num_two_electron_integrals), stat = ifail)
468 if (ifail /= 0) stop
"could not allocate 2 electron integral"
470 read (iounit) (nam1(i), i = 1, 33), nsym, nt, nnuc, nd, ltri, (nob(i), i = 1, nsym), (nd, i = 1, nt), (nd, i = 1, nt), &
471 (charg(i), i = 1, nnuc), (xnuc(i), i = 1, nnuc)
473 write (stdout,
"(/' Transformed integrals read:',/5X,30A4)") (nam1(i), i = 1, 30)
477 if (abs(charg(n)) < vsmall) cycle
479 if (abs(charg(i)) < vsmall) cycle
480 en = en + charg(n) * charg(i) / abs(xnuc(n) - xnuc(i))
484 this % core_energy = en
486 write (stdout,
"(' NSYM =',I5,3X,'NOB =',20I5)") nsym, (nob(i), i = 1, nsym)
487 write (stdout,
"(/,10x,'Nuclear repulsion energy = ',f15.7)") en
488 write (stdout,
"(' NNUC =',I5,3X,'CHARG=',10F10.0/21X,10F10.0)") nnuc, (charg(i), i = 1, nnuc)
489 write (stdout,
"(15X,'XNUC =',10F10.5/21X,10F10.5)") (xnuc(i), i = 1, nnuc)
492 call rdints(iounit, nsym, nob, ltri, this % num_one_electron_integrals + 1, ia, this % one_electron_integral, nalm)
494 if (nalm /= 0) stop
"UNABLE TO READ ALCHEMY INTEGRALS"
497 call rdints(iounit, nsym, nob, ltri, this % num_one_electron_integrals + 1, ia, this % one_electron_integral, nalm)
499 if (nalm /= 0) stop
"UNABLE TO READ ALCHEMY INTEGRALS"
503 allocate(xtempp(this % num_one_electron_integrals))
504 call rdints(iounit, nsym, nob, ltri, this % num_one_electron_integrals + 1, ia, xtempp, nalm)
508 if (iat /= this % num_one_electron_integrals) stop
"INCORRECT NUMBER OF INTEGRALS"
510 if(abs(this % positron_flag) == 1) sign = -1.0
512 x1e = this % one_electron_integral(i) + xtempp(i)
513 this % one_electron_integral(i) = x1e
525 call rdint(imin, imax, nend, imaxp, iounit, ia, this % num_two_electron_integrals + 1, this % two_electron_integral)
526 if (nend /= 1) stop
"UNABLE TO READ ALCHEMY INTEGRALS"
532 1600
FORMAT(
' Integrals read successfully:', /, &
533 ' 1-electron integrals, NINT1e =',i10, /, &
534 ' 2-electron integrals, NINT2e =',i10)
535 write (stdout, 1600) this % num_one_electron_integrals, this % num_two_electron_integrals
537 this % nhe(:) = nhe(:)
541 this % nhe(:) = nob(:)
542 this % dtnuc(22:21+nnuc) = xnuc(1:nnuc)
543 this % dtnuc(2:1+nnuc) = charg(1:nnuc)
550 integer,
intent(in) :: i,j,k,l,m
552 integer :: ia, ib, integral_idx
558 integral_idx = this % get_one_electron_index(j, l, m)
559 coeff = this % one_electron_integral(integral_idx)
562 integral_idx = this % get_two_electron_index(i, j, k, l, m)
563 coeff = this % two_electron_integral(integral_idx)
575 integer,
intent(in) :: i, j, pos
576 integer :: m, p, q, ii, jj
578 ii = this % orbital_mapping(i)
579 jj = this % orbital_mapping(j)
581 p = this % orbital_idx(ii)
582 q = this % orbital_idx(jj)
584 m = this % symmetry_idx(ii)
600 integer,
intent(in) :: i, j, k, l, m
601 integer :: symmetry, mpp(4), nbp(4), npp(4), mapped(4), npq(4), ido, block_pointer, ipqrs, mv, md, mpq, mrs, mpr
603 mapped(1) = this % orbital_mapping(i)
604 mapped(2) = this % orbital_mapping(j)
605 mapped(3) = this % orbital_mapping(k)
606 mapped(4) = this % orbital_mapping(l)
609 npp(ido) = this % orbital_idx(mapped(ido))
610 symmetry = this % symmetry_idx(mapped(ido))
612 nbp(ido) = this % num_orbitals_sym(symmetry + 1)
618 mv = abs(mpp(1) - mpp(2))
629 mpr = this % pair_idx(mpq) + mrs + this % num_two_electron_blocks(mv + 1)
631 block_pointer = this % two_electron_pointer(mpr) - 1
634 if (mpp(ido) /= mpp(ido + 1))
then
635 npq(ido) = nbp(ido) * (npp(ido + 1) - 1) + npp(ido)
636 npq(ido + 1) = nbp(ido) * nbp(ido + 1)
638 if (npp(ido) < npp(ido + 1))
then
639 npq(ido) = this % pair_idx(npp(ido + 1)) + npp(ido)
641 npq(ido) = this % pair_idx(npp(ido)) + npp(ido + 1)
643 npq(ido + 1) = this % pair_idx(nbp(ido) + 1)
647 if (mpp(1) == mpp(3) .and. mpp(2) == mpp(4))
then
648 if (npq(1) < npq(3))
then
649 ipqrs = this % pair_idx(npq(3)) + npq(1)
651 ipqrs = this % pair_idx(npq(1)) + npq(3)
654 if (this % integral_ordering == 0)
then
655 ipqrs = npq(2) * (npq(3) - 1) + npq(1)
657 ipqrs = npq(4) * (npq(1) - 1) + npq(3)
669 use params,
only : cpoly
670 use scatci_routines,
only : search
673 integer,
intent(in) :: iounit
674 integer :: ido, ifail
690 if (
associated(this % one_electron_integral))
deallocate(this % one_electron_integral)
691 if (
associated(this % two_electron_integral))
deallocate(this % two_electron_integral)
693 if (
allocated(this % pair_labels))
deallocate(this % pair_labels)
696 if (
allocated(this % num_orbitals_sym))
deallocate(this % num_orbitals_sym)
698 if (
allocated(this % one_electron_pointer))
deallocate(this % one_electron_pointer)
699 if (
allocated(this % two_electron_pointer))
deallocate(this % two_electron_pointer)
701 if (
allocated(this % pair_idx))
deallocate(this % pair_idx)
702 if (
allocated(this % orbital_idx))
deallocate(this % orbital_idx)
703 if (
allocated(this % symmetry_idx))
deallocate(this % symmetry_idx)
705 if (
allocated(this % num_two_electron_blocks))
deallocate(this % num_two_electron_blocks)
706 if (
allocated(this % num_one_electron_blocks))
deallocate(this % num_one_electron_blocks)