MPI-SCATCI 2.0
An MPI version of SCATCI
Loading...
Searching...
No Matches
SWEDEN_Module.F90
Go to the documentation of this file.
1! Copyright 2019
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-in (UKRmol+ suite).
7!
8! UKRmol-in 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-in 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-in (in source/COPYING). Alternatively, you can also visit
20! <https://www.gnu.org/licenses/>.
21
22!> \brief SWEDEN integral module
23!> \authors A Al-Refaie
24!> \date 2017
25!>
26!> \note 16/01/2019 - Jakub Benda: Unifom coding style and expanded documentation.
27!>
28module sweden_module
29
30 use const_gbl, only: stdout
31 use consts_mpi_ci, only: nidx
32 use global_utils, only: indfunc, mprod
33 use mpi_memory_gbl, only: mpi_memory_allocate_real, mpi_memory_deallocate_real, mpi_memory_synchronize, local_master
34 use precisn, only: longint, wp
35 use baseintegral_module, only: baseintegral
36 use memorymanager_module, only: master_memory
37 use options_module, only: options
38 use parallelization_module, only: grid => process_grid
39 use timing_module, only: master_timer
40 use utility_module, only: pack_ints, unpack_ints
41
42 implicit none
43
44 public swedenintegral
45
46 private
47
48 type, extends(baseintegral) :: swedenintegral
49
50 !Our integrals
51#ifdef mpithree
52 real(wp), pointer :: one_electron_integral(:)
53 real(wp), pointer :: two_electron_integral(:)
54#else
55 real(wp), allocatable :: one_electron_integral(:)
56 real(wp), allocatable :: two_electron_integral(:)
57#endif
58
59 integer :: one_electron_window
60 integer :: two_electron_window
61
62 integer :: num_one_electron_integrals
63 integer :: num_two_electron_integrals
64
65 real(wp), allocatable :: xnuc(:),ynuc(:),znuc(:),charge(:)
66 character(len=8), allocatable :: cname(:)
67
68 integer :: num_unique_pairs !> How many IJKL pairs we have
69 integer(longint), allocatable :: pair_labels(:,:) !> The list of unique labels
70 integer, allocatable :: num_orbitals_sym(:) !> The number of labels per symmetry
71
72 integer :: max_number_pair_sets
73 integer :: num_two_electron_blocks
74 integer, allocatable :: one_electron_pointer(:)
75 integer, allocatable :: two_electron_pointer(:)
76
77 integer :: num_pq, num_rs
78 integer :: num_pair_idx
79
80 !>the pair id
81 integer, allocatable :: pair_idx(:)
82 integer, allocatable :: orbital_idx(:)
83 integer, allocatable :: symmetry_idx(:)
84
85 contains
86
87 procedure, public :: initialize_self => initialize_sweden
88 procedure, public :: finalize_self => finalize_sweden
89 procedure, public :: load_integrals => load_integrals_sweden
90 procedure, public :: get_integral_ijklm => get_integral_sweden
91 procedure, public :: write_geometries => write_geometries_sweden
92 procedure, public :: destroy_integrals => destroy_integral_sweden
93 procedure, private :: count_num_pairs
94 procedure, private :: generate_pairs
95 procedure, private :: generate_pointer_table
96 procedure, private :: generate_pair_index
97 procedure, private :: generate_orbital_index
98 !procedure, private :: read_one_electron_integrals
99 !procedure, private :: read_two_electron_integrals
100 procedure, private :: get_one_electron_index
101 procedure, private :: get_two_electron_index
102
103 end type swedenintegral
104
105contains
106
107 integer function count_num_pairs (this)
108 use global_utils, only: mprod
109
110 class(swedenintegral) :: this
111 integer :: i, j, k, l
112 integer :: jend, lend
113 integer :: ij, kl, ijkltest
114
115 count_num_pairs = 0
116
117 do i = 1, this % num_symmetries
118 count_num_pairs = count_num_pairs + 1
119 end do
120
121 if (this % num_symmetries == 1) return
122
123 !Generate IJIJ pairs
124 do i = 2, this % num_symmetries
125 jend = i - 1
126 do j = 1, jend
127 lend = j - 1
128 count_num_pairs = count_num_pairs + 1
129 end do
130 end do
131
132 !Generate IIJJ pairs
133 do i = 2, this % num_symmetries
134 jend = i - 1
135 do j = 1, jend
136 lend = j - 1
137 count_num_pairs = count_num_pairs + 1
138 end do
139 end do
140
141 if (this % num_symmetries < 4) return
142
143 do i = 2, this % num_symmetries
144 jend = i - 1
145 do j = 1, jend
146 do k = 2, i
147 lend = k - 1
148 if (i == k) lend = j
149 do l = 1, lend
150 if (i == k .and. j == l) cycle
151 ij = mprod(i, j, 0, stdout)
152 kl = mprod(k, l, 0, stdout)
153 ijkltest = mprod(ij, kl, 0, stdout)
154 if (ijkltest /= 1) cycle
155 count_num_pairs = count_num_pairs + 1
156 end do
157 end do
158 end do
159 end do
160
161 end function count_num_pairs
162
163
164 subroutine generate_pairs (this)
165 class(swedenintegral) :: this
166 integer :: i, j, k, l
167 integer :: jend, lend
168 integer :: ij, kl, ijkltest
169 integer :: pair_number
170
171 pair_number = 0
172
173 write (stdout, *) 'All IIII blocks of integrals'
174
175 do i = 1, this % num_symmetries
176 j = i - 1
177 pair_number = pair_number + 1
178 call pack_ints(j, j, j, j, 0, 0, 0, 0, this % pair_labels(:, pair_number))
179 write (stdout, *) pair_number, j, j, j, j
180 end do
181
182 if (this % num_symmetries == 1) return
183
184 !Generate IJIJ pairs
185 write (stdout, *) 'All IJIJ blocks'
186 do i = 2, this % num_symmetries
187 jend = i - 1
188 do j = 1, jend
189 lend = j - 1
190 pair_number = pair_number + 1
191 call pack_ints(jend, lend, jend, lend, 0, 0, 0, 0, this % pair_labels(:, pair_number))
192 write (stdout, *) pair_number, jend, lend, jend, lend
193 end do
194 end do
195
196 !Generate IIJJ pairs
197 write (stdout, *) 'All IIJJ blocks'
198 do i = 2, this % num_symmetries
199 jend = i - 1
200 do j = 1, jend
201 lend = j - 1
202 pair_number = pair_number + 1
203 call pack_ints(jend, jend, lend, lend, 0, 0, 0, 0, this % pair_labels(:, pair_number))
204 write (stdout, *) pair_number, jend, jend, lend, lend
205 end do
206 end do
207
208 if (this % num_symmetries < 4) return
209 write (stdout, *)'All IJKL blocks'
210 do i = 2, this % num_symmetries
211 jend = i - 1
212 do j = 1, jend
213 do k = 2, i
214 lend = k - 1
215 if (i == k) lend = j
216 do l = 1, lend
217 if (i == k .and. j == l) cycle
218 ij = mprod(i, j, 0, stdout)
219 kl = mprod(k, l, 0, stdout)
220 ijkltest = mprod(ij, kl, 0, stdout)
221 if (ijkltest /=1 ) cycle
222 pair_number = pair_number + 1
223 call pack_ints(i - 1, j - 1, k - 1, l - 1, 0, 0, 0, 0, this % pair_labels(:, pair_number))
224 write (stdout, *) pair_number, i - 1, j - 1, k - 1, l - 1
225 end do
226 end do
227 end do
228 end do
229
230 end subroutine generate_pairs
231
232
233 subroutine generate_pointer_table (this)
234 class(swedenintegral) :: this
235
236 integer :: label(8), num_orbs(4)
237 integer :: ido, jdo, nam1, nam2, num_pq, num_rs, num_pr
238 integer :: block_number, err
239
240 this % num_two_electron_blocks = indfunc(this % num_symmetries + 1, 0)
241 this % num_two_electron_blocks = indfunc(this % num_two_electron_blocks + 1, 0)
242 this % num_two_electron_integrals = 1
243
244 allocate(this % one_electron_pointer(this % num_symmetries + 1), stat = err)
245
246 call master_memory % track_memory(storage_size(this % one_electron_pointer)/8, &
247 size(this % one_electron_pointer), err, 'SWEDEN::One electron pointer')
248
249 this % one_electron_pointer(1) = 1
250
251 do ido = 1, this % num_symmetries
252 this % one_electron_pointer(ido + 1) = this % one_electron_pointer(ido) + indfunc(this % num_orbitals_sym(ido) + 1, 0)
253 end do
254
255 this % num_one_electron_integrals = this % one_electron_pointer(this % num_symmetries + 1) - 1
256
257 allocate(this % two_electron_pointer(this % num_two_electron_blocks), stat = err)
258
259 call master_memory % track_memory(storage_size(this % two_electron_pointer)/8, &
260 size(this % two_electron_pointer), err, 'SWEDEN::Two electron pointer')
261
262 this % two_electron_pointer(:) = 0
263
264 write (stdout, "(//,5X,'Integral Storage Table follows : ',/)")
265
266 do ido = 1, this % num_unique_pairs
267 !> Get our lsabels
268 call unpack_ints(this % pair_labels(:, ido), label)
269
270 do jdo = 1, 4
271 label(jdo) = label(jdo) + 1
272 num_orbs(jdo) = this % num_orbitals_sym(label(jdo))
273 end do
274
275 ! if IIJJ
276 if (label(1) == label(2)) then
277 num_pq = indfunc(num_orbs(1) + 1, 0)
278 else
279 num_pq = num_orbs(1) * num_orbs(2)
280 end if
281 nam1 = indfunc(max(label(1), label(2)) + 1, 0) - abs(label(1) - label(2))
282
283 ! if JJ
284 if (label(3) == label(4)) then
285 num_rs = indfunc(num_orbs(3) + 1, 0)
286 else
287 num_rs = num_orbs(3) * num_orbs(4)
288 end if
289
290 nam2 = indfunc(max(label(3), label(4)) + 1, 0) - abs(label(3)-label(4))
291 block_number = indfunc(max(nam1, nam2) + 1, 0) - abs(nam1 - nam2)
292 this % two_electron_pointer(block_number) = this % num_two_electron_integrals
293
294 write (stdout, "(3X,4I3,1X,I5,1X,I10)") label(1), label(2), label(3), label(4), &
295 block_number, this % num_two_electron_integrals
296
297 if (nam1 == nam2) then
298 num_pr = indfunc(num_pq + 1, 0)
299 else
300 num_pr = num_pq * num_rs
301 end if
302
303 this % max_number_pair_sets = max(this % max_number_pair_sets, num_pq, num_rs)
304 if (num_pr > 0) this % num_two_electron_integrals = this % num_two_electron_integrals + num_pr + 1
305 end do
306
307 !Move to the end of the block
308 this % num_two_electron_integrals = this % num_two_electron_integrals - 1
309
310 write (stdout, "('No of 1 electron integrals = ',i8)") this % num_one_electron_integrals
311 write (stdout, "('No of 2 electron integrals = ',i8)") this % num_two_electron_integrals
312
313 end subroutine generate_pointer_table
314
315
316 subroutine generate_orbital_index (this)
317 class(swedenintegral) :: this
318 integer :: total_num_orbitals, orbital, iorb, isym, max_orbitals, ifail
319
320 total_num_orbitals = sum(this % num_orbitals_sym(:))
321
322 allocate(this % orbital_idx(total_num_orbitals), this % symmetry_idx(total_num_orbitals), stat = ifail)
323
324 call master_memory % track_memory(storage_size(this%orbital_idx)/8, size(this % orbital_idx), ifail, 'SWEDEN::pair_idx')
325 call master_memory % track_memory(storage_size(this%symmetry_idx)/8, size(this % symmetry_idx), ifail, &
326 'SWEDEN::symmetry_idx')
327
328 this % orbital_idx(:) = 0
329 this % symmetry_idx(:) = 0
330
331 max_orbitals = 0
332 orbital = 0
333
334 do isym = 1, this % num_symmetries
335 max_orbitals = max(max_orbitals, this % num_orbitals_sym(isym)**2)
336 do iorb = 1, this % num_orbitals_sym(isym)
337 orbital = orbital + 1
338 this % orbital_idx(orbital) = iorb
339 this % symmetry_idx(orbital) = isym - 1
340 end do
341 end do
342
343 this % num_pair_idx = max((this % num_symmetries**2 + this % num_symmetries) / 2 + 1, &
344 this % max_number_pair_sets, &
345 300, &
346 max_orbitals)
347
348 end subroutine generate_orbital_index
349
350
351 subroutine generate_pair_index (this)
352 class(swedenintegral) :: this
353 integer :: ido, idx, ifail
354
355 allocate(this % pair_idx(0:this%num_pair_idx), stat = ifail)
356 call master_memory % track_memory(storage_size(this % pair_idx)/8, size(this % pair_idx), ifail, 'SWEDEN::pair_idx')
357
358 idx = 0
359 this % pair_idx(0) = 0
360 do ido = 1, this % num_pair_idx
361 this % pair_idx(ido) = idx
362 idx = idx + ido
363 end do
364
365 end subroutine generate_pair_index
366
367
368 subroutine initialize_sweden (this, option)
369 class(swedenintegral) :: this
370 class(options), intent(in) :: option
371 integer :: ido, jdo, ifail
372
373 write (stdout, "('Using SWEDEN integral')")
374
375 this % num_unique_pairs = 0
376 this % num_symmetries = option % num_syms
377
378 allocate(this % num_orbitals_sym(this % num_symmetries), stat = ifail)
379 call master_memory % track_memory(storage_size(this % num_orbitals_sym)/8, &
380 size(this % num_orbitals_sym), ifail, 'SWEDEN::num_orbitals_sym')
381
382 this % num_orbitals_sym(:) = option % num_electronic_orbitals_sym(:)
383 this % num_unique_pairs = this % count_num_pairs()
384
385 allocate(this % pair_labels(nidx, this % num_unique_pairs), stat = ifail)
386 call master_memory % track_memory(storage_size(this % pair_labels)/8, &
387 size(this % pair_labels), ifail, 'SWEDEN::Pair labels')
388
389 write (stdout, *) 'SWEDEN Integral -- Generating pairs'
390
391 !>Generate indexes
392 call this % generate_pairs
393 call this % generate_orbital_index
394 call this % generate_pair_index
395
396 write (stdout, "('1',/,10x,'D2h Two Electron Integral Box ','Information')")
397 write (stdout, "( /,10x,'No. of Boxes = ',i4,/)") this % num_unique_pairs
398 write (stdout, "( 10x,'Box Descripti ons: ',/)")
399 write (stdout, *) 'SWEDEN Integral -- Generating block pointers'
400
401 call this % generate_pointer_table
402
403 end subroutine initialize_sweden
404
405
406 subroutine finalize_sweden (this)
407 class(swedenintegral) :: this
408 end subroutine finalize_sweden
409
410
411 !>This is just a copy from scatci_routines with only the relevant SWEDEN parts
412 subroutine load_integrals_sweden (this, iounit)
413 use params, only: ctrans1, cpoly
414 use global_utils, only: intape
415 use scatci_routines, only: search, chn2e
416
417 class(swedenintegral) :: this
418 integer, intent(in) :: iounit
419
420 ! Sweden header arrays
421 character(len=4), dimension(4) :: LABEL
422 character(len=4), dimension(33) :: NAM1
423 integer(longint), dimension(8) :: NAO, NCORE
424 integer(longint), dimension(20) :: NHE, NOB
425 real(wp), allocatable :: xtempe(:), xtempp(:)
426
427 integer(longint) :: I, NSYM, IONEIN
428 integer :: ifail, k, l, ind, ii
429 real(wp) :: EN
430
431 call master_timer % start_timer('SWEDEN load')
432
433 write (stdout, *) ' Loading SWEDEN Integrals into core'
434
435 !allocate the integral space, this will be replaced by a caching system
436 !One electron integral
437 !allocate(this%one_electron_integral(2*this%num_one_electron_integrals),stat=ifail)
438 this % one_electron_window = mpi_memory_allocate_real(this % one_electron_integral, 2 * this % num_one_electron_integrals)
439
440 !if(ifail /=0) stop "could not allocate 1 electron integral"
441
442 !Two electron integral
443 this % two_electron_window = mpi_memory_allocate_real(this % two_electron_integral, this % num_two_electron_integrals)
444
445 call mpi_memory_synchronize(this % one_electron_window)
446 call mpi_memory_synchronize(this % two_electron_window)
447
448 !if( (this%two_electron_window == -1 .and. this%one_electron_window == -1) .or. local_rank == local_master) then
449 !if(ifail /=0) stop "could not allocate 2 electron integral"
450
451 read (iounit) (label(i), i = 1, 4)
452
453 write (stdout, fmt='(/,5X,''Label on Sweden tape = '',4A)') (label(i), i = 1, 4)
454
455 read (iounit) nsym, en, (nao(i), nob(i), ncore(i), i = 1, nsym)
456
457 write (stdout, "(' NSYM =',I5,3X,'NOB =',20I5)") nsym, (nob(i), i = 1, nsym)
458 write (stdout, "(/,10x,'Nuclear repulsion energy = ',f15.7)") en
459 write (stdout, "(/10x,' NAO NMO NCORE',/,(10x,2I5,i7))") (nao(i), nob(i), ncore(i), i = 1, nsym)
460
461 this % core_energy = en
462
463 do i = 1, nsym
464 if (ncore(i) /= 0) then
465 write (stdout, "(10X,'Non-zero CORE in Sweden. Sym no. = ',i5,' Ncore = ',I5,/)") i, ncore(i)
466 write (stdout, "(10X,'Core Energy = ',F15.7,' Hartrees ',/)") en
467 end if
468 end do
469
470 !Do Erro checkin here will ignore for now
471
472 ionein = 0
473 do i = 1, nsym
474 ionein = ionein + (nob(i) * (nob(i) + 1)) / 2
475 end do
476
477 if ((this % two_electron_window == -1 .and. this % one_electron_window == -1) .or. grid % lrank == local_master) then
478 call search(iounit, ctrans1, ifail)
479 read (iounit)
480 call intape(iounit, this % one_electron_integral, this % num_one_electron_integrals)
481
482 !Positron case
483 if (this % positron_flag /= 0) then
484 allocate(xtempe(this % num_one_electron_integrals), stat = ifail)
485 call master_memory % track_memory(storage_size(xtempe)/8, size(xtempe), ifail, 'SWEDEN::xtempe')
486
487 allocate(xtempp(this % num_one_electron_integrals), stat = ifail)
488 call master_memory % track_memory(storage_size(xtempp)/8, size(xtempp), ifail, 'SWEDEN::xtempp')
489
490 xtempe(1:this % num_one_electron_integrals) = this % one_electron_integral(1:this % num_one_electron_integrals)
491 call intape(iounit, xtempp, this % num_one_electron_integrals)
492
493 !Are we using Quantemol-N?
494 if (this % quantamoln_flag) then
495 ind = 0
496 do k = 1, nsym
497 DO l = 1, nob(k)
498 ind = ind + l
499 write (413, "(i6,3x,i6,3x,i6,5x,f12.7)") k - 1, l, l, xtempp(ind)
500 end do
501 end do
502 end if
503
504 do i = 1, this % num_one_electron_integrals
505 this % one_electron_integral(i + this % num_one_electron_integrals) = 2.0_wp * xtempp(i) - xtempe(i)
506 end do
507
508 call master_memory % free_memory(storage_size(xtempp)/8, size(xtempp))
509 deallocate(xtempp)
510 call master_memory % free_memory(storage_size(xtempe)/8, size(xtempe))
511 deallocate(xtempe)
512 end if
513
514 call chn2e(iounit, stdout, this % two_electron_integral, this % num_two_electron_integrals)
515 end if
516
517 1600 format(' Integrals read successfully:', /, &
518 ' 1-electron integrals, NINT1e =',i10, /, &
519 ' 2-electron integrals, NINT2e =',i10)
520
521 write (stdout, 1600) this % num_one_electron_integrals, this % num_two_electron_integrals
522
523 this % nhe(:) = nhe(:)
524 this % nnuc = 0
525 this % dtnuc(:) = 0
526 this % dtnuc(1) = en
527 this % nhe(:) = nob(:)
528 this % dtnuc(22:41) = 0
529 this % dtnuc(2:21) = 0
530
531 !Reading Geometries
532 rewind iounit
533 call search(iounit, cpoly, ifail)
534 read (iounit) this % nnuc
535
536 allocate(this % xnuc(this % nnuc), this % ynuc(this % nnuc), this % znuc(this % nnuc), &
537 this % charge(this % nnuc), this % CNAME(this % nnuc))
538
539 do i = 1, this % nnuc
540 read (iounit) this % cname(i), ii, this % xnuc(i), this % ynuc(i), this % znuc(i), this % charge(i)
541 end do
542
543 call master_timer % stop_timer('SWEDEN load')
544
545 !endif
546
547 call mpi_memory_synchronize(this % one_electron_window)
548 call mpi_memory_synchronize(this % two_electron_window)
549
550 end subroutine load_integrals_sweden
551
552
553 function get_integral_sweden (this, i, j, k, l, m) result(coeff)
554 class(swedenintegral) :: this
555 integer, intent(in) :: i, j, k, l, m
556 real(wp) :: coeff
557 integer :: ia, ib, integral_idx
558
559 coeff = 0.0
560
561 !One electron case
562 if (i == 0) then
563 integral_idx = this % get_one_electron_index(j, l, m)
564 coeff = this % one_electron_integral(integral_idx)
565 else
566 integral_idx = this % get_two_electron_index(i, j, k, l, m)
567 coeff = this % two_electron_integral(integral_idx)
568 end if
569
570 end function get_integral_sweden
571
572
573 integer function get_one_electron_index (this, i, j, pos)
574 class(swedenintegral), intent(in) :: this
575 integer, intent(in) :: i, j, pos
576 integer :: m, p, q, ii, jj
577
578 ii = this % orbital_mapping(i)
579 jj = this % orbital_mapping(j)
580
581 p = this % orbital_idx(ii)
582 q = this % orbital_idx(jj)
583
584 m = this % symmetry_idx(ii)
585
586 if (p < q) then
587 get_one_electron_index = this % pair_idx(q) + p + this % one_electron_pointer(m + 1) - 1
588 else
589 get_one_electron_index = this % pair_idx(p) + q + this % one_electron_pointer(m + 1) - 1
590 end if
591
592 if (pos /= 0) get_one_electron_index = get_one_electron_index + this % num_one_electron_integrals
593 !write(stdout,"(10i8)") 0,p,0,q,0,get_one_electron_index,m,this%one_electron_pointer(m+1),this%pair_idx(p)
594
595 end function get_one_electron_index
596
597
598 integer function get_two_electron_index (this, i, j, k, l, m)
599 class(swedenintegral), intent(in) :: this
600 integer, intent(in) :: i, j, k, l, m
601 integer :: symmetry
602 integer, dimension(4) :: orb_num_sym, orb_sym, num_orb_sym
603 integer :: mapped(4)
604 integer :: ido
605 integer :: mpq, mrs, mpr, aaa, block_pointer, nobrs, nobpq, ipqrs
606
607 mapped(1) = this % orbital_mapping(i)
608 mapped(2) = this % orbital_mapping(j)
609 mapped(3) = this % orbital_mapping(k)
610 mapped(4) = this % orbital_mapping(l)
611
612 do ido = 1, 4
613 orb_num_sym(ido) = this % orbital_idx(mapped(ido))
614 symmetry = this % symmetry_idx(mapped(ido)) + 1
615 orb_sym(ido) = symmetry
616 num_orb_sym(ido) = this % num_orbitals_sym(symmetry)
617 end do
618
619 !write(stdout,"(4i4,2x,4i4,2x,4i4)") orb_num_sym(1:4),orb_sym(1:4),num_orb_sym(1:4)
620
621 mpq = this % pair_idx(orb_sym(1)) + orb_sym(2)
622 mrs = this % pair_idx(orb_sym(3)) + orb_sym(4)
623 mpr = this % pair_idx(mpq) + mrs
624
625 if (mpq == mrs .and. &
626 ( orb_num_sym(1) < orb_num_sym(3) .or. &
627 (orb_num_sym(1) == orb_num_sym(3) .and. orb_num_sym(2) < orb_num_sym(4)) .or. &
628 (orb_num_sym(1) < orb_num_sym(3) .and. orb_num_sym(2) < orb_num_sym(4)) )) then
629 aaa = orb_num_sym(1) ; orb_num_sym(1) = orb_num_sym(3) ; orb_num_sym(3) = aaa
630 aaa = orb_sym(1) ; orb_sym(1) = orb_sym(3) ; orb_sym(3) = aaa
631 aaa = orb_num_sym(2) ; orb_num_sym(2) = orb_num_sym(4) ; orb_num_sym(4) = aaa
632 aaa = orb_sym(2) ; orb_sym(2) = orb_sym(4) ; orb_sym(4) = aaa
633 end if
634
635 block_pointer = this % two_electron_pointer(mpr) - 1
636
637 if (orb_sym(1) == orb_sym(2) .and. orb_sym(3) == orb_sym(4) .and. orb_sym(1) == orb_sym(3)) then
638 ipqrs = this % pair_idx(orb_num_sym(1)) + orb_num_sym(2)
639 !IF(ipqrs.GT.nobtest)WRITE(6,910)ipqrs, nobtest
640 ipqrs = this % pair_idx(ipqrs - 1) + ipqrs - 1 + this % pair_idx(orb_num_sym(3)) + orb_num_sym(4)
641 else if (orb_sym(1) == orb_sym(3) .and. orb_sym(2) == orb_sym(4)) then
642 ipqrs = (orb_num_sym(1) - 1) * num_orb_sym(2) + orb_num_sym(2) - 1
643 ! IF(ipqrs.GT.nobtest)WRITE(6,910)ipqrs, nobtest
644 ipqrs = this % pair_idx(ipqrs) + ipqrs + (orb_num_sym(3) - 1) * num_orb_sym(4) + orb_num_sym(4)
645 else if (orb_sym(1) == orb_sym(2) .and. orb_sym(3) == orb_sym(4)) then
646 nobrs = this % pair_idx(num_orb_sym(3)) + num_orb_sym(3)
647 ipqrs = (this % pair_idx(orb_num_sym(1)) + orb_num_sym(2) - 1)*nobrs + this % pair_idx(orb_num_sym(3)) + orb_num_sym(4)
648 else
649 nobrs = num_orb_sym(3) * num_orb_sym(4)
650 ipqrs = ((orb_num_sym(1) - 1) * num_orb_sym(2) + orb_num_sym(2) - 1) * nobrs + (orb_num_sym(3) - 1) * num_orb_sym(4) &
651 + orb_num_sym(4)
652 end if
653
654 get_two_electron_index = ipqrs + block_pointer + 1
655
656 !write(stdout,"(6i8)") i,j,k,l,m,get_two_electron_index
657
658 end function get_two_electron_index
659
660
661 subroutine write_geometries_sweden (this, iounit)
662 use params, only: cpoly
663 use scatci_routines, only: search
664
665 class(swedenintegral), intent(in) :: this
666 integer, intent(in) :: iounit
667 integer :: ido, ifail, i
668
669 do ido = 1, this % nnuc
670 write (iounit) this % cname(ido), this % xnuc(ido), this % ynuc(ido), this % znuc(ido), this % charge(ido)
671 end do
672
673 write (stdout, "(/,' Nuclear data X Y Z Charge',/,(3x,a8,2x,4F10.6))") &
674 (this % cname(i), this % xnuc(i), this % ynuc(i), this % znuc(i), this % charge(i), i = 1, this % nnuc)
675
676 end subroutine write_geometries_sweden
677
678
679 subroutine destroy_integral_sweden (this)
680 class(swedenintegral) :: this
681
682 !if(allocated(this%one_electron_integral)) then
683 !deallocate(this%one_electron_integral)
684 !endif
685
686 call mpi_memory_deallocate_real(this % one_electron_integral, &
687 size(this % one_electron_integral), this % one_electron_window)
688 call mpi_memory_deallocate_real(this % two_electron_integral, &
689 size(this % two_electron_integral), this % two_electron_window)
690
691 !if(allocated(this%two_electron_integral)) then
692 !deallocate(this%two_electron_integral)
693 !endif
694
695 if (allocated(this % pair_labels)) then
696 call master_memory % free_memory(storage_size(this % pair_labels)/8, size(this % pair_labels))
697 deallocate(this % pair_labels)
698 end if
699
700 !> The number of labels per symmetry
701 if (allocated(this % num_orbitals_sym)) then
702 call master_memory % free_memory(storage_size(this % num_orbitals_sym)/8, size(this % num_orbitals_sym))
703 deallocate(this % num_orbitals_sym)
704 end if
705
706 if (allocated(this % one_electron_pointer)) then
707 call master_memory % free_memory(storage_size(this % one_electron_pointer)/8, size(this % one_electron_pointer))
708 deallocate(this % one_electron_pointer)
709 end if
710
711 if (allocated(this % two_electron_pointer)) then
712 call master_memory % free_memory(storage_size(this % two_electron_pointer)/8, size(this % two_electron_pointer))
713 deallocate(this % two_electron_pointer)
714 end if
715
716 if (allocated(this % pair_idx)) then
717 call master_memory % free_memory(storage_size(this % pair_idx)/8, size(this % pair_idx))
718 deallocate(this % pair_idx)
719 end if
720
721 if (allocated(this%orbital_idx)) then
722 call master_memory % free_memory(storage_size(this % orbital_idx)/8, size(this % orbital_idx))
723 deallocate(this %orbital_idx)
724 end if
725
726 if (allocated(this % symmetry_idx)) then
727 call master_memory % free_memory(storage_size(this % symmetry_idx)/8, size(this % symmetry_idx))
728 deallocate(this % symmetry_idx)
729 end if
730
731 end subroutine destroy_integral_sweden
732
733end module sweden_module
MPI SCATCI Constants module.
integer, parameter nidx
Number of long integers used to store up to 8 (packed) integral indices.