35     use integer_packing,        
only: unpack8ints
 
   36     use precisn,                
only: longint, wp
 
   64         integer  :: diagonal_flag
 
   65         integer  :: positron_flag
 
   67         logical  :: constructed = .false.   
 
   68         logical  :: initialized = .false.   
 
   70         integer  :: number_of_integrals = 0
 
   71         real(wp) :: element_one = 0.0
 
  105             class(
basematrix), 
intent(inout) :: matrix_elements
 
  123         class(
options),      
target, 
intent(in)    :: option
 
  124         class(
csfobject),    
target, 
intent(in)    :: csfs(:)
 
  129         this % options  => option
 
  131         this % orbitals => orbitals
 
  132         this % integral => integral
 
  133         this % phase_flag = this % options % phase_correction_flag
 
  134         this % positron_flag = this % options % positron_flag
 
  137         this % diagonal_flag = min(this % options % matrix_eval, 2)
 
  138         this % constructed = .true.
 
  161         class(
csfobject),             
intent(in)    :: csf_a, csf_b
 
  163         integer,           
intent(in)  :: flag
 
  164         logical, 
optional, 
intent(in)  :: job_
 
  166         integer  :: diag, num_differences, dtr_diff(4), dtr_diff_fast(4), dtr_idx_a, dtr_idx_b
 
  170         if (
present(job_)) 
then 
  177         call sym_elements % clear()
 
  182             if (.not. this % my_job()) 
return 
  186         if (csf_a % id /= csf_b % id) 
then 
  188             if (csf_a % check_slater(csf_b) > 4) 
return 
  193         do dtr_idx_a = 1, csf_a % num_orbitals
 
  195             do dtr_idx_b = 1, csf_b % num_orbitals
 
  198                 call csf_a % orbital(dtr_idx_a) % compare_excitations_fast(csf_b % orbital(dtr_idx_b), &
 
  199                                                                            this % options % num_electrons, &
 
  205                 select case (num_differences)
 
  209                         call this % handle_two_pair(dtr_diff, coeff, sym_elements, flag)
 
  211                         call this % handle_one_pair(dtr_diff, coeff, sym_elements, csf_a % orbital(dtr_idx_a), flag)
 
  213                         call this % handle_same(dtr_diff, coeff, sym_elements, csf_a % orbital(dtr_idx_a), flag)
 
  235         integer,  
intent(in)         ::    dtrs(4)
 
  236         real(wp), 
intent(in)         ::    coeff
 
  237         integer,  
intent(in)         :: flag
 
  239         if (this % diagonal_flag> 1 .and. this % orbitals % get_minimum_mcon(dtrs) > 0) 
return 
  242         call this % orbitals % evaluate_IJKL_and_coeffs(dtrs, coeff, 0, sym_element, flag)
 
  262         integer,           
intent(inout) :: dtrs(4)
 
  263         real(wp),          
intent(in)    :: coeff
 
  264         integer,           
intent(in)    :: flag
 
  268         integer :: ref_dtrs(this % options % num_electrons)
 
  269         integer :: num_electrons, N, M, ido, ia1, ia2, lnadd
 
  276         num_electrons = this % options % num_electrons
 
  288         call csf % get_determinants(ref_dtrs, num_electrons)
 
  291         if (this % diagonal_flag > 1 .and. this % orbitals % get_two_minimum_mcon(dtrs(3), dtrs(4)) > 0) 
then 
  298         do ido = 1, num_electrons
 
  300             if (ref_dtrs(ido) == dtrs(3)) cycle
 
  302             if (nchk == 1 .and. this % orbitals % get_mcon(ref_dtrs(ido)) > 0) cycle
 
  304             dtrs(1) = ref_dtrs(ido)
 
  305             dtrs(2) = ref_dtrs(ido)
 
  307             call this % orbitals % evaluate_IJKL_and_coeffs(dtrs, coeff, 0, sym_element, flag)
 
  311         if (this % positron_flag /= 0) lnadd = this % orbitals % add_positron(dtrs, 3, 4)
 
  312         if (nchk == 1) 
return 
  315         so1 = this % orbitals % spin_orbitals(dtrs(3))
 
  316         so2 = this % orbitals % spin_orbitals(dtrs(4))
 
  319         if (so1 % m_quanta /= so2 % m_quanta .or. so1 % spin /= so2 % spin) 
return 
  320         if (so1 % orbital_number < so2 % orbital_number) 
then 
  321             ia1 = so2 % orbital_number
 
  322             ia2 = so1 % orbital_number
 
  324             ia1 = so1 % orbital_number
 
  325             ia2 = so2 % orbital_number
 
  329         call sym_element % insert_ijklm_symbol(0, ia1, 0, ia2, lnadd, coeff)
 
  345     subroutine handle_same (this, dtrs, coeff, sym_element, csf, flag)
 
  349         integer,           
intent(inout) :: dtrs(4)
 
  350         real(wp),          
intent(in)    :: coeff
 
  351         integer,           
intent(in)    :: flag
 
  355         integer :: ref_dtrs(this % options % num_electrons)
 
  356         integer :: num_electrons, N, M, ido, jdo, ia1, ia2, lnadd
 
  363         num_electrons = this % options % num_electrons
 
  375         call csf % get_determinants(ref_dtrs, num_electrons)
 
  377         do ido = 2, num_electrons
 
  378             dtrs(1) = ref_dtrs(ido)
 
  381                 dtrs(3) = ref_dtrs(jdo)
 
  383                 if (this % diagonal_flag > 1 .and. this % orbitals % get_two_minimum_mcon(dtrs(1), dtrs(3)) > 0) cycle
 
  385                 call this % orbitals % evaluate_IJKL_and_coeffs(dtrs, coeff, 0, sym_element, flag)
 
  389         if (this % NFLG /= 0) this % NFLG = 2
 
  390         do ido = 1, num_electrons
 
  392             if (this % diagonal_flag > 1 .and. this % orbitals%get_mcon(n) /= 0) cycle
 
  394             m = this % orbitals % get_orbital_number(n)
 
  395             if (this % positron_flag /= 0) lnadd = this % orbitals % add_positron(dtrs, 1, 2)
 
  396             call sym_element % insert_ijklm_symbol(0, m, 0, m, lnadd, coeff)
 
  415         integer,                
intent(in)    :: dummy_orb
 
  416         real(wp),               
intent(in)    :: coeff
 
  417         integer(longint),       
intent(in)    :: label(2)
 
  419         integer :: ido, jdo, num_elements, lwd(8)
 
  423         if (coeff == 0.0_wp) 
return 
  426         if (this % phase_flag > 0) 
then 
  427             call unpack8ints(label, lwd)
 
  429                 if (lwd(jdo) == this % phase_flag) 
return 
  431         else if (this % phase_flag == 0) 
then 
  432             call unpack8ints(label, lwd)
 
  434                 if (lwd(jdo) <= 0) cycle
 
  435                 if (this % orbitals % mcorb(lwd(jdo)) == 0) 
return 
  442         this % number_of_integrals = this % number_of_integrals + 1
 
  459         class(symbolicelementvector), 
intent(in)    :: symbolic_elements
 
  460         integer,                      
intent(in)    :: dummy_orb
 
  462         integer          :: ido, num_elements
 
  463         integer(longint) :: label(2)
 
  466         num_elements = symbolic_elements % get_size()
 
  469         if (num_elements == 0) 
return 
  470         do ido = 1, num_elements
 
  471             call symbolic_elements % get_coeff_and_integral(ido, coeff, label)
 
  484         if (grid % gprocs == 1 .or. grid % grank == -1) 
return 
  486         if (this % job_id /= grid % grank) 
then 
  490         this % job_id = this % job_id + 1
 
  491         if (this % job_id == grid % gprocs) 
then 
  504     integer function fast_slat (rep1, rep2, fin1, fin2, num_rep1, num_rep2, spin_orbs, tot_num_spin_orbs)
 
  505         integer, 
intent(in)    :: num_rep1, rep1(num_rep1), fin1(num_rep1)
 
  506         integer, 
intent(in)    :: num_rep2, rep2(num_rep2), fin2(num_rep2), tot_num_spin_orbs
 
  507         integer, 
intent(inout) :: spin_orbs(tot_num_spin_orbs)
 
  511         integer :: i_spin_orbital
 
  513         integer :: orb_remove
 
  515         do i_dtrs = 1, num_rep1
 
  516             orb_remove = (rep1(i_dtrs) + 1) / 2
 
  517             orb_add = (fin1(i_dtrs) + 1) / 2
 
  518             spin_orbs(orb_remove) = spin_orbs(orb_remove) - 1
 
  519             spin_orbs(orb_add) = spin_orbs(orb_add) + 1
 
  522         do i_dtrs = 1, num_rep2
 
  523             orb_remove = (rep2(i_dtrs) + 1) / 2
 
  524             orb_add = (fin2(i_dtrs) + 1) / 2
 
  525             spin_orbs(orb_remove) = spin_orbs(orb_remove) + 1
 
  526             spin_orbs(orb_add) = spin_orbs(orb_add) - 1
 
  531         do i_dtrs = 1, num_rep1
 
  532             orb_remove = (rep1(i_dtrs) + 1) / 2
 
  533             orb_add = (fin1(i_dtrs) + 1) / 2
 
  535             spin_orbs(orb_remove) = 0
 
  537             spin_orbs(orb_add) = 0
 
  540         do i_dtrs = 1, num_rep2
 
  541             orb_remove = (rep2(i_dtrs) + 1) / 2
 
  542             orb_add = (fin2(i_dtrs) + 1) / 2
 
  544             spin_orbs(orb_remove) = 0
 
  546             spin_orbs(orb_add) = 0