LCOV - code coverage report
Current view: top level - src - qs_active_space_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:123285f) Lines: 92.3 % 117 108
Test Date: 2026-11-04 00:58:17 Functions: 66.7 % 9 6

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief The types needed for the calculation of active space Hamiltonians
      10              : !> \par History
      11              : !>      04.2016 created [JGH]
      12              : !> \author JGH
      13              : ! **************************************************************************************************
      14              : MODULE qs_active_space_types
      15              :    USE cp_dbcsr_api,                    ONLY: dbcsr_csr_destroy,&
      16              :                                               dbcsr_csr_p_type,&
      17              :                                               dbcsr_p_type
      18              :    USE cp_dbcsr_operations,             ONLY: dbcsr_deallocate_matrix_set
      19              :    USE cp_fm_types,                     ONLY: cp_fm_release,&
      20              :                                               cp_fm_type
      21              :    USE input_section_types,             ONLY: section_vals_type
      22              :    USE kinds,                           ONLY: default_path_length,&
      23              :                                               dp
      24              :    USE message_passing,                 ONLY: mp_comm_null,&
      25              :                                               mp_comm_type,&
      26              :                                               mp_para_env_release,&
      27              :                                               mp_para_env_type
      28              :    USE qs_density_mixing_types,         ONLY: direct_mixing_nr,&
      29              :                                               mixing_storage_release,&
      30              :                                               mixing_storage_type
      31              :    USE qs_mo_types,                     ONLY: deallocate_mo_set,&
      32              :                                               mo_set_type
      33              : #include "./base/base_uses.f90"
      34              : 
      35              :    IMPLICIT NONE
      36              :    PRIVATE
      37              : 
      38              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_active_space_types'
      39              : 
      40              :    PUBLIC :: active_space_type, eri_type, eri_type_eri_element_func
      41              :    PUBLIC :: create_active_space_type, release_active_space_type
      42              :    PUBLIC :: csr_idx_to_combined, csr_idx_from_combined
      43              : 
      44              : ! **************************************************************************************************
      45              : !> \brief Quantities needed for AS determination
      46              : !> \author JGH
      47              : ! **************************************************************************************************
      48              :    TYPE eri_gpw_type
      49              :       LOGICAL                       :: redo_poisson = .FALSE.
      50              :       LOGICAL                       :: store_wfn = .FALSE.
      51              :       REAL(KIND=dp)                 :: cutoff = 0.0_dp
      52              :       REAL(KIND=dp)                 :: rel_cutoff = 0.0_dp
      53              :       REAL(KIND=dp)                 :: eps_grid = 0.0_dp
      54              :       REAL(KIND=dp)                 :: eps_filter = 0.0_dp
      55              :       INTEGER                       :: print_level = 0
      56              :       INTEGER                       :: group_size = 0
      57              :    END TYPE eri_gpw_type
      58              : 
      59              :    TYPE eri_type
      60              :       INTEGER                       :: method = 0
      61              :       INTEGER                       :: operator = 0
      62              :       LOGICAL                       :: enlarge_cell = .FALSE.
      63              :       REAL(KIND=dp)                 :: omega = 0.0_dp
      64              :       INTEGER, DIMENSION(3)         :: periodicity = 0
      65              :       REAL(KIND=dp), DIMENSION(3)   :: eri_cell = 0
      66              :       REAL(KIND=dp), DIMENSION(3)   :: eri_cell_angles = 0
      67              :       REAL(KIND=dp)                 :: cutoff_radius = 0.0_dp
      68              :       REAL(KIND=dp)                 :: eps_integral = 0.0_dp
      69              :       TYPE(eri_gpw_type)            :: eri_gpw = eri_gpw_type()
      70              :       TYPE(dbcsr_csr_p_type), &
      71              :          DIMENSION(:), POINTER      :: eri => NULL()
      72              :       INTEGER                       :: norb = 0
      73              :       TYPE(mp_para_env_type), POINTER :: para_env_sub => NULL()
      74              :       TYPE(mp_comm_type) :: comm_exchange = mp_comm_null
      75              :    CONTAINS
      76              :       PROCEDURE :: eri_foreach => eri_type_eri_foreach
      77              :    END TYPE eri_type
      78              : 
      79              : ! **************************************************************************************************
      80              : !> \brief Abstract function object for the `eri_type_eri_foreach` method
      81              : ! **************************************************************************************************
      82              :    TYPE, ABSTRACT :: eri_type_eri_element_func
      83              :    CONTAINS
      84              :       PROCEDURE(eri_type_eri_element_func_interface), DEFERRED :: func
      85              :    END TYPE eri_type_eri_element_func
      86              : 
      87              :    TYPE active_space_type
      88              :       INTEGER                                      :: nelec_active = 0
      89              :       INTEGER                                      :: nelec_inactive = 0
      90              :       INTEGER                                      :: nelec_total = 0
      91              :       INTEGER, POINTER, DIMENSION(:, :)            :: active_orbitals => NULL()
      92              :       INTEGER, POINTER, DIMENSION(:, :)            :: inactive_orbitals => NULL()
      93              :       INTEGER                                      :: nmo_active = 0
      94              :       INTEGER                                      :: nmo_inactive = 0
      95              :       INTEGER                                      :: multiplicity = 0
      96              :       INTEGER                                      :: nspins = 0
      97              :       LOGICAL                                      :: restricted_orbitals = .FALSE.
      98              :       LOGICAL                                      :: molecule = .FALSE.
      99              :       INTEGER                                      :: model = 0
     100              :       REAL(KIND=dp)                                :: energy_total = 0.0_dp
     101              :       REAL(KIND=dp)                                :: energy_ref = 0.0_dp
     102              :       REAL(KIND=dp)                                :: energy_inactive = 0.0_dp
     103              :       REAL(KIND=dp)                                :: energy_active = 0.0_dp
     104              :       REAL(KIND=dp)                                :: eps_fci = 0.0_dp
     105              :       REAL(KIND=dp)                                :: alpha = 0.0_dp
     106              :       INTEGER                                      :: as_mixing_method = direct_mixing_nr
     107              :       INTEGER                                      :: as_mixing_iter = 0
     108              :       INTEGER                                      :: as_mixing_dim = 0
     109              :       LOGICAL                                      :: do_scf_embedding = .FALSE.
     110              :       LOGICAL                                      :: qcschema = .FALSE.
     111              :       LOGICAL                                      :: fcidump = .FALSE.
     112              :       CHARACTER(LEN=default_path_length)           :: qcschema_filename = ''
     113              :       TYPE(eri_type)                               :: eri = eri_type()
     114              :       REAL(KIND=dp), DIMENSION(:), POINTER         :: as_mix_r_old => NULL()
     115              :       REAL(KIND=dp), DIMENSION(:), POINTER         :: as_mix_weight => NULL()
     116              :       REAL(KIND=dp), DIMENSION(:), POINTER         :: as_mix_x_old => NULL()
     117              :       REAL(KIND=dp), DIMENSION(:, :), POINTER      :: as_mix_r_buffer => NULL()
     118              :       REAL(KIND=dp), DIMENSION(:, :), POINTER      :: as_mix_x_buffer => NULL()
     119              :       TYPE(mixing_storage_type), POINTER           :: as_mixing_store => NULL()
     120              :       TYPE(mo_set_type), DIMENSION(:), POINTER     :: mos_active => NULL()
     121              :       TYPE(mo_set_type), DIMENSION(:), POINTER     :: mos_inactive => NULL()
     122              :       TYPE(cp_fm_type), DIMENSION(:), POINTER      :: p_active => NULL()
     123              :       TYPE(cp_fm_type), DIMENSION(:), POINTER      :: ks_sub => NULL()
     124              :       TYPE(cp_fm_type), DIMENSION(:), POINTER      :: vxc_sub => NULL()
     125              :       TYPE(cp_fm_type), DIMENSION(:), POINTER      :: h_sub => NULL()
     126              :       TYPE(cp_fm_type), DIMENSION(:), POINTER      :: fock_sub => NULL()
     127              :       TYPE(cp_fm_type), DIMENSION(:), POINTER      :: sab_sub => NULL()
     128              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER    :: pmat_inactive => NULL()
     129              :       TYPE(section_vals_type), POINTER             :: xc_section => NULL()
     130              :    END TYPE active_space_type
     131              : 
     132              :    ABSTRACT INTERFACE
     133              : ! **************************************************************************************************
     134              : !> \brief The function signature to be implemented by a child of `eri_type_eri_element_func`
     135              : !> \param this object reference
     136              : !> \param i i-index
     137              : !> \param j j-index
     138              : !> \param k k-index
     139              : !> \param l l-index
     140              : !> \param val value of the integral at (i,j,k.l)
     141              : !> \return True if the ERI foreach loop should continue, false, if not
     142              : ! **************************************************************************************************
     143              :       LOGICAL FUNCTION eri_type_eri_element_func_interface(this, i, j, k, l, val)
     144              :          IMPORT :: eri_type_eri_element_func, dp
     145              :          CLASS(eri_type_eri_element_func), INTENT(inout) :: this
     146              :          INTEGER, INTENT(in)                             :: i, j, k, l
     147              :          REAL(KIND=dp), INTENT(in)                       :: val
     148              :       END FUNCTION eri_type_eri_element_func_interface
     149              :    END INTERFACE
     150              : 
     151              : ! **************************************************************************************************
     152              : 
     153              : CONTAINS
     154              : 
     155              : ! **************************************************************************************************
     156              : !> \brief Creates an active space environment type, nullifying all quantities.
     157              : !> \param active_space_env the active space environment to be initialized
     158              : ! **************************************************************************************************
     159          108 :    SUBROUTINE create_active_space_type(active_space_env)
     160              :       TYPE(active_space_type), POINTER                   :: active_space_env
     161              : 
     162          108 :       IF (ASSOCIATED(active_space_env)) THEN
     163            0 :          CALL release_active_space_type(active_space_env)
     164              :       END IF
     165              : 
     166         1296 :       ALLOCATE (active_space_env)
     167              :       NULLIFY (active_space_env%active_orbitals, active_space_env%inactive_orbitals)
     168              :       NULLIFY (active_space_env%mos_active, active_space_env%mos_inactive)
     169              :       NULLIFY (active_space_env%ks_sub, active_space_env%p_active)
     170              :       NULLIFY (active_space_env%vxc_sub, active_space_env%h_sub)
     171              :       NULLIFY (active_space_env%fock_sub, active_space_env%pmat_inactive)
     172              :       NULLIFY (active_space_env%as_mixing_store)
     173              :       NULLIFY (active_space_env%as_mix_r_old, active_space_env%as_mix_weight)
     174              :       NULLIFY (active_space_env%as_mix_x_old)
     175              :       NULLIFY (active_space_env%as_mix_r_buffer, active_space_env%as_mix_x_buffer)
     176              : 
     177          108 :    END SUBROUTINE create_active_space_type
     178              : 
     179              : ! **************************************************************************************************
     180              : !> \brief Releases all quantities in the active space environment.
     181              : !> \param active_space_env the active space environment to be released
     182              : ! **************************************************************************************************
     183          108 :    SUBROUTINE release_active_space_type(active_space_env)
     184              :       TYPE(active_space_type), POINTER                   :: active_space_env
     185              : 
     186              :       INTEGER                                            :: imo
     187              : 
     188          108 :       IF (ASSOCIATED(active_space_env)) THEN
     189              : 
     190          108 :          IF (ASSOCIATED(active_space_env%active_orbitals)) THEN
     191          108 :             DEALLOCATE (active_space_env%active_orbitals)
     192              :          END IF
     193              : 
     194          108 :          IF (ASSOCIATED(active_space_env%inactive_orbitals)) THEN
     195          108 :             DEALLOCATE (active_space_env%inactive_orbitals)
     196              :          END IF
     197              : 
     198          108 :          IF (ASSOCIATED(active_space_env%mos_active)) THEN
     199          234 :             DO imo = 1, SIZE(active_space_env%mos_active)
     200          234 :                CALL deallocate_mo_set(active_space_env%mos_active(imo))
     201              :             END DO
     202          108 :             DEALLOCATE (active_space_env%mos_active)
     203              :          END IF
     204              : 
     205          108 :          IF (ASSOCIATED(active_space_env%mos_inactive)) THEN
     206          234 :             DO imo = 1, SIZE(active_space_env%mos_inactive)
     207          234 :                CALL deallocate_mo_set(active_space_env%mos_inactive(imo))
     208              :             END DO
     209          108 :             DEALLOCATE (active_space_env%mos_inactive)
     210              :          END IF
     211              : 
     212          108 :          CALL release_eri_type(active_space_env%eri)
     213              : 
     214          108 :          CALL cp_fm_release(active_space_env%p_active)
     215          108 :          CALL cp_fm_release(active_space_env%ks_sub)
     216          108 :          CALL cp_fm_release(active_space_env%vxc_sub)
     217          108 :          CALL cp_fm_release(active_space_env%h_sub)
     218          108 :          CALL cp_fm_release(active_space_env%fock_sub)
     219          108 :          CALL cp_fm_release(active_space_env%sab_sub)
     220              : 
     221          108 :          IF (ASSOCIATED(active_space_env%as_mixing_store)) THEN
     222          108 :             CALL mixing_storage_release(active_space_env%as_mixing_store)
     223          108 :             DEALLOCATE (active_space_env%as_mixing_store)
     224              :          END IF
     225          108 :          IF (ASSOCIATED(active_space_env%as_mix_r_old)) THEN
     226            0 :             DEALLOCATE (active_space_env%as_mix_r_old)
     227              :          END IF
     228          108 :          IF (ASSOCIATED(active_space_env%as_mix_weight)) THEN
     229            0 :             DEALLOCATE (active_space_env%as_mix_weight)
     230              :          END IF
     231          108 :          IF (ASSOCIATED(active_space_env%as_mix_x_old)) THEN
     232            0 :             DEALLOCATE (active_space_env%as_mix_x_old)
     233              :          END IF
     234          108 :          IF (ASSOCIATED(active_space_env%as_mix_r_buffer)) THEN
     235            0 :             DEALLOCATE (active_space_env%as_mix_r_buffer)
     236              :          END IF
     237          108 :          IF (ASSOCIATED(active_space_env%as_mix_x_buffer)) THEN
     238            0 :             DEALLOCATE (active_space_env%as_mix_x_buffer)
     239              :          END IF
     240              : 
     241          108 :          IF (ASSOCIATED(active_space_env%pmat_inactive)) THEN
     242          108 :             CALL dbcsr_deallocate_matrix_set(active_space_env%pmat_inactive)
     243              :          END IF
     244              : 
     245          108 :          DEALLOCATE (active_space_env)
     246              :       END IF
     247              : 
     248          108 :    END SUBROUTINE release_active_space_type
     249              : 
     250              : ! **************************************************************************************************
     251              : !> \brief Releases the ERI environment type.
     252              : !> \param eri_env the ERI environment to be released
     253              : ! **************************************************************************************************
     254          108 :    SUBROUTINE release_eri_type(eri_env)
     255              :       TYPE(eri_type)                                     :: eri_env
     256              : 
     257              :       INTEGER                                            :: i
     258              : 
     259          108 :       IF (ASSOCIATED(eri_env%eri)) THEN
     260              : 
     261          244 :          DO i = 1, SIZE(eri_env%eri)
     262          136 :             CALL dbcsr_csr_destroy(eri_env%eri(i)%csr_mat)
     263          244 :             DEALLOCATE (eri_env%eri(i)%csr_mat)
     264              :          END DO
     265          108 :          CALL mp_para_env_release(eri_env%para_env_sub)
     266          108 :          CALL eri_env%comm_exchange%free()
     267          108 :          DEALLOCATE (eri_env%eri)
     268              : 
     269              :       END IF
     270              : 
     271          108 :    END SUBROUTINE release_eri_type
     272              : 
     273              : ! **************************************************************************************************
     274              : !> \brief calculates combined index (ij)
     275              : !> \param i Index j
     276              : !> \param j Index i
     277              : !> \param n Dimension in i or j direction
     278              : !> \returns The combined index
     279              : !> \par History
     280              : !>      04.2016 created [JGH]
     281              : ! **************************************************************************************************
     282        10513 :    INTEGER FUNCTION csr_idx_to_combined(i, j, n) RESULT(ij)
     283              :       INTEGER, INTENT(IN)                                :: i, j, n
     284              : 
     285        10513 :       CPASSERT(i <= j)
     286        10513 :       CPASSERT(i <= n)
     287        10513 :       CPASSERT(j <= n)
     288              : 
     289        10513 :       ij = (i - 1)*n - ((i - 1)*(i - 2))/2 + (j - i + 1)
     290              : 
     291        10513 :       CPASSERT(ij <= (n*(n + 1))/2 .AND. 0 <= ij)
     292              : 
     293        10513 :    END FUNCTION csr_idx_to_combined
     294              : 
     295              : ! **************************************************************************************************
     296              : !> \brief extracts indices i and j from combined index ij
     297              : !> \param ij The combined index
     298              : !> \param n Dimension in i or j direction
     299              : !> \param i Resulting i index
     300              : !> \param j Resulting j index
     301              : !> \par History
     302              : !>      04.2016 created [JGH]
     303              : ! **************************************************************************************************
     304        16075 :    SUBROUTINE csr_idx_from_combined(ij, n, i, j)
     305              :       INTEGER, INTENT(IN)                                :: ij, n
     306              :       INTEGER, INTENT(OUT)                               :: i, j
     307              : 
     308              :       INTEGER                                            :: m, m0
     309              : 
     310        16075 :       m = MAX(ij/n, 1)
     311        43298 :       DO i = m, n
     312        43298 :          m0 = (i - 1)*n - ((i - 1)*(i - 2))/2
     313        43298 :          j = ij - m0 + i - 1
     314        43298 :          IF (j <= n) EXIT
     315              :       END DO
     316              : 
     317        16075 :       CPASSERT(i > 0 .AND. i <= n)
     318        16075 :       CPASSERT(j > 0 .AND. j <= n)
     319        16075 :       CPASSERT(i <= j)
     320              : 
     321        16075 :    END SUBROUTINE csr_idx_from_combined
     322              : 
     323              : ! **************************************************************************************************
     324              : !> \brief Calls the provided function for each element in the ERI
     325              : !> \param this object reference
     326              : !> \param nspin The spin number
     327              : !> \param active_orbitals the active orbital indices
     328              : !> \param fobj The function object from which to call `func(i, j, k, l, val)`
     329              : !> \param spin1 the first spin value
     330              : !> \param spin2 the second spin value
     331              : !> \par History
     332              : !>      04.2016 created [JHU]
     333              : !>      06.2016 factored out from qs_a_s_methods:fcidump [TMU]
     334              : !> \note Calls MPI, must be executed on all ranks.
     335              : ! **************************************************************************************************
     336          256 :    SUBROUTINE eri_type_eri_foreach(this, nspin, active_orbitals, fobj, spin1, spin2)
     337              :       CLASS(eri_type), INTENT(in)              :: this
     338              :       CLASS(eri_type_eri_element_func)         :: fobj
     339              :       INTEGER, DIMENSION(:, :), INTENT(IN)     :: active_orbitals
     340              :       INTEGER, OPTIONAL                        :: spin1, spin2
     341              : 
     342              :       CHARACTER(LEN=*), PARAMETER :: routineN = "eri_type_eri_foreach"
     343              : 
     344              :       INTEGER                                  :: i1, i12, i12l, i2, i3, i34, i34l, i4, m1, m2, m3, m4, &
     345              :                                                   irptr, nspin, nindex, nmo, proc, nonzero_elements_local, handle, dummy_int(1)
     346          256 :       INTEGER, ALLOCATABLE, DIMENSION(:)       :: colind, offsets, nonzero_elements_global
     347          256 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: erival
     348              :       REAL(KIND=dp)                            :: erint, dummy_real(1)
     349              :       TYPE(mp_comm_type) :: mp_group
     350              : 
     351          256 :       CALL timeset(routineN, handle)
     352              : 
     353          256 :       IF (.NOT. PRESENT(spin1)) THEN
     354            0 :          spin1 = nspin
     355              :       END IF
     356          256 :       IF (.NOT. PRESENT(spin2)) THEN
     357            0 :          spin2 = nspin
     358              :       END IF
     359              : 
     360          256 :       dummy_int = 0
     361          256 :       dummy_real = 0.0_dp
     362              : 
     363              :       ASSOCIATE (eri => this%eri(nspin)%csr_mat, norb => this%norb)
     364          256 :          nindex = (norb*(norb + 1))/2
     365          256 :          CALL mp_group%set_handle(eri%mp_group%get_handle())
     366          256 :          nmo = SIZE(active_orbitals, 1)
     367              :          ! Irrelevant in case of half-transformed integrals
     368         1280 :          ALLOCATE (erival(nindex), colind(nindex))
     369              :          ALLOCATE (offsets(0:mp_group%num_pe - 1), &
     370         1024 :                    nonzero_elements_global(0:mp_group%num_pe - 1))
     371              : 
     372         1256 :          DO m1 = 1, nmo
     373          744 :             i1 = active_orbitals(m1, spin1)
     374         2680 :             DO m2 = m1, nmo
     375         1680 :                i2 = active_orbitals(m2, spin1)
     376         1680 :                i12 = csr_idx_to_combined(i1, i2, norb)
     377         1680 :                i12l = (i12 - 1)/this%comm_exchange%num_pe + 1
     378              : 
     379              :                ! In case of half-transformed integrals, every process might carry integrals of a row
     380              :                ! The number of integrals varies between processes and rows (related to the randomized
     381              :                ! distribution of matrix blocks)
     382              : 
     383              :                ! 1) Collect the amount of local data from each process
     384         1680 :                nonzero_elements_local = 0
     385         1680 :                IF (MOD(i12 - 1, this%comm_exchange%num_pe) == this%comm_exchange%mepos) THEN
     386         1662 :                   nonzero_elements_local = eri%nzerow_local(i12l)
     387              :                END IF
     388         1680 :                CALL mp_group%allgather(nonzero_elements_local, nonzero_elements_global)
     389              : 
     390              :                ! 2) Prepare arrays for communication (calculate the offsets and the total number of elements)
     391         1680 :                offsets(0) = 0
     392         3360 :                DO proc = 1, mp_group%num_pe - 1
     393         3360 :                   offsets(proc) = offsets(proc - 1) + nonzero_elements_global(proc - 1)
     394              :                END DO
     395         1680 :                nindex = offsets(mp_group%num_pe - 1) + nonzero_elements_global(mp_group%num_pe - 1)
     396         1680 :                irptr = 1
     397         1680 :                IF (MOD(i12 - 1, this%comm_exchange%num_pe) == this%comm_exchange%mepos) THEN
     398         1662 :                   irptr = eri%rowptr_local(i12l)
     399              : 
     400              :                   ! Exchange actual data
     401              :                   CALL mp_group%allgatherv(eri%colind_local(irptr:irptr + nonzero_elements_local - 1), &
     402         6454 :                                            colind(1:nindex), nonzero_elements_global, offsets)
     403              :                   CALL mp_group%allgatherv(eri%nzval_local%r_dp(irptr:irptr + nonzero_elements_local - 1), &
     404         6454 :                                            erival(1:nindex), nonzero_elements_global, offsets)
     405              :                ELSE
     406           18 :                   CALL mp_group%allgatherv(dummy_int(1:0), colind(1:nindex), nonzero_elements_global, offsets)
     407           18 :                   CALL mp_group%allgatherv(dummy_real(1:0), erival(1:nindex), nonzero_elements_global, offsets)
     408              :                END IF
     409              : 
     410        12008 :                DO i34l = 1, nindex
     411         9584 :                   i34 = colind(i34l)
     412         9584 :                   erint = erival(i34l)
     413         9584 :                   CALL csr_idx_from_combined(i34, norb, i3, i4)
     414              : 
     415        29180 :                   DO m3 = 1, nmo
     416        29180 :                      IF (active_orbitals(m3, spin2) == i3) THEN
     417              :                         EXIT
     418              :                      END IF
     419              :                   END DO
     420              : 
     421        40256 :                   DO m4 = 1, nmo
     422        40256 :                      IF (active_orbitals(m4, spin2) == i4) THEN
     423              :                         EXIT
     424              :                      END IF
     425              :                   END DO
     426              : 
     427              :                   ! terminate the loop prematurely if the function returns false
     428        20848 :                   IF (.NOT. fobj%func(m1, m2, m3, m4, erint)) RETURN
     429              :                END DO
     430              : 
     431              :             END DO
     432              :          END DO
     433              :       END ASSOCIATE
     434              : 
     435          256 :       CALL timestop(handle)
     436          512 :    END SUBROUTINE eri_type_eri_foreach
     437              : 
     438            0 : END MODULE qs_active_space_types
        

Generated by: LCOV version 2.0-1