36 use const_gbl,
only: stdout
37 use mpi_memory_gbl,
only: mpi_memory_allocate_integer_2dim, mpi_memory_allocate_real, mpi_memory_synchronize, &
38 mpi_memory_deallocate_integer_2dim, mpi_memory_deallocate_real, local_master
39 use mpi_gbl,
only: mpi_mod_barrier, shared_enabled
40 use precisn,
only: longint, wp
41 use scatci_routines,
only: rdnfto, rdwf, setposwf
65 integer(longint),
pointer :: int64dtrs(:,:)
66 real(wp),
pointer :: coeffdtrs(:)
68 integer(longint),
allocatable :: int64dtrs(:,:)
69 real(wp),
allocatable :: coeffdtrs(:)
72 integer :: int64_win = -1
73 integer :: coeffs_win = -1
77 integer :: length_coeff
78 integer :: length_dtrs
79 integer,
pointer :: num_dtr_csf_out(:)
82 integer,
allocatable :: index_dtrs(:)
83 integer,
allocatable :: index_coeffs(:)
84 integer,
allocatable :: packed_dtrs(:)
85 real(wp),
allocatable :: coeffs(:)
88 integer :: largest_num_configs
93 integer :: num_electrons
96 integer,
allocatable :: orbitals(:)
97 integer,
allocatable :: spin(:)
98 integer,
allocatable :: reference_dtrs(:)
99 integer(longint),
allocatable :: ref_int64dtrs(:)
138 integer :: num_orbitals
140 integer :: orbital_sequence_number
141 logical :: is_continuum
142 integer :: target_symmetry
143 integer :: continuum_symmetry
144 integer :: continuum_orbital_idx
145 integer :: target_configuration
163 class(
options),
intent(in) :: option
166 integer :: ido, ifail, size_mem
169 this % num_csfs = option % num_csfs
170 this % length_dtrs = option % length_dtrs
171 this % length_coeff = option % length_coeff
172 this % megul = option % megul
174 allocate(this % num_dtr_csf_out(this % num_csfs), stat = ifail)
176 call master_memory % track_memory(kind(this % num_dtr_csf_out), &
177 size(this % num_dtr_csf_out), ifail,
'CSFMANAGER::num_dtr_csr_out')
179 this % num_dtr_csf_out = option % num_dtr_csf_out
180 this % num_electrons = option % num_electrons
182 this % num_MO = orbital % total_num_orbitals
183 this % num_SO = orbital % total_num_spin_orbitals
185 allocate(this % orbitals(this % num_SO), &
186 this % reference_dtrs(this % num_electrons), &
187 this % spin(this % num_SO), stat = ifail)
190 size(this % orbitals), ifail,
'CSFMANAGER::orbitals')
191 call master_memory % track_memory(kind(this % reference_dtrs), &
192 size(this % reference_dtrs), ifail,
'CSFMANAGER::reference_dtrs')
194 size(this % spin), ifail,
'CSFMANAGER::spin')
196 do ido = 1, this % num_SO
197 this % orbitals(ido) = orbital % get_orbital_number(ido)
198 this % spin(ido) = orbital % get_spin(ido)
201 this % reference_dtrs(:) = option % reference_dtrs(:)
202 this % Nints = this % num_SO / 64 + 1
204 allocate(this % ref_int64dtrs(this % Nints), stat = ifail)
206 call master_memory % track_memory(kind(this % ref_int64dtrs), &
207 size(this % ref_int64dtrs), ifail,
'CSFMANAGER::ref_int64dtrs')
209 this % ref_int64dtrs(:) = 0
210 write (stdout,
"('Nints = ',i4)") this % Nints
211 this % pt_orb => orbital
213 do ido = 1, this % num_electrons
214 call this % toggle_determinant(this % reference_dtrs(ido), this % ref_int64dtrs, this % Nints)
217 if ((shared_enabled .and. grid % lrank == local_master) .or. .not. shared_enabled)
then
219 allocate(this % index_dtrs(this % num_csfs + 1), &
220 this % index_coeffs(this % num_csfs + 1), &
221 this % packed_dtrs(this % length_dtrs), &
222 this % coeffs(this % length_coeff), stat = ifail)
225 call setposwf(option % positron_flag, &
226 option % num_continuum, &
227 option % num_target_sym, &
231 call rdwf(this % num_csfs + 1, &
232 this % index_coeffs, &
234 this % packed_dtrs, &
235 this % length_dtrs, &
237 this % length_coeff, &
251 class(
csfmanager),
intent(inout),
target :: this
253 call master_memory % free_memory(kind(this % num_dtr_csf_out),
size(this % num_dtr_csf_out))
254 call master_memory % free_memory(kind(this % orbitals),
size(this % orbitals))
255 call master_memory % free_memory(kind(this % reference_dtrs),
size(this % reference_dtrs))
256 call master_memory % free_memory(kind(this % spin),
size(this % spin))
257 call master_memory % free_memory(kind(this % ref_int64dtrs),
size(this % ref_int64dtrs))
259 if (
associated(this % num_dtr_csf_out))
deallocate (this % num_dtr_csf_out)
260 if (
allocated(this % orbitals))
deallocate (this % orbitals)
261 if (
allocated(this % reference_dtrs))
deallocate (this % reference_dtrs)
262 if (
allocated(this % spin))
deallocate (this % spin)
263 if (
allocated(this % ref_int64dtrs))
deallocate (this % ref_int64dtrs)
265 if (
allocated(this % index_dtrs))
deallocate (this % index_dtrs)
266 if (
allocated(this % index_coeffs))
deallocate (this % index_coeffs)
267 if (
allocated(this % packed_dtrs))
deallocate (this % packed_dtrs)
268 if (
allocated(this % coeffs))
deallocate (this % coeffs)
270 call mpi_memory_deallocate_integer_2dim(this % int64dtrs,
size(this % int64dtrs), this % int64_win, grid % lcomm)
271 call mpi_memory_deallocate_real(this % coeffdtrs,
size(this % coeffdtrs), this % coeffs_win, grid % lcomm)
292 subroutine create_csfs (this, CSF, orbital_sequence, num_ci_target_sym, continuum_projection)
294 class(
csfmanager),
intent(inout),
target :: this
295 type(
csfobject),
intent(inout),
allocatable,
target :: CSF(:)
296 integer,
intent(in) :: num_ci_target_sym(:), continuum_projection(:)
298 integer :: orbital_sequence(this % num_csfs)
299 integer :: csf_det(this % num_electrons)
301 real(wp) :: phase_fold
302 integer :: ido, jdo, kdo, ifail, num_orbs, start_index_dtr, start_index_coeff, num_spin_orb
303 integer :: dtr_size, elec_idx, total_number_orbs, orb_counter, count_number, symmetry_idx
307 this % largest_num_configs = 0
309 write (stdout,
"('Creating our CSFs.........')", advance =
"no")
311 total_number_orbs = 0
313 do ido = 1, this % num_csfs
314 total_number_orbs = total_number_orbs + this % num_dtr_csf_out(ido)
317 write (stdout,
"('Total number of determinants = ',i12)") total_number_orbs
319 allocate(csf(this % num_csfs))
321 this % int64_win = mpi_memory_allocate_integer_2dim(this % int64dtrs, this % Nints, total_number_orbs, grid % lcomm)
322 this % coeffs_win = mpi_memory_allocate_real(this % coeffdtrs, total_number_orbs, grid % lcomm)
324 call mpi_mod_barrier(ifail, grid % gcomm)
325 call mpi_memory_synchronize(this % int64_win, grid % lcomm)
326 call mpi_memory_synchronize(this % coeffs_win, grid % lcomm)
328 do ido = 1, this % num_csfs
329 num_orbs = this % num_dtr_csf_out(ido)
332 csf(ido) % manager => this
333 csf(ido) % num_orbitals = num_orbs
336 csf(ido) % orbital_sequence_number = orbital_sequence(ido)
338 this % largest_num_configs = max(this % largest_num_configs, num_orbs)
340 if (csf(ido) % orbital_sequence_number > 0)
then
342 csf(ido) % is_continuum = .true.
343 csf(ido) % continuum_orbital_idx = mod(ido - 1, 2)
344 csf(ido) % target_symmetry = symmetry_idx
345 csf(ido) % target_configuration = ((count_number - 1) / 2) + 1
346 csf(ido) % continuum_symmetry = continuum_projection(symmetry_idx) + 1
348 count_number = count_number + 1
350 if (count_number > num_ci_target_sym(symmetry_idx) * 2)
then
351 symmetry_idx = symmetry_idx + 1
357 csf(ido) % is_continuum = .false.
361 orb_counter = orb_counter + 1
362 allocate(csf(ido) % orbital(num_orbs), stat = ifail)
364 csf(ido) % orbital(1) % id_dtr = orb_counter
365 csf(ido) % orbital(1) % csf => csf(ido)
367 if ((shared_enabled .and. grid % lrank == local_master) .or. .not. shared_enabled)
then
369 start_index_dtr = this % index_dtrs(ido)
370 start_index_coeff = this % index_coeffs(ido) - 1
371 num_spin_orb = this % packed_dtrs(start_index_dtr)
372 this % int64dtrs(:,orb_counter) = this % ref_int64dtrs(:)
373 csf_det(:) = this % reference_dtrs(:)
375 do kdo = 1, num_spin_orb
376 call this % toggle_determinant(this % packed_dtrs(start_index_dtr + kdo), &
377 this % int64dtrs(:,orb_counter), this % Nints)
378 call this % toggle_determinant(this % packed_dtrs(start_index_dtr + num_spin_orb + kdo), &
379 this % int64dtrs(:,orb_counter), this % Nints)
380 elec_idx = this % pt_orb % get_electron_number(this % packed_dtrs(start_index_dtr + kdo))
381 csf_det(elec_idx) = this % packed_dtrs(start_index_dtr + num_spin_orb + kdo)
386 this % coeffdtrs(orb_counter) = this % coeffs(start_index_coeff + 1) * phase_fold
387 start_index_dtr = start_index_dtr + 2 * num_spin_orb + 1
394 orb_counter = orb_counter + 1
395 csf(ido) % orbital(jdo) % id_dtr = orb_counter
396 csf(ido) % orbital(jdo) % csf => csf(ido)
398 if ((shared_enabled .and. grid % lrank == local_master) .or. .not. shared_enabled)
then
399 num_spin_orb = this % packed_dtrs(start_index_dtr)
400 this % int64dtrs(:,orb_counter) = this % ref_int64dtrs(:)
401 csf_det(:) = this % reference_dtrs(:)
403 do kdo = 1, num_spin_orb
404 call this % toggle_determinant(this % packed_dtrs(start_index_dtr + kdo), &
405 this % int64dtrs(:,orb_counter), this % Nints)
406 call this % toggle_determinant(this % packed_dtrs(start_index_dtr + num_spin_orb + kdo), &
407 this % int64dtrs(:,orb_counter), this % Nints)
408 elec_idx = this % pt_orb % get_electron_number(this % packed_dtrs(start_index_dtr + kdo))
409 csf_det(elec_idx) = this % packed_dtrs(start_index_dtr + num_spin_orb + kdo)
414 this % coeffdtrs(orb_counter) = this % coeffs(start_index_coeff + jdo) * phase_fold
415 start_index_dtr = start_index_dtr + 2 * num_spin_orb + 1
420 write (stdout,
"('success!')")
421 write (stdout,
"('Largest number of configurations in a single CSF is ',i10)") this % largest_num_configs
423 call mpi_mod_barrier(ifail, grid % gcomm)
424 call mpi_memory_synchronize(this % int64_win, grid % lcomm)
425 call mpi_memory_synchronize(this % coeffs_win, grid % lcomm)
429 call master_memory % free_memory(kind(this % num_dtr_csf_out),
size(this % num_dtr_csf_out))
432 if ((shared_enabled .and. grid % lrank == local_master) .or. .not. shared_enabled)
then
433 deallocate(this % index_dtrs, this % index_coeffs, this % packed_dtrs, this % coeffs)
435 deallocate(this % num_dtr_csf_out)
450 do ido = 1, this % num_csfs
451 call csf(ido) % print
465 integer,
intent(in) :: num_electrons
466 integer,
intent(out) :: num_excitations
467 integer,
intent(out) :: output_dtrs(4)
468 real(wp),
intent(out) :: coeff
475 manager => this % csf % manager
479 manager % int64dtrs(:, that % id_dtr), &
480 output_dtrs, num_excitations,
phase, manager % Nints)
482 coeff =
phase * manager % coeffdtrs(this % id_dtr) &
483 * manager % coeffdtrs(that % id_dtr)
489 class(
csfobject),
intent(in) :: this, that
491 integer :: min_num_excitation, ido
493 manager => this % manager
496 manager % int64dtrs(:, that % orbital(1) % id_dtr), &
504 integer,
intent(in) :: Nints
506 integer(longint) :: det1(Nints)
507 integer(longint) :: bit_set
508 integer :: spin_position, array_position, local_orbital
511 array_position = (det0 - 1) / 64 + 1
514 local_orbital = det0 - (array_position - 1) * 64 - 1
515 bit_set = ibset(bit_set, local_orbital)
517 det1(array_position) = ieor(det1(array_position), bit_set)
522 integer function pzero (det1, det2, Nint)
523 integer,
intent(in) :: nint
524 integer(longint),
intent(in) :: det1(nint), det2(nint)
525 integer(longint) :: xor1
526 integer :: l, nexcitations = 0
528 xor1 = ieor(det1(1), det2(1))
532 xor1 = ieor(det1(l), det2(l))
552 integer(longint),
intent(in) :: det
553 integer(longint),
parameter :: mask = int(z
'5555555555555555', longint)
555 get_beta = iand(ishft(det, -1), mask)
568 integer(longint),
intent(in) :: det
569 integer(longint),
parameter :: mask = int(z
'5555555555555555', longint)
577 integer,
intent(in) :: nint
578 integer(longint),
intent(in) :: det1(nint), det2(nint)
594 integer,
intent(in) :: Nint
595 integer(longint),
intent(in) :: det1(Nint,2), det2(Nint,2)
596 integer,
intent(out) :: exc(4)
597 integer,
intent(out) :: degree
598 double precision,
intent(inout) :: phase
619 integer,
intent(in) :: Nint
620 integer(longint),
intent(in) :: det1(Nint)
621 integer(longint),
intent(in) :: det2(Nint)
622 integer,
intent(inout) :: exc(2)
623 double precision,
intent(out) :: phase
625 integer :: tz, l, ispin, ishift, nperm, i, j, k, m, n, high, low
627 integer :: particles(1)
628 integer(longint) :: hole, particle, tmp, masklow, maskhigh
629 double precision,
parameter :: phase_dble(0:1) = (/ 1.d0, -1.d0 /)
636 if (det1(l) == det2(l)) cycle
637 tmp = ieor(det1(l), det2(l))
638 particle = iand(tmp, det2(l))
639 hole = iand(tmp, det1(l))
640 if (particle /= 0_8)
then
641 tz = trailz(particle)
644 if (hole /= 0_8)
then
649 if (exc(1) /= 0 .and. exc(2) /=0 )
then
650 low = min(exc(1), exc(2))
651 high = max(exc(1), exc(2))
652 j = ishft(low - 1, -6) + 1
653 n = iand(low - 1, 63)
654 k = ishft(high - 1, -6) + 1
655 m = iand(high - 1, 63)
659 nperm = nperm + popcnt(iand(det1(j), iand(not(ishft(1_8, n + 1)) + 1, ishft(1_8, m) - 1)))
661 nperm = nperm + popcnt(iand(det1(k), ishft(1_8, m) - 1)) &
662 + popcnt(iand(det1(j), not(ishft(1_8, n + 1)) + 1))
664 nperm = nperm + popcnt(det1(i))
667 phase = phase_dble(iand(nperm, 1))
676 integer,
intent(in) :: Nint
677 integer(longint),
intent(in) :: det1(Nint), det2(Nint)
678 integer,
intent(out) :: exc(4)
679 double precision,
intent(out) :: phase
680 integer :: l, ispin, idx_hole, idx_particle, ishift
681 integer :: i, j, k, m, n, high, low, a, b, c, d, nperm, tz, nexc, num_holes
682 integer(longint) :: hole, particle, tmp, spin_total, masklow, maskhigh
683 integer :: holes(2), particles(2), comp(2)
684 double precision,
parameter :: phase_dble(0:1) = (/ 1.d0, -1.d0 /)
695 if (det1(l) == det2(l)) cycle
696 tmp = ieor(det1(l), det2(l))
697 particle = iand(tmp, det2(l))
698 hole = iand(tmp, det1(l))
699 do while (particle /= 0_8)
700 tz = trailz(particle)
702 idx_particle = idx_particle + 1
704 particles(idx_particle) = tz + ishift
705 particle = iand(particle, particle - 1_8)
707 do while (hole /= 0_8)
710 idx_hole = idx_hole + 1
711 holes(idx_hole) = tz + ishift
712 num_holes = num_holes + 1
714 hole = iand(hole, hole - 1_8)
745 low = min(particles(i), holes(i))
746 high = max(particles(i), holes(i))
747 j = ishft(low - 1, -6) + 1
748 n = iand(low - 1, 63)
749 k = ishft(high - 1, -6) + 1
750 m = iand(high - 1, 63)
753 nperm = nperm + popcnt(iand(det1(j), iand(not(ishft(1_8, n + 1)) + 1, ishft(1_8, m) - 1)))
755 nperm = nperm + popcnt(iand(det1(k), ishft(1_8, m) - 1)) &
756 + popcnt(iand(det1(j), not(ishft(1_8, n + 1)) + 1))
758 nperm = nperm + popcnt(det1(l))
766 if (num_holes == 2)
then
767 a = min(holes(1), particles(1))
768 b = max(holes(1), particles(1))
769 c = min(holes(2), particles(2))
770 d = max(holes(2), particles(2))
771 if (c > a .and. c < b .and. d > b) nperm = nperm + 1
791 exc(2) = particles(1)
793 exc(4) = particles(2)
795 phase = phase_dble(iand(nperm, 1))
801 integer,
intent(in) :: Nints
802 integer(longint),
target,
intent(in) :: targ(Nints)
803 integer(longint),
pointer,
intent(out) :: point(:)
805 point(1:nints) => targ(1:nints)
811 integer,
intent(in) :: nelec
813 integer,
intent(out) :: dtrs(nelec)
814 integer(longint) :: current_so
815 integer :: tz, ishift = -63, ints, idx_dtr, nexec
821 do ints = 1, this % csf % manager % Nints
823 current_so = this % csf % manager % int64dtrs(ints, this % id_dtr)
824 do while (current_so /= 0)
825 tz = trailz(current_so)
826 idx_dtr = idx_dtr + 1
827 dtrs(idx_dtr) = tz + ishift
828 current_so = iand(current_so, current_so - 1)
836 integer,
intent(inout),
dimension(:) :: a
837 real(wp),
intent(inout) ::
phase
840 if (
size(a) > 1)
then
850 integer,
intent(inout) :: A(:)
851 integer,
intent(out) :: marker
852 real(wp),
intent(inout) :: phase