LCOV - code coverage report
Current view: top level - src - rpa_main.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:b8e0b09) Lines: 557 579 96.2 %
Date: 2024-08-31 06:31:37 Functions: 4 4 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Routines to calculate RI-RPA energy
      10             : !> \par History
      11             : !>      06.2012 created [Mauro Del Ben]
      12             : !>      04.2015 GW routines added [Jan Wilhelm]
      13             : !>      10.2015 Cubic-scaling RPA routines added [Jan Wilhelm]
      14             : !>      10.2018 Cubic-scaling SOS-MP2 added [Frederick Stein]
      15             : !>      03.2019 Refactoring [Frederick Stein]
      16             : ! **************************************************************************************************
      17             : MODULE rpa_main
      18             :    USE bibliography,                    ONLY: &
      19             :         Bates2013, DelBen2013, DelBen2015, Freeman1977, Gruneis2009, Ren2011, Ren2013, &
      20             :         Wilhelm2016a, Wilhelm2016b, Wilhelm2017, Wilhelm2018, cite_reference
      21             :    USE bse_main,                        ONLY: start_bse_calculation
      22             :    USE cp_blacs_env,                    ONLY: cp_blacs_env_create,&
      23             :                                               cp_blacs_env_release,&
      24             :                                               cp_blacs_env_type
      25             :    USE cp_cfm_types,                    ONLY: cp_cfm_type
      26             :    USE cp_dbcsr_api,                    ONLY: dbcsr_add,&
      27             :                                               dbcsr_clear,&
      28             :                                               dbcsr_get_info,&
      29             :                                               dbcsr_p_type,&
      30             :                                               dbcsr_type
      31             :    USE cp_fm_basic_linalg,              ONLY: cp_fm_scale_and_add
      32             :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      33             :                                               cp_fm_struct_release,&
      34             :                                               cp_fm_struct_type
      35             :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      36             :                                               cp_fm_release,&
      37             :                                               cp_fm_set_all,&
      38             :                                               cp_fm_to_fm,&
      39             :                                               cp_fm_type
      40             :    USE dbt_api,                         ONLY: dbt_type
      41             :    USE dgemm_counter_types,             ONLY: dgemm_counter_init,&
      42             :                                               dgemm_counter_type,&
      43             :                                               dgemm_counter_write
      44             :    USE group_dist_types,                ONLY: create_group_dist,&
      45             :                                               get_group_dist,&
      46             :                                               group_dist_d1_type,&
      47             :                                               maxsize,&
      48             :                                               release_group_dist
      49             :    USE hfx_types,                       ONLY: block_ind_type,&
      50             :                                               hfx_compression_type
      51             :    USE input_constants,                 ONLY: rpa_exchange_axk,&
      52             :                                               rpa_exchange_none,&
      53             :                                               rpa_exchange_sosex,&
      54             :                                               wfc_mm_style_gemm
      55             :    USE kinds,                           ONLY: dp,&
      56             :                                               int_8
      57             :    USE kpoint_types,                    ONLY: kpoint_type
      58             :    USE machine,                         ONLY: m_flush,&
      59             :                                               m_memory
      60             :    USE mathconstants,                   ONLY: pi,&
      61             :                                               z_zero
      62             :    USE message_passing,                 ONLY: mp_comm_type,&
      63             :                                               mp_para_env_release,&
      64             :                                               mp_para_env_type
      65             :    USE minimax_exp,                     ONLY: check_exp_minimax_range
      66             :    USE mp2_grids,                       ONLY: get_clenshaw_grid,&
      67             :                                               get_minimax_grid
      68             :    USE mp2_laplace,                     ONLY: SOS_MP2_postprocessing
      69             :    USE mp2_ri_grad_util,                ONLY: array2fm
      70             :    USE mp2_types,                       ONLY: mp2_type,&
      71             :                                               three_dim_real_array,&
      72             :                                               two_dim_int_array,&
      73             :                                               two_dim_real_array
      74             :    USE qs_environment_types,            ONLY: get_qs_env,&
      75             :                                               qs_environment_type
      76             :    USE rpa_exchange,                    ONLY: rpa_exchange_needed_mem,&
      77             :                                               rpa_exchange_work_type
      78             :    USE rpa_grad,                        ONLY: rpa_grad_copy_Q,&
      79             :                                               rpa_grad_create,&
      80             :                                               rpa_grad_finalize,&
      81             :                                               rpa_grad_matrix_operations,&
      82             :                                               rpa_grad_needed_mem,&
      83             :                                               rpa_grad_type
      84             :    USE rpa_gw,                          ONLY: allocate_matrices_gw,&
      85             :                                               allocate_matrices_gw_im_time,&
      86             :                                               compute_GW_self_energy,&
      87             :                                               compute_QP_energies,&
      88             :                                               compute_W_cubic_GW,&
      89             :                                               deallocate_matrices_gw,&
      90             :                                               deallocate_matrices_gw_im_time,&
      91             :                                               get_fermi_level_offset
      92             :    USE rpa_gw_ic,                       ONLY: calculate_ic_correction
      93             :    USE rpa_gw_kpoints_util,             ONLY: get_bandstruc_and_k_dependent_MOs,&
      94             :                                               invert_eps_compute_W_and_Erpa_kp
      95             :    USE rpa_im_time,                     ONLY: compute_mat_P_omega,&
      96             :                                               zero_mat_P_omega
      97             :    USE rpa_im_time_force_methods,       ONLY: calc_laplace_loop_forces,&
      98             :                                               calc_post_loop_forces,&
      99             :                                               calc_rpa_loop_forces,&
     100             :                                               init_im_time_forces,&
     101             :                                               keep_initial_quad
     102             :    USE rpa_im_time_force_types,         ONLY: im_time_force_release,&
     103             :                                               im_time_force_type
     104             :    USE rpa_util,                        ONLY: Q_trace_and_add_unit_matrix,&
     105             :                                               alloc_im_time,&
     106             :                                               calc_mat_Q,&
     107             :                                               compute_Erpa_by_freq_int,&
     108             :                                               contract_P_omega_with_mat_L,&
     109             :                                               dealloc_im_time,&
     110             :                                               remove_scaling_factor_rpa
     111             :    USE util,                            ONLY: get_limit
     112             : #include "./base/base_uses.f90"
     113             : 
     114             :    IMPLICIT NONE
     115             : 
     116             :    PRIVATE
     117             : 
     118             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'rpa_main'
     119             : 
     120             :    PUBLIC :: rpa_ri_compute_en
     121             : 
     122             : CONTAINS
     123             : 
     124             : ! **************************************************************************************************
     125             : !> \brief ...
     126             : !> \param qs_env ...
     127             : !> \param Erpa ...
     128             : !> \param mp2_env ...
     129             : !> \param BIb_C ...
     130             : !> \param BIb_C_gw ...
     131             : !> \param BIb_C_bse_ij ...
     132             : !> \param BIb_C_bse_ab ...
     133             : !> \param para_env ...
     134             : !> \param para_env_sub ...
     135             : !> \param color_sub ...
     136             : !> \param gd_array ...
     137             : !> \param gd_B_virtual ...
     138             : !> \param gd_B_all ...
     139             : !> \param gd_B_occ_bse ...
     140             : !> \param gd_B_virt_bse ...
     141             : !> \param mo_coeff ...
     142             : !> \param fm_matrix_PQ ...
     143             : !> \param fm_matrix_L_kpoints ...
     144             : !> \param fm_matrix_Minv_L_kpoints ...
     145             : !> \param fm_matrix_Minv ...
     146             : !> \param fm_matrix_Minv_Vtrunc_Minv ...
     147             : !> \param kpoints ...
     148             : !> \param Eigenval ...
     149             : !> \param nmo ...
     150             : !> \param homo ...
     151             : !> \param dimen_RI ...
     152             : !> \param dimen_RI_red ...
     153             : !> \param gw_corr_lev_occ ...
     154             : !> \param gw_corr_lev_virt ...
     155             : !> \param bse_lev_virt ...
     156             : !> \param unit_nr ...
     157             : !> \param do_ri_sos_laplace_mp2 ...
     158             : !> \param my_do_gw ...
     159             : !> \param do_im_time ...
     160             : !> \param do_bse ...
     161             : !> \param matrix_s ...
     162             : !> \param mat_munu ...
     163             : !> \param mat_P_global ...
     164             : !> \param t_3c_M ...
     165             : !> \param t_3c_O ...
     166             : !> \param t_3c_O_compressed ...
     167             : !> \param t_3c_O_ind ...
     168             : !> \param starts_array_mc ...
     169             : !> \param ends_array_mc ...
     170             : !> \param starts_array_mc_block ...
     171             : !> \param ends_array_mc_block ...
     172             : !> \param calc_forces ...
     173             : ! **************************************************************************************************
     174        1360 :    SUBROUTINE rpa_ri_compute_en(qs_env, Erpa, mp2_env, BIb_C, BIb_C_gw, BIb_C_bse_ij, BIb_C_bse_ab, &
     175             :                                 para_env, para_env_sub, color_sub, &
     176         272 :                                 gd_array, gd_B_virtual, gd_B_all, gd_B_occ_bse, gd_B_virt_bse, &
     177         272 :                                 mo_coeff, fm_matrix_PQ, fm_matrix_L_kpoints, fm_matrix_Minv_L_kpoints, &
     178             :                                 fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, kpoints, &
     179         544 :                                 Eigenval, nmo, homo, dimen_RI, dimen_RI_red, gw_corr_lev_occ, gw_corr_lev_virt, &
     180             :                                 bse_lev_virt, &
     181             :                                 unit_nr, do_ri_sos_laplace_mp2, my_do_gw, do_im_time, do_bse, matrix_s, &
     182             :                                 mat_munu, mat_P_global, t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
     183             :                                 starts_array_mc, ends_array_mc, &
     184             :                                 starts_array_mc_block, ends_array_mc_block, calc_forces)
     185             : 
     186             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     187             :       REAL(KIND=dp), INTENT(OUT)                         :: Erpa
     188             :       TYPE(mp2_type), INTENT(INOUT)                      :: mp2_env
     189             :       TYPE(three_dim_real_array), DIMENSION(:), &
     190             :          INTENT(INOUT)                                   :: BIb_C, BIb_C_gw
     191             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
     192             :          INTENT(INOUT)                                   :: BIb_C_bse_ij, BIb_C_bse_ab
     193             :       TYPE(mp_para_env_type), POINTER                    :: para_env, para_env_sub
     194             :       INTEGER, INTENT(INOUT)                             :: color_sub
     195             :       TYPE(group_dist_d1_type), INTENT(INOUT)            :: gd_array
     196             :       TYPE(group_dist_d1_type), DIMENSION(:), &
     197             :          INTENT(INOUT)                                   :: gd_B_virtual
     198             :       TYPE(group_dist_d1_type), INTENT(INOUT)            :: gd_B_all, gd_B_occ_bse, gd_B_virt_bse
     199             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: mo_coeff
     200             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_matrix_PQ
     201             :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :)     :: fm_matrix_L_kpoints, &
     202             :                                                             fm_matrix_Minv_L_kpoints, &
     203             :                                                             fm_matrix_Minv, &
     204             :                                                             fm_matrix_Minv_Vtrunc_Minv
     205             :       TYPE(kpoint_type), POINTER                         :: kpoints
     206             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
     207             :          INTENT(INOUT)                                   :: Eigenval
     208             :       INTEGER, INTENT(IN)                                :: nmo
     209             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: homo
     210             :       INTEGER, INTENT(IN)                                :: dimen_RI, dimen_RI_red
     211             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: gw_corr_lev_occ, gw_corr_lev_virt
     212             :       INTEGER, INTENT(IN)                                :: bse_lev_virt, unit_nr
     213             :       LOGICAL, INTENT(IN)                                :: do_ri_sos_laplace_mp2, my_do_gw, &
     214             :                                                             do_im_time, do_bse
     215             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
     216             :       TYPE(dbcsr_p_type), INTENT(IN)                     :: mat_munu
     217             :       TYPE(dbcsr_p_type), INTENT(INOUT)                  :: mat_P_global
     218             :       TYPE(dbt_type)                                     :: t_3c_M
     219             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_3c_O
     220             :       TYPE(hfx_compression_type), ALLOCATABLE, &
     221             :          DIMENSION(:, :, :), INTENT(INOUT)               :: t_3c_O_compressed
     222             :       TYPE(block_ind_type), ALLOCATABLE, &
     223             :          DIMENSION(:, :, :), INTENT(INOUT)               :: t_3c_O_ind
     224             :       INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(IN)     :: starts_array_mc, ends_array_mc, &
     225             :                                                             starts_array_mc_block, &
     226             :                                                             ends_array_mc_block
     227             :       LOGICAL, INTENT(IN)                                :: calc_forces
     228             : 
     229             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'rpa_ri_compute_en'
     230             : 
     231             :       INTEGER :: best_integ_group_size, best_num_integ_point, color_rpa_group, dimen_homo_square, &
     232             :          dimen_nm_gw, dimen_virt_square, handle, handle2, handle3, ierr, iiB, &
     233             :          input_num_integ_groups, integ_group_size, ispin, jjB, min_integ_group_size, &
     234             :          my_ab_comb_bse_end, my_ab_comb_bse_size, my_ab_comb_bse_start, my_group_L_end, &
     235             :          my_group_L_size, my_group_L_start, my_ij_comb_bse_end, my_ij_comb_bse_size, &
     236             :          my_ij_comb_bse_start, my_nm_gw_end, my_nm_gw_size, my_nm_gw_start, ncol_block_mat, &
     237             :          ngroup, nrow_block_mat, nspins, num_integ_group, num_integ_points, pos_integ_group
     238             :       INTEGER(KIND=int_8)                                :: mem
     239         544 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: dimen_ia, my_ia_end, my_ia_size, &
     240         272 :                                                             my_ia_start, virtual
     241             :       LOGICAL                                            :: do_kpoints_from_Gamma, do_minimax_quad, &
     242             :                                                             my_open_shell, skip_integ_group_opt
     243             :       REAL(KIND=dp) :: allowed_memory, avail_mem, E_Range, Emax, Emin, mem_for_iaK, mem_for_QK, &
     244             :          mem_min, mem_per_group, mem_per_rank, mem_per_repl, mem_real
     245         272 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: Eigenval_kp
     246         544 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:)        :: fm_mat_Q, fm_mat_Q_gemm, fm_mat_S, &
     247         272 :                                                             fm_mat_S_gw
     248         816 :       TYPE(cp_fm_type), DIMENSION(1)                     :: fm_mat_R_gw, fm_mat_S_ab_bse, &
     249         544 :                                                             fm_mat_S_ij_bse
     250             :       TYPE(mp_para_env_type), POINTER                    :: para_env_RPA
     251             :       TYPE(two_dim_real_array), ALLOCATABLE, &
     252         544 :          DIMENSION(:)                                    :: BIb_C_2D, BIb_C_2D_gw
     253        2720 :       TYPE(two_dim_real_array), DIMENSION(1)             :: BIb_C_2D_bse_ab, BIb_C_2D_bse_ij
     254             : 
     255         272 :       CALL timeset(routineN, handle)
     256             : 
     257         272 :       CALL cite_reference(DelBen2013)
     258         272 :       CALL cite_reference(DelBen2015)
     259             : 
     260         272 :       IF (mp2_env%ri_rpa%exchange_correction == rpa_exchange_axk) THEN
     261          10 :          CALL cite_reference(Bates2013)
     262         262 :       ELSE IF (mp2_env%ri_rpa%exchange_correction == rpa_exchange_sosex) THEN
     263           2 :          CALL cite_reference(Freeman1977)
     264           2 :          CALL cite_reference(Gruneis2009)
     265             :       END IF
     266         272 :       IF (mp2_env%ri_rpa%do_rse) THEN
     267           4 :          CALL cite_reference(Ren2011)
     268           4 :          CALL cite_reference(Ren2013)
     269             :       END IF
     270             : 
     271         272 :       IF (my_do_gw) THEN
     272          92 :          CALL cite_reference(Wilhelm2016a)
     273          92 :          CALL cite_reference(Wilhelm2017)
     274          92 :          CALL cite_reference(Wilhelm2018)
     275             :       END IF
     276             : 
     277         272 :       IF (do_im_time) THEN
     278         134 :          CALL cite_reference(Wilhelm2016b)
     279             :       END IF
     280             : 
     281         272 :       nspins = SIZE(homo)
     282         272 :       my_open_shell = (nspins == 2)
     283        1904 :       ALLOCATE (virtual(nspins), dimen_ia(nspins), my_ia_end(nspins), my_ia_start(nspins), my_ia_size(nspins))
     284         598 :       virtual(:) = nmo - homo(:)
     285         598 :       dimen_ia(:) = virtual(:)*homo(:)
     286             : 
     287        1088 :       ALLOCATE (Eigenval_kp(nmo, 1, nspins))
     288        8378 :       Eigenval_kp(:, 1, :) = Eigenval(:, :)
     289             : 
     290         272 :       IF (do_im_time) mp2_env%ri_rpa%minimax_quad = .TRUE.
     291         272 :       do_minimax_quad = mp2_env%ri_rpa%minimax_quad
     292             : 
     293         272 :       IF (do_ri_sos_laplace_mp2) THEN
     294          58 :          num_integ_points = mp2_env%ri_laplace%n_quadrature
     295          58 :          input_num_integ_groups = mp2_env%ri_laplace%num_integ_groups
     296             : 
     297             :          ! check the range for the minimax approximation
     298          58 :          E_Range = mp2_env%e_range
     299          58 :          IF (mp2_env%e_range <= 1.0_dp .OR. mp2_env%e_gap <= 0.0_dp) THEN
     300             :             Emin = HUGE(dp)
     301             :             Emax = 0.0_dp
     302          88 :             DO ispin = 1, nspins
     303          88 :                IF (homo(ispin) > 0) THEN
     304          50 :                   Emin = MIN(Emin, 2.0_dp*(Eigenval(homo(ispin) + 1, ispin) - Eigenval(homo(ispin), ispin)))
     305        2740 :                   Emax = MAX(Emax, 2.0_dp*(MAXVAL(Eigenval(:, ispin)) - MINVAL(Eigenval(:, ispin))))
     306             :                END IF
     307             :             END DO
     308          38 :             E_Range = Emax/Emin
     309             :          END IF
     310          58 :          IF (E_Range < 2.0_dp) E_Range = 2.0_dp
     311             :          ierr = 0
     312          58 :          CALL check_exp_minimax_range(num_integ_points, E_Range, ierr)
     313          58 :          IF (ierr /= 0) THEN
     314             :             jjB = num_integ_points - 1
     315           0 :             DO iiB = 1, jjB
     316           0 :                num_integ_points = num_integ_points - 1
     317             :                ierr = 0
     318           0 :                CALL check_exp_minimax_range(num_integ_points, E_Range, ierr)
     319           0 :                IF (ierr == 0) EXIT
     320             :             END DO
     321             :          END IF
     322          58 :          CPASSERT(num_integ_points >= 1)
     323             :       ELSE
     324         214 :          num_integ_points = mp2_env%ri_rpa%rpa_num_quad_points
     325         214 :          input_num_integ_groups = mp2_env%ri_rpa%rpa_num_integ_groups
     326             : 
     327         214 :          IF (my_do_gw .AND. do_minimax_quad) THEN
     328          46 :             IF (num_integ_points > 34) THEN
     329           0 :                IF (unit_nr > 0) &
     330             :                   CALL cp_warn(__LOCATION__, &
     331             :                                "The required number of quadrature point exceeds the maximum possible in the "// &
     332           0 :                                "Minimax quadrature scheme. The number of quadrature point has been reset to 30.")
     333           0 :                num_integ_points = 30
     334             :             END IF
     335             :          ELSE
     336         168 :             IF (do_minimax_quad .AND. num_integ_points > 20) THEN
     337           0 :                IF (unit_nr > 0) &
     338             :                   CALL cp_warn(__LOCATION__, &
     339             :                                "The required number of quadrature point exceeds the maximum possible in the "// &
     340           0 :                                "Minimax quadrature scheme. The number of quadrature point has been reset to 20.")
     341           0 :                num_integ_points = 20
     342             :             END IF
     343             :          END IF
     344             :       END IF
     345         272 :       allowed_memory = mp2_env%mp2_memory
     346             : 
     347         272 :       CALL get_group_dist(gd_array, color_sub, my_group_L_start, my_group_L_end, my_group_L_size)
     348             : 
     349         272 :       ngroup = para_env%num_pe/para_env_sub%num_pe
     350             : 
     351             :       ! for imaginary time or periodic GW or BSE, we use all processors for a single frequency/time point
     352         272 :       IF (do_im_time .OR. mp2_env%ri_g0w0%do_periodic .OR. do_bse) THEN
     353             : 
     354         154 :          integ_group_size = ngroup
     355         154 :          best_num_integ_point = num_integ_points
     356             : 
     357             :       ELSE
     358             : 
     359             :          ! Calculate available memory and create integral group according to that
     360             :          ! mem_for_iaK is the memory needed for storing the 3 centre integrals
     361         260 :          mem_for_iaK = REAL(SUM(dimen_ia), KIND=dp)*dimen_RI_red*8.0_dp/(1024_dp**2)
     362         118 :          mem_for_QK = REAL(dimen_RI_red, KIND=dp)*nspins*dimen_RI_red*8.0_dp/(1024_dp**2)
     363             : 
     364         118 :          CALL m_memory(mem)
     365         118 :          mem_real = (mem + 1024*1024 - 1)/(1024*1024)
     366         118 :          CALL para_env%min(mem_real)
     367             : 
     368         118 :          mem_per_rank = 0.0_dp
     369             : 
     370             :          ! B_ia_P
     371             :          mem_per_repl = mem_for_iaK
     372             :          ! Q (regular and for dgemm)
     373         118 :          mem_per_repl = mem_per_repl + 2.0_dp*mem_for_QK
     374             : 
     375         118 :          IF (calc_forces) CALL rpa_grad_needed_mem(homo, virtual, dimen_RI_red, mem_per_rank, mem_per_repl, do_ri_sos_laplace_mp2)
     376         118 :          CALL rpa_exchange_needed_mem(mp2_env, homo, virtual, dimen_RI_red, para_env, mem_per_rank, mem_per_repl)
     377             : 
     378         118 :          mem_min = mem_per_repl/para_env%num_pe + mem_per_rank
     379             : 
     380         118 :          IF (unit_nr > 0) THEN
     381          59 :             WRITE (unit_nr, '(T3,A,T68,F9.2,A4)') 'RI_INFO| Minimum required memory per MPI process:', mem_min, ' MiB'
     382          59 :             WRITE (unit_nr, '(T3,A,T68,F9.2,A4)') 'RI_INFO| Available memory per MPI process:', mem_real, ' MiB'
     383             :          END IF
     384             : 
     385             :          ! Use only the allowed amount of memory
     386         118 :          mem_real = MIN(mem_real, allowed_memory)
     387             :          ! For the memory estimate, we require the amount of required memory per replication group and the available memory
     388         118 :          mem_real = mem_real - mem_per_rank
     389             : 
     390         118 :          mem_per_group = mem_real*para_env_sub%num_pe
     391             : 
     392             :          ! here we try to find the best rpa/laplace group size
     393         118 :          skip_integ_group_opt = .FALSE.
     394             : 
     395             :          ! Check the input number of integration groups
     396         118 :          IF (input_num_integ_groups > 0) THEN
     397           0 :             IF (MOD(num_integ_points, input_num_integ_groups) == 0) THEN
     398           0 :                IF (MOD(ngroup, input_num_integ_groups) == 0) THEN
     399           0 :                   best_integ_group_size = ngroup/input_num_integ_groups
     400           0 :                   best_num_integ_point = num_integ_points/input_num_integ_groups
     401           0 :                   skip_integ_group_opt = .TRUE.
     402             :                ELSE
     403           0 :                   IF (unit_nr > 0) WRITE (unit_nr, '(T3,A)') 'Total number of groups not multiple of NUM_INTEG_GROUPS'
     404             :                END IF
     405             :             ELSE
     406           0 :                IF (unit_nr > 0) WRITE (unit_nr, '(T3,A)') 'NUM_QUAD_POINTS not multiple of NUM_INTEG_GROUPS'
     407             :             END IF
     408             :          END IF
     409             : 
     410         118 :          IF (.NOT. skip_integ_group_opt) THEN
     411         118 :             best_integ_group_size = ngroup
     412         118 :             best_num_integ_point = num_integ_points
     413             : 
     414         118 :             min_integ_group_size = MAX(1, ngroup/num_integ_points)
     415             : 
     416         118 :             integ_group_size = min_integ_group_size - 1
     417         132 :             DO iiB = min_integ_group_size + 1, ngroup
     418          96 :                integ_group_size = integ_group_size + 1
     419             : 
     420             :                ! check that the ngroup is a multiple of integ_group_size
     421          96 :                IF (MOD(ngroup, integ_group_size) /= 0) CYCLE
     422             : 
     423             :                ! check for memory
     424          96 :                avail_mem = integ_group_size*mem_per_group
     425          96 :                IF (avail_mem < mem_per_repl) CYCLE
     426             : 
     427             :                ! check that the integration groups have the same size
     428          96 :                num_integ_group = ngroup/integ_group_size
     429          96 :                IF (MOD(num_integ_points, num_integ_group) /= 0) CYCLE
     430             : 
     431          82 :                best_num_integ_point = num_integ_points/num_integ_group
     432          82 :                best_integ_group_size = integ_group_size
     433             : 
     434         132 :                EXIT
     435             : 
     436             :             END DO
     437             :          END IF
     438             : 
     439         118 :          integ_group_size = best_integ_group_size
     440             : 
     441             :       END IF
     442             : 
     443         272 :       IF (unit_nr > 0 .AND. .NOT. do_im_time) THEN
     444          69 :          IF (do_ri_sos_laplace_mp2) THEN
     445             :             WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
     446          14 :                "RI_INFO| Group size for laplace numerical integration:", integ_group_size*para_env_sub%num_pe
     447             :             WRITE (UNIT=unit_nr, FMT="(T3,A)") &
     448          14 :                "INTEG_INFO| MINIMAX approximation"
     449             :             WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
     450          14 :                "INTEG_INFO| Number of integration points:", num_integ_points
     451             :             WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
     452          14 :                "INTEG_INFO| Number of integration points per Laplace group:", best_num_integ_point
     453             :          ELSE
     454             :             WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
     455          55 :                "RI_INFO| Group size for frequency integration:", integ_group_size*para_env_sub%num_pe
     456          55 :             IF (do_minimax_quad) THEN
     457             :                WRITE (UNIT=unit_nr, FMT="(T3,A)") &
     458          16 :                   "INTEG_INFO| MINIMAX quadrature"
     459             :             ELSE
     460             :                WRITE (UNIT=unit_nr, FMT="(T3,A)") &
     461          39 :                   "INTEG_INFO| Clenshaw-Curtius quadrature"
     462             :             END IF
     463             :             WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
     464          55 :                "INTEG_INFO| Number of integration points:", num_integ_points
     465             :             WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
     466          55 :                "INTEG_INFO| Number of integration points per RPA group:", best_num_integ_point
     467             :          END IF
     468          69 :          CALL m_flush(unit_nr)
     469             :       END IF
     470             : 
     471         272 :       num_integ_group = ngroup/integ_group_size
     472             : 
     473         272 :       pos_integ_group = MOD(color_sub, integ_group_size)
     474         272 :       color_rpa_group = color_sub/integ_group_size
     475             : 
     476         272 :       CALL timeset(routineN//"_reorder", handle2)
     477             : 
     478             :       ! not necessary for imaginary time
     479             : 
     480        1142 :       ALLOCATE (BIb_C_2D(nspins))
     481         272 :       IF (.NOT. do_im_time) THEN
     482             : 
     483             :          ! reorder the local data in such a way to help the next stage of matrix creation
     484             :          ! now the data inside the group are divided into a ia x K matrix
     485         300 :          DO ispin = 1, nspins
     486             :             CALL calculate_BIb_C_2D(BIb_C_2D(ispin)%array, BIb_C(ispin)%array, para_env_sub, dimen_ia(ispin), &
     487             :                                     homo(ispin), virtual(ispin), gd_B_virtual(ispin), &
     488         162 :                                     my_ia_size(ispin), my_ia_start(ispin), my_ia_end(ispin), my_group_L_size)
     489             : 
     490         162 :             DEALLOCATE (BIb_C(ispin)%array)
     491         462 :             CALL release_group_dist(gd_B_virtual(ispin))
     492             : 
     493             :          END DO
     494             : 
     495             :          ! in the GW case, BIb_C_2D_gw is an nm x K matrix, with n: number of corr GW levels, m=nmo
     496         138 :          IF (my_do_gw) THEN
     497         142 :             ALLOCATE (BIb_C_2D_gw(nspins))
     498             : 
     499          46 :             CALL timeset(routineN//"_reorder_gw", handle3)
     500             : 
     501          46 :             dimen_nm_gw = nmo*(gw_corr_lev_occ(1) + gw_corr_lev_virt(1))
     502             : 
     503             :             ! The same for open shell
     504          96 :             DO ispin = 1, nspins
     505             :                CALL calculate_BIb_C_2D(BIb_C_2D_gw(ispin)%array, BIb_C_gw(ispin)%array, para_env_sub, dimen_nm_gw, &
     506             :                                        gw_corr_lev_occ(ispin) + gw_corr_lev_virt(ispin), nmo, gd_B_all, &
     507          50 :                                        my_nm_gw_size, my_nm_gw_start, my_nm_gw_end, my_group_L_size)
     508          96 :                DEALLOCATE (BIb_C_gw(ispin)%array)
     509             :             END DO
     510             : 
     511          46 :             CALL release_group_dist(gd_B_all)
     512             : 
     513          92 :             CALL timestop(handle3)
     514             : 
     515             :          END IF
     516             :       END IF
     517             : 
     518         308 :       IF (do_bse) THEN
     519             : 
     520          18 :          CALL timeset(routineN//"_reorder_bse1", handle3)
     521             : 
     522          18 :          dimen_homo_square = homo(1)**2
     523             :          ! We do not implement an explicit bse_lev_occ different to homo here, because the small number of occupied levels
     524             :          ! does not critically influence the memory
     525             :          CALL calculate_BIb_C_2D(BIb_C_2D_bse_ij(1)%array, BIb_C_bse_ij, para_env_sub, dimen_homo_square, &
     526             :                                  homo(1), homo(1), gd_B_occ_bse, &
     527          18 :                                  my_ij_comb_bse_size, my_ij_comb_bse_start, my_ij_comb_bse_end, my_group_L_size)
     528             : 
     529          18 :          DEALLOCATE (BIb_C_bse_ij)
     530          18 :          CALL release_group_dist(gd_B_occ_bse)
     531             : 
     532          18 :          CALL timestop(handle3)
     533             : 
     534          18 :          CALL timeset(routineN//"_reorder_bse2", handle3)
     535             : 
     536          18 :          dimen_virt_square = bse_lev_virt**2
     537             : 
     538             :          CALL calculate_BIb_C_2D(BIb_C_2D_bse_ab(1)%array, BIb_C_bse_ab, para_env_sub, dimen_virt_square, &
     539             :                                  bse_lev_virt, bse_lev_virt, gd_B_virt_bse, &
     540          18 :                                  my_ab_comb_bse_size, my_ab_comb_bse_start, my_ab_comb_bse_end, my_group_L_size)
     541             : 
     542          18 :          DEALLOCATE (BIb_C_bse_ab)
     543          18 :          CALL release_group_dist(gd_B_virt_bse)
     544             : 
     545          18 :          CALL timestop(handle3)
     546             : 
     547             :       END IF
     548             : 
     549         272 :       CALL timestop(handle2)
     550             : 
     551         272 :       IF (num_integ_group > 1) THEN
     552          82 :          ALLOCATE (para_env_RPA)
     553          82 :          CALL para_env_RPA%from_split(para_env, color_rpa_group)
     554             :       ELSE
     555         190 :          para_env_RPA => para_env
     556             :       END IF
     557             : 
     558             :       ! now create the matrices needed for the calculation, Q, S and G
     559             :       ! Q and G will have omega dependence
     560             : 
     561         272 :       IF (do_im_time) THEN
     562         834 :          ALLOCATE (fm_mat_Q(nspins), fm_mat_Q_gemm(1), fm_mat_S(1))
     563             :       ELSE
     564        1176 :          ALLOCATE (fm_mat_Q(nspins), fm_mat_Q_gemm(nspins), fm_mat_S(nspins))
     565             :       END IF
     566             : 
     567             :       CALL create_integ_mat(BIb_C_2D, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
     568             :                             dimen_RI_red, dimen_ia, color_rpa_group, &
     569             :                             mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
     570             :                             my_ia_size, my_ia_start, my_ia_end, &
     571             :                             my_group_L_size, my_group_L_start, my_group_L_end, &
     572             :                             para_env_RPA, fm_mat_S, nrow_block_mat, ncol_block_mat, &
     573             :                             dimen_ia_for_block_size=dimen_ia(1), &
     574         272 :                             do_im_time=do_im_time, fm_mat_Q_gemm=fm_mat_Q_gemm, fm_mat_Q=fm_mat_Q, qs_env=qs_env)
     575             : 
     576         598 :       DEALLOCATE (BIb_C_2D, my_ia_end, my_ia_size, my_ia_start)
     577             : 
     578             :       ! for GW, we need other matrix fm_mat_S, always allocate the container to prevent crying compilers
     579        1142 :       ALLOCATE (fm_mat_S_gw(nspins))
     580         272 :       IF (my_do_gw .AND. .NOT. do_im_time) THEN
     581             : 
     582             :          CALL create_integ_mat(BIb_C_2D_gw, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
     583             :                                dimen_RI_red, [dimen_nm_gw, dimen_nm_gw], color_rpa_group, &
     584             :                                mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
     585             :                                [my_nm_gw_size, my_nm_gw_size], [my_nm_gw_start, my_nm_gw_start], [my_nm_gw_end, my_nm_gw_end], &
     586             :                                my_group_L_size, my_group_L_start, my_group_L_end, &
     587             :                                para_env_RPA, fm_mat_S_gw, nrow_block_mat, ncol_block_mat, &
     588             :                                fm_mat_Q(1)%matrix_struct%context, fm_mat_Q(1)%matrix_struct%context, &
     589         414 :                                fm_mat_Q=fm_mat_R_gw)
     590          96 :          DEALLOCATE (BIb_C_2D_gw)
     591             : 
     592             :       END IF
     593             : 
     594             :       ! for Bethe-Salpeter, we need other matrix fm_mat_S
     595         272 :       IF (do_bse) THEN
     596             :          CALL create_integ_mat(BIb_C_2D_bse_ij, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
     597             :                                dimen_RI_red, [dimen_homo_square], color_rpa_group, &
     598             :                                mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
     599             :                                [my_ij_comb_bse_size], [my_ij_comb_bse_start], [my_ij_comb_bse_end], &
     600             :                                my_group_L_size, my_group_L_start, my_group_L_end, &
     601             :                                para_env_RPA, fm_mat_S_ij_bse, nrow_block_mat, ncol_block_mat, &
     602          90 :                                fm_mat_Q(1)%matrix_struct%context, fm_mat_Q(1)%matrix_struct%context)
     603             : 
     604             :          CALL create_integ_mat(BIb_C_2D_bse_ab, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
     605             :                                dimen_RI_red, [dimen_virt_square], color_rpa_group, &
     606             :                                mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
     607             :                                [my_ab_comb_bse_size], [my_ab_comb_bse_start], [my_ab_comb_bse_end], &
     608             :                                my_group_L_size, my_group_L_start, my_group_L_end, &
     609             :                                para_env_RPA, fm_mat_S_ab_bse, nrow_block_mat, ncol_block_mat, &
     610          90 :                                fm_mat_Q(1)%matrix_struct%context, fm_mat_Q(1)%matrix_struct%context)
     611             : 
     612             :       END IF
     613             : 
     614         272 :       do_kpoints_from_Gamma = qs_env%mp2_env%ri_rpa_im_time%do_kpoints_from_Gamma
     615         272 :       IF (do_kpoints_from_Gamma) THEN
     616          18 :          CALL get_bandstruc_and_k_dependent_MOs(qs_env, Eigenval_kp)
     617             :       END IF
     618             : 
     619             :       ! Now start the RPA calculation
     620             :       ! fm_mo_coeff_occ, fm_mo_coeff_virt will be deallocated here
     621             :       CALL rpa_num_int(qs_env, Erpa, mp2_env, para_env, para_env_RPA, para_env_sub, unit_nr, &
     622             :                        homo, virtual, dimen_RI, dimen_RI_red, dimen_ia, dimen_nm_gw, &
     623             :                        Eigenval_kp, num_integ_points, num_integ_group, color_rpa_group, &
     624             :                        fm_matrix_PQ, fm_mat_S, fm_mat_Q_gemm, fm_mat_Q, fm_mat_S_gw, fm_mat_R_gw(1), &
     625             :                        fm_mat_S_ij_bse(1), fm_mat_S_ab_bse(1), &
     626             :                        my_do_gw, do_bse, gw_corr_lev_occ, gw_corr_lev_virt, &
     627             :                        bse_lev_virt, &
     628             :                        do_minimax_quad, &
     629             :                        do_im_time, mo_coeff, &
     630             :                        fm_matrix_L_kpoints, fm_matrix_Minv_L_kpoints, &
     631             :                        fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, mat_munu, mat_P_global, &
     632             :                        t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
     633             :                        starts_array_mc, ends_array_mc, &
     634             :                        starts_array_mc_block, ends_array_mc_block, &
     635             :                        matrix_s, do_kpoints_from_Gamma, kpoints, gd_array, color_sub, &
     636         272 :                        do_ri_sos_laplace_mp2=do_ri_sos_laplace_mp2, calc_forces=calc_forces)
     637             : 
     638         272 :       CALL release_group_dist(gd_array)
     639             : 
     640         272 :       IF (num_integ_group > 1) CALL mp_para_env_release(para_env_RPA)
     641             : 
     642         272 :       IF (.NOT. do_im_time) THEN
     643         138 :          CALL cp_fm_release(fm_mat_Q_gemm)
     644         138 :          CALL cp_fm_release(fm_mat_S)
     645             :       END IF
     646         272 :       CALL cp_fm_release(fm_mat_Q)
     647             : 
     648         272 :       IF (my_do_gw .AND. .NOT. do_im_time) THEN
     649          46 :          CALL cp_fm_release(fm_mat_S_gw)
     650          46 :          CALL cp_fm_release(fm_mat_R_gw(1))
     651             :       END IF
     652             : 
     653         272 :       IF (do_bse) THEN
     654          18 :          CALL cp_fm_release(fm_mat_S_ij_bse(1))
     655          18 :          CALL cp_fm_release(fm_mat_S_ab_bse(1))
     656             :       END IF
     657             : 
     658         272 :       CALL timestop(handle)
     659             : 
     660        1088 :    END SUBROUTINE rpa_ri_compute_en
     661             : 
     662             : ! **************************************************************************************************
     663             : !> \brief reorder the local data in such a way to help the next stage of matrix creation;
     664             : !>        now the data inside the group are divided into a ia x K matrix (BIb_C_2D);
     665             : !>        Subroutine created to avoid massive double coding
     666             : !> \param BIb_C_2D ...
     667             : !> \param BIb_C ...
     668             : !> \param para_env_sub ...
     669             : !> \param dimen_ia ...
     670             : !> \param homo ...
     671             : !> \param virtual ...
     672             : !> \param gd_B_virtual ...
     673             : !> \param my_ia_size ...
     674             : !> \param my_ia_start ...
     675             : !> \param my_ia_end ...
     676             : !> \param my_group_L_size ...
     677             : !> \author Jan Wilhelm, 03/2015
     678             : ! **************************************************************************************************
     679         248 :    SUBROUTINE calculate_BIb_C_2D(BIb_C_2D, BIb_C, para_env_sub, dimen_ia, homo, virtual, &
     680             :                                  gd_B_virtual, &
     681             :                                  my_ia_size, my_ia_start, my_ia_end, my_group_L_size)
     682             : 
     683             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
     684             :          INTENT(OUT)                                     :: BIb_C_2D
     685             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
     686             :          INTENT(IN)                                      :: BIb_C
     687             :       TYPE(mp_para_env_type), INTENT(IN)                 :: para_env_sub
     688             :       INTEGER, INTENT(IN)                                :: dimen_ia, homo, virtual
     689             :       TYPE(group_dist_d1_type), INTENT(INOUT)            :: gd_B_virtual
     690             :       INTEGER                                            :: my_ia_size, my_ia_start, my_ia_end, &
     691             :                                                             my_group_L_size
     692             : 
     693             :       INTEGER, PARAMETER                                 :: occ_chunk = 128
     694             : 
     695             :       INTEGER :: ia_global, iiB, itmp(2), jjB, my_B_size, my_B_virtual_start, occ_high, occ_low, &
     696             :          proc_receive, proc_send, proc_shift, rec_B_size, rec_B_virtual_end, rec_B_virtual_start
     697         248 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), TARGET   :: BIb_C_rec_1D
     698         248 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: BIb_C_rec
     699             : 
     700         248 :       itmp = get_limit(dimen_ia, para_env_sub%num_pe, para_env_sub%mepos)
     701         248 :       my_ia_start = itmp(1)
     702         248 :       my_ia_end = itmp(2)
     703         248 :       my_ia_size = my_ia_end - my_ia_start + 1
     704             : 
     705         248 :       CALL get_group_dist(gd_B_virtual, para_env_sub%mepos, sizes=my_B_size, starts=my_B_virtual_start)
     706             : 
     707             :       ! reorder data
     708         990 :       ALLOCATE (BIb_C_2D(my_group_L_size, my_ia_size))
     709             : 
     710             : !$OMP     PARALLEL DO DEFAULT(NONE) PRIVATE(jjB,ia_global) &
     711             : !$OMP              SHARED(homo,my_B_size,virtual,my_B_virtual_start,my_ia_start,my_ia_end,BIb_C,BIb_C_2D,&
     712         248 : !$OMP              my_group_L_size)
     713             :       DO iiB = 1, homo
     714             :          DO jjB = 1, my_B_size
     715             :             ia_global = (iiB - 1)*virtual + my_B_virtual_start + jjB - 1
     716             :             IF (ia_global >= my_ia_start .AND. ia_global <= my_ia_end) THEN
     717             :                BIb_C_2D(1:my_group_L_size, ia_global - my_ia_start + 1) = BIb_C(1:my_group_L_size, jjB, iiB)
     718             :             END IF
     719             :          END DO
     720             :       END DO
     721             : 
     722         248 :       IF (para_env_sub%num_pe > 1) THEN
     723          30 :          ALLOCATE (BIb_C_rec_1D(INT(my_group_L_size, int_8)*maxsize(gd_B_virtual)*MIN(homo, occ_chunk)))
     724          20 :          DO proc_shift = 1, para_env_sub%num_pe - 1
     725          10 :             proc_send = MODULO(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
     726          10 :             proc_receive = MODULO(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
     727             : 
     728          10 :             CALL get_group_dist(gd_B_virtual, proc_receive, rec_B_virtual_start, rec_B_virtual_end, rec_B_size)
     729             : 
     730             :             ! do this in chunks to avoid high memory overhead
     731          20 :             DO occ_low = 1, homo, occ_chunk
     732          10 :                occ_high = MIN(homo, occ_low + occ_chunk - 1)
     733             :                BIb_C_rec(1:my_group_L_size, 1:rec_B_size, 1:occ_high - occ_low + 1) => &
     734          10 :                   BIb_C_rec_1D(1:INT(my_group_L_size, int_8)*rec_B_size*(occ_high - occ_low + 1))
     735             :                CALL para_env_sub%sendrecv(BIb_C(:, :, occ_low:occ_high), proc_send, &
     736       31970 :                                           BIb_C_rec(:, :, 1:occ_high - occ_low + 1), proc_receive)
     737             : !$OMP          PARALLEL DO DEFAULT(NONE) PRIVATE(jjB,ia_global) &
     738             : !$OMP                   SHARED(occ_low,occ_high,rec_B_size,virtual,rec_B_virtual_start,my_ia_start,my_ia_end,BIb_C_rec,BIb_C_2D,&
     739          10 : !$OMP                          my_group_L_size)
     740             :                DO iiB = occ_low, occ_high
     741             :                   DO jjB = 1, rec_B_size
     742             :                      ia_global = (iiB - 1)*virtual + rec_B_virtual_start + jjB - 1
     743             :                      IF (ia_global >= my_ia_start .AND. ia_global <= my_ia_end) THEN
     744             :                      BIb_C_2D(1:my_group_L_size, ia_global - my_ia_start + 1) = BIb_C_rec(1:my_group_L_size, jjB, iiB - occ_low + 1)
     745             :                      END IF
     746             :                   END DO
     747             :                END DO
     748             :             END DO
     749             : 
     750             :          END DO
     751          10 :          DEALLOCATE (BIb_C_rec_1D)
     752             :       END IF
     753             : 
     754         248 :    END SUBROUTINE calculate_BIb_C_2D
     755             : 
     756             : ! **************************************************************************************************
     757             : !> \brief ...
     758             : !> \param BIb_C_2D ...
     759             : !> \param para_env ...
     760             : !> \param para_env_sub ...
     761             : !> \param color_sub ...
     762             : !> \param ngroup ...
     763             : !> \param integ_group_size ...
     764             : !> \param dimen_RI ...
     765             : !> \param dimen_ia ...
     766             : !> \param color_rpa_group ...
     767             : !> \param ext_row_block_size ...
     768             : !> \param ext_col_block_size ...
     769             : !> \param unit_nr ...
     770             : !> \param my_ia_size ...
     771             : !> \param my_ia_start ...
     772             : !> \param my_ia_end ...
     773             : !> \param my_group_L_size ...
     774             : !> \param my_group_L_start ...
     775             : !> \param my_group_L_end ...
     776             : !> \param para_env_RPA ...
     777             : !> \param fm_mat_S ...
     778             : !> \param nrow_block_mat ...
     779             : !> \param ncol_block_mat ...
     780             : !> \param blacs_env_ext ...
     781             : !> \param blacs_env_ext_S ...
     782             : !> \param dimen_ia_for_block_size ...
     783             : !> \param do_im_time ...
     784             : !> \param fm_mat_Q_gemm ...
     785             : !> \param fm_mat_Q ...
     786             : !> \param qs_env ...
     787             : ! **************************************************************************************************
     788         354 :    SUBROUTINE create_integ_mat(BIb_C_2D, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
     789         354 :                                dimen_RI, dimen_ia, color_rpa_group, &
     790             :                                ext_row_block_size, ext_col_block_size, unit_nr, &
     791         354 :                                my_ia_size, my_ia_start, my_ia_end, &
     792             :                                my_group_L_size, my_group_L_start, my_group_L_end, &
     793         354 :                                para_env_RPA, fm_mat_S, nrow_block_mat, ncol_block_mat, &
     794             :                                blacs_env_ext, blacs_env_ext_S, dimen_ia_for_block_size, &
     795         354 :                                do_im_time, fm_mat_Q_gemm, fm_mat_Q, qs_env)
     796             : 
     797             :       TYPE(two_dim_real_array), DIMENSION(:), &
     798             :          INTENT(INOUT)                                   :: BIb_C_2D
     799             :       TYPE(mp_para_env_type), INTENT(IN)                 :: para_env, para_env_sub
     800             :       INTEGER, INTENT(IN)                                :: color_sub, ngroup, integ_group_size, &
     801             :                                                             dimen_RI
     802             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: dimen_ia
     803             :       INTEGER, INTENT(IN)                                :: color_rpa_group, ext_row_block_size, &
     804             :                                                             ext_col_block_size, unit_nr
     805             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: my_ia_size, my_ia_start, my_ia_end
     806             :       INTEGER, INTENT(IN)                                :: my_group_L_size, my_group_L_start, &
     807             :                                                             my_group_L_end
     808             :       TYPE(mp_para_env_type), INTENT(IN), POINTER        :: para_env_RPA
     809             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT)      :: fm_mat_S
     810             :       INTEGER, INTENT(INOUT)                             :: nrow_block_mat, ncol_block_mat
     811             :       TYPE(cp_blacs_env_type), OPTIONAL, POINTER         :: blacs_env_ext, blacs_env_ext_S
     812             :       INTEGER, INTENT(IN), OPTIONAL                      :: dimen_ia_for_block_size
     813             :       LOGICAL, INTENT(IN), OPTIONAL                      :: do_im_time
     814             :       TYPE(cp_fm_type), DIMENSION(:), OPTIONAL           :: fm_mat_Q_gemm, fm_mat_Q
     815             :       TYPE(qs_environment_type), INTENT(IN), OPTIONAL, &
     816             :          POINTER                                         :: qs_env
     817             : 
     818             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'create_integ_mat'
     819             : 
     820             :       INTEGER                                            :: col_row_proc_ratio, grid_2D(2), handle, &
     821             :                                                             iproc, iproc_col, iproc_row, ispin, &
     822             :                                                             mepos_in_RPA_group
     823         354 :       INTEGER, ALLOCATABLE, DIMENSION(:, :)              :: group_grid_2_mepos
     824             :       LOGICAL                                            :: my_blacs_ext, my_blacs_S_ext, &
     825             :                                                             my_do_im_time
     826             :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env, blacs_env_Q
     827             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct
     828         354 :       TYPE(group_dist_d1_type)                           :: gd_ia, gd_L
     829             : 
     830         354 :       CALL timeset(routineN, handle)
     831             : 
     832         354 :       CPASSERT(PRESENT(blacs_env_ext) .OR. PRESENT(dimen_ia_for_block_size))
     833             : 
     834         354 :       my_blacs_ext = .FALSE.
     835         354 :       IF (PRESENT(blacs_env_ext)) my_blacs_ext = .TRUE.
     836             : 
     837         354 :       my_blacs_S_ext = .FALSE.
     838         354 :       IF (PRESENT(blacs_env_ext_S)) my_blacs_S_ext = .TRUE.
     839             : 
     840         354 :       my_do_im_time = .FALSE.
     841         354 :       IF (PRESENT(do_im_time)) my_do_im_time = do_im_time
     842             : 
     843         354 :       NULLIFY (blacs_env)
     844             :       ! create the RPA blacs env
     845         354 :       IF (my_blacs_S_ext) THEN
     846          82 :          blacs_env => blacs_env_ext_S
     847             :       ELSE
     848         272 :          IF (para_env_RPA%num_pe > 1) THEN
     849         190 :             col_row_proc_ratio = MAX(1, dimen_ia_for_block_size/dimen_RI)
     850             : 
     851         190 :             iproc_col = MIN(MAX(INT(SQRT(REAL(para_env_RPA%num_pe*col_row_proc_ratio, KIND=dp))), 1), para_env_RPA%num_pe) + 1
     852         190 :             DO iproc = 1, para_env_RPA%num_pe
     853         190 :                iproc_col = iproc_col - 1
     854         190 :                IF (MOD(para_env_RPA%num_pe, iproc_col) == 0) EXIT
     855             :             END DO
     856             : 
     857         190 :             iproc_row = para_env_RPA%num_pe/iproc_col
     858         190 :             grid_2D(1) = iproc_row
     859         190 :             grid_2D(2) = iproc_col
     860             :          ELSE
     861         246 :             grid_2D = 1
     862             :          END IF
     863         272 :          CALL cp_blacs_env_create(blacs_env=blacs_env, para_env=para_env_RPA, grid_2d=grid_2D)
     864             : 
     865         272 :          IF (unit_nr > 0 .AND. .NOT. my_do_im_time) THEN
     866             :             WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
     867          69 :                "MATRIX_INFO| Number row processes:", grid_2D(1)
     868             :             WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
     869          69 :                "MATRIX_INFO| Number column processes:", grid_2D(2)
     870             :          END IF
     871             : 
     872             :          ! define the block_size for the row
     873         272 :          IF (ext_row_block_size > 0) THEN
     874           0 :             nrow_block_mat = ext_row_block_size
     875             :          ELSE
     876         272 :             nrow_block_mat = MAX(1, dimen_RI/grid_2D(1)/2)
     877             :          END IF
     878             : 
     879             :          ! define the block_size for the column
     880         272 :          IF (ext_col_block_size > 0) THEN
     881           0 :             ncol_block_mat = ext_col_block_size
     882             :          ELSE
     883         272 :             ncol_block_mat = MAX(1, dimen_ia_for_block_size/grid_2D(2)/2)
     884             :          END IF
     885             : 
     886         272 :          IF (unit_nr > 0 .AND. .NOT. my_do_im_time) THEN
     887             :             WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
     888          69 :                "MATRIX_INFO| Row block size:", nrow_block_mat
     889             :             WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
     890          69 :                "MATRIX_INFO| Column block size:", ncol_block_mat
     891             :          END IF
     892             :       END IF
     893             : 
     894         287 :       IF (.NOT. my_do_im_time) THEN
     895         468 :          DO ispin = 1, SIZE(BIb_C_2D)
     896         248 :             NULLIFY (fm_struct)
     897         248 :             IF (my_blacs_ext) THEN
     898             :                CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=dimen_RI, &
     899          86 :                                         ncol_global=dimen_ia(ispin), para_env=para_env_RPA)
     900             :             ELSE
     901             :                CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=dimen_RI, &
     902             :                                         ncol_global=dimen_ia(ispin), para_env=para_env_RPA, &
     903         162 :                                         nrow_block=nrow_block_mat, ncol_block=ncol_block_mat, force_block=.TRUE.)
     904             : 
     905             :             END IF ! external blacs_env
     906             : 
     907         248 :             CALL create_group_dist(gd_ia, my_ia_start(ispin), my_ia_end(ispin), my_ia_size(ispin), para_env_RPA)
     908         248 :             CALL create_group_dist(gd_L, my_group_L_start, my_group_L_end, my_group_L_size, para_env_RPA)
     909             : 
     910             :             ! create the info array
     911             : 
     912         248 :             mepos_in_RPA_group = MOD(color_sub, integ_group_size)
     913         992 :             ALLOCATE (group_grid_2_mepos(0:integ_group_size - 1, 0:para_env_sub%num_pe - 1))
     914         872 :             group_grid_2_mepos = 0
     915         248 :             group_grid_2_mepos(mepos_in_RPA_group, para_env_sub%mepos) = para_env_RPA%mepos
     916         248 :             CALL para_env_RPA%sum(group_grid_2_mepos)
     917             : 
     918             :             CALL array2fm(BIb_C_2D(ispin)%array, fm_struct, my_group_L_start, my_group_L_end, &
     919             :                           my_ia_start(ispin), my_ia_end(ispin), gd_L, gd_ia, &
     920             :                           group_grid_2_mepos, ngroup, para_env_sub%num_pe, fm_mat_S(ispin), &
     921         248 :                           integ_group_size, color_rpa_group)
     922             : 
     923         248 :             DEALLOCATE (group_grid_2_mepos)
     924         248 :             CALL cp_fm_struct_release(fm_struct)
     925             : 
     926             :             ! deallocate the info array
     927         248 :             CALL release_group_dist(gd_L)
     928         248 :             CALL release_group_dist(gd_ia)
     929             : 
     930             :             ! sum the local data across processes belonging to different RPA group.
     931         468 :             IF (para_env_RPA%num_pe /= para_env%num_pe) THEN
     932             :                BLOCK
     933             :                   TYPE(mp_comm_type) :: comm_exchange
     934         130 :                   comm_exchange = fm_mat_S(ispin)%matrix_struct%context%interconnect(para_env)
     935         130 :                   CALL comm_exchange%sum(fm_mat_S(ispin)%local_data)
     936         260 :                   CALL comm_exchange%free()
     937             :                END BLOCK
     938             :             END IF
     939             :          END DO
     940             :       END IF
     941             : 
     942         354 :       IF (PRESENT(fm_mat_Q_gemm) .AND. .NOT. my_do_im_time) THEN
     943             :          ! create the Q matrix dimen_RIxdimen_RI where the result of the mat-mat-mult will be stored
     944         138 :          NULLIFY (fm_struct)
     945             :          CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=dimen_RI, &
     946             :                                   ncol_global=dimen_RI, para_env=para_env_RPA, &
     947         138 :                                   nrow_block=nrow_block_mat, ncol_block=ncol_block_mat, force_block=.TRUE.)
     948         300 :          DO ispin = 1, SIZE(fm_mat_Q_gemm)
     949         300 :             CALL cp_fm_create(fm_mat_Q_gemm(ispin), fm_struct, name="fm_mat_Q_gemm")
     950             :          END DO
     951         138 :          CALL cp_fm_struct_release(fm_struct)
     952             :       END IF
     953             : 
     954         354 :       IF (PRESENT(fm_mat_Q)) THEN
     955         318 :          NULLIFY (blacs_env_Q)
     956         318 :          IF (my_blacs_ext) THEN
     957          46 :             blacs_env_Q => blacs_env_ext
     958         272 :          ELSE IF (para_env_RPA%num_pe == para_env%num_pe .AND. PRESENT(qs_env)) THEN
     959         190 :             CALL get_qs_env(qs_env, blacs_env=blacs_env_Q)
     960             :          ELSE
     961          82 :             CALL cp_blacs_env_create(blacs_env=blacs_env_Q, para_env=para_env_RPA)
     962             :          END IF
     963         318 :          NULLIFY (fm_struct)
     964             :          CALL cp_fm_struct_create(fm_struct, context=blacs_env_Q, nrow_global=dimen_RI, &
     965         318 :                                   ncol_global=dimen_RI, para_env=para_env_RPA)
     966         690 :          DO ispin = 1, SIZE(fm_mat_Q)
     967         690 :             CALL cp_fm_create(fm_mat_Q(ispin), fm_struct, name="fm_mat_Q")
     968             :          END DO
     969             : 
     970         318 :          CALL cp_fm_struct_release(fm_struct)
     971             : 
     972         318 :          IF (.NOT. (my_blacs_ext .OR. (para_env_RPA%num_pe == para_env%num_pe .AND. PRESENT(qs_env)))) &
     973          82 :             CALL cp_blacs_env_release(blacs_env_Q)
     974             :       END IF
     975             : 
     976             :       ! release blacs_env
     977         354 :       IF (.NOT. my_blacs_S_ext) CALL cp_blacs_env_release(blacs_env)
     978             : 
     979         354 :       CALL timestop(handle)
     980             : 
     981         354 :    END SUBROUTINE create_integ_mat
     982             : 
     983             : ! **************************************************************************************************
     984             : !> \brief ...
     985             : !> \param qs_env ...
     986             : !> \param Erpa ...
     987             : !> \param mp2_env ...
     988             : !> \param para_env ...
     989             : !> \param para_env_RPA ...
     990             : !> \param para_env_sub ...
     991             : !> \param unit_nr ...
     992             : !> \param homo ...
     993             : !> \param virtual ...
     994             : !> \param dimen_RI ...
     995             : !> \param dimen_RI_red ...
     996             : !> \param dimen_ia ...
     997             : !> \param dimen_nm_gw ...
     998             : !> \param Eigenval ...
     999             : !> \param num_integ_points ...
    1000             : !> \param num_integ_group ...
    1001             : !> \param color_rpa_group ...
    1002             : !> \param fm_matrix_PQ ...
    1003             : !> \param fm_mat_S ...
    1004             : !> \param fm_mat_Q_gemm ...
    1005             : !> \param fm_mat_Q ...
    1006             : !> \param fm_mat_S_gw ...
    1007             : !> \param fm_mat_R_gw ...
    1008             : !> \param fm_mat_S_ij_bse ...
    1009             : !> \param fm_mat_S_ab_bse ...
    1010             : !> \param my_do_gw ...
    1011             : !> \param do_bse ...
    1012             : !> \param gw_corr_lev_occ ...
    1013             : !> \param gw_corr_lev_virt ...
    1014             : !> \param bse_lev_virt ...
    1015             : !> \param do_minimax_quad ...
    1016             : !> \param do_im_time ...
    1017             : !> \param mo_coeff ...
    1018             : !> \param fm_matrix_L_kpoints ...
    1019             : !> \param fm_matrix_Minv_L_kpoints ...
    1020             : !> \param fm_matrix_Minv ...
    1021             : !> \param fm_matrix_Minv_Vtrunc_Minv ...
    1022             : !> \param mat_munu ...
    1023             : !> \param mat_P_global ...
    1024             : !> \param t_3c_M ...
    1025             : !> \param t_3c_O ...
    1026             : !> \param t_3c_O_compressed ...
    1027             : !> \param t_3c_O_ind ...
    1028             : !> \param starts_array_mc ...
    1029             : !> \param ends_array_mc ...
    1030             : !> \param starts_array_mc_block ...
    1031             : !> \param ends_array_mc_block ...
    1032             : !> \param matrix_s ...
    1033             : !> \param do_kpoints_from_Gamma ...
    1034             : !> \param kpoints ...
    1035             : !> \param gd_array ...
    1036             : !> \param color_sub ...
    1037             : !> \param do_ri_sos_laplace_mp2 ...
    1038             : !> \param calc_forces ...
    1039             : ! **************************************************************************************************
    1040         272 :    SUBROUTINE rpa_num_int(qs_env, Erpa, mp2_env, para_env, para_env_RPA, para_env_sub, unit_nr, &
    1041         272 :                           homo, virtual, dimen_RI, dimen_RI_red, dimen_ia, dimen_nm_gw, &
    1042             :                           Eigenval, num_integ_points, num_integ_group, color_rpa_group, &
    1043         544 :                           fm_matrix_PQ, fm_mat_S, fm_mat_Q_gemm, fm_mat_Q, fm_mat_S_gw, fm_mat_R_gw, &
    1044             :                           fm_mat_S_ij_bse, fm_mat_S_ab_bse, &
    1045         272 :                           my_do_gw, do_bse, gw_corr_lev_occ, gw_corr_lev_virt, &
    1046             :                           bse_lev_virt, &
    1047         272 :                           do_minimax_quad, do_im_time, mo_coeff, &
    1048             :                           fm_matrix_L_kpoints, fm_matrix_Minv_L_kpoints, &
    1049             :                           fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, mat_munu, mat_P_global, &
    1050             :                           t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
    1051             :                           starts_array_mc, ends_array_mc, &
    1052             :                           starts_array_mc_block, ends_array_mc_block, &
    1053             :                           matrix_s, do_kpoints_from_Gamma, kpoints, gd_array, color_sub, &
    1054             :                           do_ri_sos_laplace_mp2, calc_forces)
    1055             : 
    1056             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1057             :       REAL(KIND=dp), INTENT(OUT)                         :: Erpa
    1058             :       TYPE(mp2_type)                                     :: mp2_env
    1059             :       TYPE(mp_para_env_type), POINTER                    :: para_env, para_env_RPA, para_env_sub
    1060             :       INTEGER, INTENT(IN)                                :: unit_nr
    1061             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: homo, virtual
    1062             :       INTEGER, INTENT(IN)                                :: dimen_RI, dimen_RI_red
    1063             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: dimen_ia
    1064             :       INTEGER, INTENT(IN)                                :: dimen_nm_gw
    1065             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
    1066             :          INTENT(INOUT)                                   :: Eigenval
    1067             :       INTEGER, INTENT(IN)                                :: num_integ_points, num_integ_group, &
    1068             :                                                             color_rpa_group
    1069             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_matrix_PQ
    1070             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT)      :: fm_mat_S
    1071             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: fm_mat_Q_gemm, fm_mat_Q, fm_mat_S_gw
    1072             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mat_R_gw, fm_mat_S_ij_bse, &
    1073             :                                                             fm_mat_S_ab_bse
    1074             :       LOGICAL, INTENT(IN)                                :: my_do_gw, do_bse
    1075             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: gw_corr_lev_occ, gw_corr_lev_virt
    1076             :       INTEGER, INTENT(IN)                                :: bse_lev_virt
    1077             :       LOGICAL, INTENT(IN)                                :: do_minimax_quad, do_im_time
    1078             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: mo_coeff
    1079             :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :)     :: fm_matrix_L_kpoints, &
    1080             :                                                             fm_matrix_Minv_L_kpoints, &
    1081             :                                                             fm_matrix_Minv, &
    1082             :                                                             fm_matrix_Minv_Vtrunc_Minv
    1083             :       TYPE(dbcsr_p_type), INTENT(IN)                     :: mat_munu
    1084             :       TYPE(dbcsr_p_type), INTENT(INOUT)                  :: mat_P_global
    1085             :       TYPE(dbt_type), INTENT(INOUT)                      :: t_3c_M
    1086             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :), &
    1087             :          INTENT(INOUT)                                   :: t_3c_O
    1088             :       TYPE(hfx_compression_type), ALLOCATABLE, &
    1089             :          DIMENSION(:, :, :), INTENT(INOUT)               :: t_3c_O_compressed
    1090             :       TYPE(block_ind_type), ALLOCATABLE, &
    1091             :          DIMENSION(:, :, :), INTENT(INOUT)               :: t_3c_O_ind
    1092             :       INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(IN)     :: starts_array_mc, ends_array_mc, &
    1093             :                                                             starts_array_mc_block, &
    1094             :                                                             ends_array_mc_block
    1095             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
    1096             :       LOGICAL                                            :: do_kpoints_from_Gamma
    1097             :       TYPE(kpoint_type), POINTER                         :: kpoints
    1098             :       TYPE(group_dist_d1_type), INTENT(IN)               :: gd_array
    1099             :       INTEGER, INTENT(IN)                                :: color_sub
    1100             :       LOGICAL, INTENT(IN)                                :: do_ri_sos_laplace_mp2, calc_forces
    1101             : 
    1102             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'rpa_num_int'
    1103             : 
    1104             :       COMPLEX(KIND=dp), ALLOCATABLE, &
    1105         272 :          DIMENSION(:, :, :, :)                           :: vec_Sigma_c_gw
    1106             :       INTEGER :: count_ev_sc_GW, cut_memory, group_size_P, gw_corr_lev_tot, handle, handle3, i, &
    1107             :          ikp_local, ispin, iter_evGW, iter_sc_GW0, j, jquad, min_bsize, mm_style, nkp, &
    1108             :          nkp_self_energy, nmo, nspins, num_3c_repl, num_cells_dm, num_fit_points, Pspin, Qspin, &
    1109             :          size_P
    1110             :       INTEGER(int_8)                                     :: dbcsr_nflop
    1111         272 :       INTEGER, ALLOCATABLE, DIMENSION(:, :)              :: index_to_cell_3c
    1112         272 :       INTEGER, ALLOCATABLE, DIMENSION(:, :, :)           :: cell_to_index_3c
    1113         544 :       INTEGER, DIMENSION(:), POINTER                     :: col_blk_size, prim_blk_sizes, &
    1114         272 :                                                             RI_blk_sizes
    1115             :       LOGICAL :: do_apply_ic_corr_to_gw, do_gw_im_time, do_ic_model, do_kpoints_cubic_RPA, &
    1116             :          do_periodic, do_print, do_ri_Sigma_x, exit_ev_gw, first_cycle, &
    1117             :          first_cycle_periodic_correction, my_open_shell, print_ic_values
    1118         272 :       LOGICAL, ALLOCATABLE, DIMENSION(:, :, :, :, :)     :: has_mat_P_blocks
    1119             :       REAL(KIND=dp) :: a_scaling, alpha, dbcsr_time, e_exchange, e_exchange_corr, eps_filter, &
    1120             :          eps_filter_im_time, ext_scaling, fermi_level_offset, fermi_level_offset_input, &
    1121             :          my_flop_rate, omega, omega_max_fit, omega_old, tau, tau_old
    1122         544 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: delta_corr, e_fermi, tau_tj, tau_wj, tj, &
    1123         272 :                                                             trace_Qomega, vec_omega_fit_gw, wj, &
    1124         272 :                                                             wkp_W
    1125         272 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: vec_W_gw, weights_cos_tf_t_to_w, &
    1126         272 :                                                             weights_cos_tf_w_to_t, &
    1127         272 :                                                             weights_sin_tf_t_to_w
    1128         272 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: Eigenval_last, Eigenval_scf, &
    1129         272 :                                                             vec_Sigma_x_gw
    1130             :       TYPE(cp_cfm_type)                                  :: cfm_mat_Q
    1131             :       TYPE(cp_fm_type) :: fm_mat_Q_static_bse_gemm, fm_mat_RI_global_work, fm_mat_S_ia_bse, &
    1132             :          fm_mat_work, fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, fm_scaled_dm_occ_tau, &
    1133             :          fm_scaled_dm_virt_tau
    1134         272 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:)        :: fm_mat_S_gw_work, fm_mat_W, &
    1135         272 :                                                             fm_mo_coeff_occ, fm_mo_coeff_virt
    1136         272 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :)     :: fm_mat_L_kpoints, fm_mat_Minv_L_kpoints
    1137             :       TYPE(dbcsr_p_type)                                 :: mat_dm, mat_L, mat_M_P_munu_occ, &
    1138             :                                                             mat_M_P_munu_virt, mat_MinvVMinv
    1139             :       TYPE(dbcsr_p_type), ALLOCATABLE, &
    1140         272 :          DIMENSION(:, :, :)                              :: mat_P_omega
    1141         272 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_berry_im_mo_mo, &
    1142         272 :                                                             matrix_berry_re_mo_mo
    1143         272 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: mat_P_omega_kp
    1144             :       TYPE(dbcsr_type), POINTER                          :: mat_W, mat_work
    1145        1904 :       TYPE(dbt_type)                                     :: t_3c_overl_int_ao_mo
    1146         272 :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: t_3c_overl_int_gw_AO, &
    1147         272 :                                                             t_3c_overl_int_gw_RI, &
    1148         272 :                                                             t_3c_overl_nnP_ic, &
    1149         272 :                                                             t_3c_overl_nnP_ic_reflected
    1150             :       TYPE(dgemm_counter_type)                           :: dgemm_counter
    1151             :       TYPE(hfx_compression_type), ALLOCATABLE, &
    1152         272 :          DIMENSION(:)                                    :: t_3c_O_mo_compressed
    1153       20128 :       TYPE(im_time_force_type)                           :: force_data
    1154         272 :       TYPE(rpa_exchange_work_type)                       :: exchange_work
    1155        1360 :       TYPE(rpa_grad_type)                                :: rpa_grad
    1156         272 :       TYPE(two_dim_int_array), ALLOCATABLE, DIMENSION(:) :: t_3c_O_mo_ind
    1157             : 
    1158         272 :       CALL timeset(routineN, handle)
    1159             : 
    1160         272 :       nspins = SIZE(homo)
    1161         272 :       nmo = homo(1) + virtual(1)
    1162         272 :       my_open_shell = (nspins == 2)
    1163             : 
    1164         272 :       do_gw_im_time = my_do_gw .AND. do_im_time
    1165         272 :       do_ri_Sigma_x = mp2_env%ri_g0w0%do_ri_Sigma_x
    1166         272 :       do_ic_model = mp2_env%ri_g0w0%do_ic_model
    1167         272 :       print_ic_values = mp2_env%ri_g0w0%print_ic_values
    1168         272 :       do_periodic = mp2_env%ri_g0w0%do_periodic
    1169         272 :       do_kpoints_cubic_RPA = mp2_env%ri_rpa_im_time%do_im_time_kpoints
    1170             : 
    1171             :       ! For SOS-MP2 only gemm is implemented
    1172         272 :       mm_style = wfc_mm_style_gemm
    1173         272 :       IF (.NOT. do_ri_sos_laplace_mp2) mm_style = mp2_env%ri_rpa%mm_style
    1174             : 
    1175         272 :       IF (my_do_gw) THEN
    1176          92 :          ext_scaling = 0.2_dp
    1177          92 :          omega_max_fit = mp2_env%ri_g0w0%omega_max_fit
    1178          92 :          fermi_level_offset_input = mp2_env%ri_g0w0%fermi_level_offset
    1179          92 :          iter_evGW = mp2_env%ri_g0w0%iter_evGW
    1180          92 :          iter_sc_GW0 = mp2_env%ri_g0w0%iter_sc_GW0
    1181          92 :          IF ((.NOT. do_im_time)) THEN
    1182          46 :             IF (iter_sc_GW0 .NE. 1 .AND. iter_evGW .NE. 1) CPABORT("Mixed scGW0/evGW not implemented.")
    1183             :             ! in case of scGW0 with the N^4 algorithm, we use the evGW code but use the DFT eigenvalues for W
    1184          46 :             IF (iter_sc_GW0 .NE. 1) iter_evGW = iter_sc_GW0
    1185             :          END IF
    1186             :       ELSE
    1187         180 :          ext_scaling = 0.0_dp
    1188         180 :          iter_evGW = 1
    1189         180 :          iter_sc_GW0 = 1
    1190             :       END IF
    1191             : 
    1192         272 :       IF (do_kpoints_cubic_RPA .AND. do_ri_sos_laplace_mp2) THEN
    1193           0 :          CPABORT("RI-SOS-Laplace-MP2 with k-point-sampling is not implemented.")
    1194             :       END IF
    1195             : 
    1196         272 :       do_apply_ic_corr_to_gw = .FALSE.
    1197         272 :       IF (mp2_env%ri_g0w0%ic_corr_list(1)%array(1) > 0.0_dp) do_apply_ic_corr_to_gw = .TRUE.
    1198             : 
    1199         272 :       IF (do_im_time) THEN
    1200         134 :          CPASSERT(do_minimax_quad .OR. do_ri_sos_laplace_mp2)
    1201             : 
    1202         134 :          group_size_P = mp2_env%ri_rpa_im_time%group_size_P
    1203         134 :          cut_memory = mp2_env%ri_rpa_im_time%cut_memory
    1204         134 :          eps_filter = mp2_env%ri_rpa_im_time%eps_filter
    1205             :          eps_filter_im_time = mp2_env%ri_rpa_im_time%eps_filter* &
    1206         134 :                               mp2_env%ri_rpa_im_time%eps_filter_factor
    1207             : 
    1208         134 :          min_bsize = mp2_env%ri_rpa_im_time%min_bsize
    1209             : 
    1210             :          CALL alloc_im_time(qs_env, para_env, dimen_RI, dimen_RI_red, &
    1211             :                             num_integ_points, nspins, fm_mat_Q(1), fm_mo_coeff_occ, fm_mo_coeff_virt, &
    1212             :                             fm_matrix_Minv_L_kpoints, fm_matrix_L_kpoints, mat_P_global, &
    1213             :                             t_3c_O, matrix_s, kpoints, eps_filter_im_time, &
    1214             :                             cut_memory, nkp, num_cells_dm, num_3c_repl, &
    1215             :                             size_P, ikp_local, &
    1216             :                             index_to_cell_3c, &
    1217             :                             cell_to_index_3c, &
    1218             :                             col_blk_size, &
    1219             :                             do_ic_model, do_kpoints_cubic_RPA, &
    1220             :                             do_kpoints_from_Gamma, do_ri_Sigma_x, my_open_shell, &
    1221             :                             has_mat_P_blocks, wkp_W, &
    1222             :                             cfm_mat_Q, fm_mat_Minv_L_kpoints, fm_mat_L_kpoints, &
    1223             :                             fm_mat_RI_global_work, fm_mat_work, fm_mo_coeff_occ_scaled, &
    1224             :                             fm_mo_coeff_virt_scaled, mat_dm, mat_L, mat_M_P_munu_occ, mat_M_P_munu_virt, &
    1225             :                             mat_MinvVMinv, mat_P_omega, mat_P_omega_kp, mat_work, mo_coeff, &
    1226         134 :                             fm_scaled_dm_occ_tau, fm_scaled_dm_virt_tau, homo, nmo)
    1227             : 
    1228         134 :          IF (calc_forces) CALL init_im_time_forces(force_data, fm_matrix_PQ, t_3c_M, unit_nr, mp2_env, qs_env)
    1229             : 
    1230         134 :          IF (my_do_gw) THEN
    1231             : 
    1232             :             CALL dbcsr_get_info(mat_P_global%matrix, &
    1233          46 :                                 row_blk_size=RI_blk_sizes)
    1234             : 
    1235             :             CALL dbcsr_get_info(matrix_s(1)%matrix, &
    1236          46 :                                 row_blk_size=prim_blk_sizes)
    1237             : 
    1238          46 :             gw_corr_lev_tot = gw_corr_lev_occ(1) + gw_corr_lev_virt(1)
    1239             : 
    1240          46 :             IF (.NOT. do_kpoints_cubic_RPA) THEN
    1241             :                CALL allocate_matrices_gw_im_time(gw_corr_lev_occ, gw_corr_lev_virt, homo, nmo, &
    1242             :                                                  num_integ_points, unit_nr, &
    1243             :                                                  RI_blk_sizes, do_ic_model, &
    1244             :                                                  para_env, fm_mat_W, fm_mat_Q(1), &
    1245             :                                                  mo_coeff, &
    1246             :                                                  t_3c_overl_int_ao_mo, t_3c_O_mo_compressed, t_3c_O_mo_ind, &
    1247             :                                                  t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
    1248             :                                                  starts_array_mc, ends_array_mc, &
    1249             :                                                  t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected, &
    1250             :                                                  matrix_s, mat_W, t_3c_O, &
    1251             :                                                  t_3c_O_compressed, t_3c_O_ind, &
    1252          46 :                                                  qs_env)
    1253             : 
    1254             :             END IF
    1255             :          END IF
    1256             : 
    1257             :       END IF
    1258             : 
    1259         272 :       IF (do_ic_model) THEN
    1260             :          ! image charge model only implemented for cubic scaling GW
    1261           2 :          CPASSERT(do_gw_im_time)
    1262           2 :          CPASSERT(.NOT. do_periodic)
    1263           2 :          IF (cut_memory .NE. 1) CPABORT("For IC, use MEMORY_CUT 1 in the LOW_SCALING section.")
    1264             :       END IF
    1265             : 
    1266         816 :       ALLOCATE (e_fermi(nspins))
    1267         272 :       IF (do_minimax_quad .OR. do_ri_sos_laplace_mp2) THEN
    1268         194 :          do_print = .NOT. do_ic_model
    1269             :          CALL get_minimax_grid(para_env, unit_nr, homo, Eigenval, num_integ_points, do_im_time, &
    1270             :                                do_ri_sos_laplace_mp2, do_print, &
    1271             :                                tau_tj, tau_wj, qs_env, do_gw_im_time, &
    1272             :                                do_kpoints_cubic_RPA, e_fermi(1), tj, wj, &
    1273             :                                weights_cos_tf_t_to_w, weights_cos_tf_w_to_t, weights_sin_tf_t_to_w, &
    1274         194 :                                qs_env%mp2_env%ri_g0w0%regularization_minimax)
    1275             : 
    1276             :          !For sos_laplace_mp2 and low-scaling RPA, potentially need to store/retrieve the initial weights
    1277         194 :          IF (qs_env%mp2_env%ri_rpa_im_time%keep_quad) THEN
    1278             :             CALL keep_initial_quad(tj, wj, tau_tj, tau_wj, weights_cos_tf_t_to_w, &
    1279             :                                    weights_cos_tf_w_to_t, do_ri_sos_laplace_mp2, do_im_time, &
    1280         194 :                                    num_integ_points, unit_nr, qs_env)
    1281             :          END IF
    1282             :       ELSE
    1283          78 :          IF (calc_forces) CPABORT("Forces with Clenshaw-Curtis grid not implemented.")
    1284             :          CALL get_clenshaw_grid(para_env, para_env_RPA, unit_nr, homo, virtual, Eigenval, num_integ_points, &
    1285             :                                 num_integ_group, color_rpa_group, fm_mat_S, my_do_gw, &
    1286          78 :                                 ext_scaling, a_scaling, tj, wj)
    1287             :       END IF
    1288             : 
    1289             :       ! This array is needed for RPA
    1290         272 :       IF (.NOT. do_ri_sos_laplace_mp2) THEN
    1291         642 :          ALLOCATE (trace_Qomega(dimen_RI_red))
    1292             :       END IF
    1293             : 
    1294         272 :       IF (do_ri_sos_laplace_mp2 .AND. .NOT. do_im_time) THEN
    1295          28 :          alpha = 1.0_dp
    1296         244 :       ELSE IF (my_open_shell .OR. do_ri_sos_laplace_mp2) THEN
    1297          68 :          alpha = 2.0_dp
    1298             :       ELSE
    1299         176 :          alpha = 4.0_dp
    1300             :       END IF
    1301             : 
    1302         272 :       IF (my_do_gw) THEN
    1303             :          CALL allocate_matrices_gw(vec_Sigma_c_gw, color_rpa_group, dimen_nm_gw, &
    1304             :                                    gw_corr_lev_occ, gw_corr_lev_virt, homo, &
    1305             :                                    nmo, num_integ_group, num_integ_points, unit_nr, &
    1306             :                                    gw_corr_lev_tot, num_fit_points, omega_max_fit, &
    1307             :                                    do_minimax_quad, do_periodic, do_ri_Sigma_x,.NOT. do_im_time, &
    1308             :                                    first_cycle_periodic_correction, &
    1309             :                                    a_scaling, Eigenval, tj, vec_omega_fit_gw, vec_Sigma_x_gw, &
    1310             :                                    delta_corr, Eigenval_last, Eigenval_scf, vec_W_gw, &
    1311             :                                    fm_mat_S_gw, fm_mat_S_gw_work, &
    1312             :                                    para_env, mp2_env, kpoints, nkp, nkp_self_energy, &
    1313          92 :                                    do_kpoints_cubic_RPA, do_kpoints_from_Gamma)
    1314             : 
    1315          92 :          IF (do_bse) THEN
    1316             : 
    1317          18 :             CALL cp_fm_create(fm_mat_Q_static_bse_gemm, fm_mat_Q_gemm(1)%matrix_struct)
    1318          18 :             CALL cp_fm_to_fm(fm_mat_Q_gemm(1), fm_mat_Q_static_bse_gemm)
    1319          18 :             CALL cp_fm_set_all(fm_mat_Q_static_bse_gemm, 0.0_dp)
    1320             : 
    1321             :          END IF
    1322             : 
    1323             :       END IF
    1324             : 
    1325         272 :       IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_create(rpa_grad, fm_mat_Q(1), &
    1326             :                                                                    fm_mat_S, homo, virtual, mp2_env, Eigenval(:, 1, :), &
    1327          40 :                                                                    unit_nr, do_ri_sos_laplace_mp2)
    1328             : 
    1329         272 :       IF (.NOT. do_im_time .AND. .NOT. do_ri_sos_laplace_mp2) &
    1330             :          CALL exchange_work%create(qs_env, para_env_sub, mat_munu, dimen_RI_red, &
    1331         110 :                                    fm_mat_S, fm_mat_Q(1), fm_mat_Q_gemm(1), homo, virtual)
    1332             : 
    1333         272 :       Erpa = 0.0_dp
    1334         272 :       IF (mp2_env%ri_rpa%exchange_correction /= rpa_exchange_none) e_exchange = 0.0_dp
    1335         272 :       first_cycle = .TRUE.
    1336         272 :       omega_old = 0.0_dp
    1337         272 :       CALL dgemm_counter_init(dgemm_counter, unit_nr, mp2_env%ri_rpa%print_dgemm_info)
    1338             : 
    1339         642 :       DO count_ev_sc_GW = 1, iter_evGW
    1340             : 
    1341         386 :          dbcsr_time = 0.0_dp
    1342         386 :          dbcsr_nflop = 0
    1343             : 
    1344         386 :          IF (do_ic_model) CYCLE
    1345             : 
    1346             :          ! reset some values, important when doing eigenvalue self-consistent GW
    1347         384 :          IF (my_do_gw) THEN
    1348         204 :             Erpa = 0.0_dp
    1349      115390 :             vec_Sigma_c_gw = z_zero
    1350         204 :             first_cycle = .TRUE.
    1351             :          END IF
    1352             : 
    1353             :          ! calculate Q_PQ(it)
    1354         384 :          IF (do_im_time) THEN
    1355             : 
    1356         146 :             IF (.NOT. do_kpoints_cubic_RPA) THEN
    1357         314 :                DO ispin = 1, nspins
    1358         314 :                   e_fermi(ispin) = (Eigenval(homo(ispin), 1, ispin) + Eigenval(homo(ispin) + 1, 1, ispin))*0.5_dp
    1359             :                END DO
    1360             :             END IF
    1361             : 
    1362         146 :             tau = 0.0_dp
    1363         146 :             tau_old = 0.0_dp
    1364             : 
    1365         146 :             IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(/T3,A,T66,i15)") &
    1366          73 :                "MEMORY_INFO| Memory cut:", cut_memory
    1367         146 :             IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T66,ES15.2)") &
    1368          73 :                "SPARSITY_INFO| Eps filter for M virt/occ tensors:", eps_filter
    1369         146 :             IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T66,ES15.2)") &
    1370          73 :                "SPARSITY_INFO| Eps filter for P matrix:", eps_filter_im_time
    1371         146 :             IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T66,i15)") &
    1372          73 :                "SPARSITY_INFO| Minimum tensor block size:", min_bsize
    1373             : 
    1374             :             ! for evGW, we have to ensure that mat_P_omega is zero
    1375         146 :             CALL zero_mat_P_omega(mat_P_omega(:, :, 1))
    1376             : 
    1377             :             ! compute the matrix Q(it) and Fourier transform it directly to mat_P_omega(iw)
    1378             :             CALL compute_mat_P_omega(mat_P_omega(:, :, 1), fm_scaled_dm_occ_tau, &
    1379             :                                      fm_scaled_dm_virt_tau, fm_mo_coeff_occ(1), fm_mo_coeff_virt(1), &
    1380             :                                      fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
    1381             :                                      mat_P_global, matrix_s, 1, &
    1382             :                                      t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
    1383             :                                      starts_array_mc, ends_array_mc, &
    1384             :                                      starts_array_mc_block, ends_array_mc_block, &
    1385             :                                      weights_cos_tf_t_to_w, tj, tau_tj, e_fermi(1), eps_filter, alpha, &
    1386             :                                      eps_filter_im_time, Eigenval(:, 1, 1), nmo, &
    1387             :                                      num_integ_points, cut_memory, &
    1388             :                                      unit_nr, mp2_env, para_env, &
    1389             :                                      qs_env, do_kpoints_from_Gamma, &
    1390             :                                      index_to_cell_3c, cell_to_index_3c, &
    1391             :                                      has_mat_P_blocks, do_ri_sos_laplace_mp2, &
    1392         146 :                                      dbcsr_time, dbcsr_nflop)
    1393             : 
    1394             :             ! the same for open shell, use fm_mo_coeff_occ_beta and fm_mo_coeff_virt_beta
    1395         146 :             IF (my_open_shell) THEN
    1396          30 :                CALL zero_mat_P_omega(mat_P_omega(:, :, 2))
    1397             :                CALL compute_mat_P_omega(mat_P_omega(:, :, 2), fm_scaled_dm_occ_tau, &
    1398             :                                         fm_scaled_dm_virt_tau, fm_mo_coeff_occ(2), &
    1399             :                                         fm_mo_coeff_virt(2), &
    1400             :                                         fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
    1401             :                                         mat_P_global, matrix_s, 2, &
    1402             :                                         t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
    1403             :                                         starts_array_mc, ends_array_mc, &
    1404             :                                         starts_array_mc_block, ends_array_mc_block, &
    1405             :                                         weights_cos_tf_t_to_w, tj, tau_tj, e_fermi(2), eps_filter, alpha, &
    1406             :                                         eps_filter_im_time, Eigenval(:, 1, 2), nmo, &
    1407             :                                         num_integ_points, cut_memory, &
    1408             :                                         unit_nr, mp2_env, para_env, &
    1409             :                                         qs_env, do_kpoints_from_Gamma, &
    1410             :                                         index_to_cell_3c, cell_to_index_3c, &
    1411             :                                         has_mat_P_blocks, do_ri_sos_laplace_mp2, &
    1412          30 :                                         dbcsr_time, dbcsr_nflop)
    1413             : 
    1414             :                !For RPA, we sum up the P matrices. If no force needed, can clean-up the beta spin one
    1415          30 :                IF (.NOT. do_ri_sos_laplace_mp2) THEN
    1416         144 :                   DO j = 1, SIZE(mat_P_omega, 2)
    1417         928 :                      DO i = 1, SIZE(mat_P_omega, 1)
    1418         784 :                         CALL dbcsr_add(mat_P_omega(i, j, 1)%matrix, mat_P_omega(i, j, 2)%matrix, 1.0_dp, 1.0_dp)
    1419         906 :                         IF (.NOT. calc_forces) CALL dbcsr_clear(mat_P_omega(i, j, 2)%matrix)
    1420             :                      END DO
    1421             :                   END DO
    1422             :                END IF
    1423             :             END IF ! my_open_shell
    1424             : 
    1425             :          END IF ! do im time
    1426             : 
    1427        9526 :          DO jquad = 1, num_integ_points
    1428             : 
    1429        9142 :             IF (MODULO(jquad, num_integ_group) /= color_rpa_group) CYCLE
    1430             : 
    1431        8532 :             CALL timeset(routineN//"_RPA_matrix_operations", handle3)
    1432             : 
    1433        8532 :             IF (do_ri_sos_laplace_mp2) THEN
    1434         206 :                omega = tau_tj(jquad)
    1435             :             ELSE
    1436        8326 :                IF (do_minimax_quad) THEN
    1437         928 :                   omega = tj(jquad)
    1438             :                ELSE
    1439        7398 :                   omega = a_scaling/TAN(tj(jquad))
    1440             :                END IF
    1441             :             END IF ! do_ri_sos_laplace_mp2
    1442             : 
    1443        8532 :             IF (do_im_time) THEN
    1444             :                ! in case we do imag time, we already calculated fm_mat_Q by a Fourier transform from im. time
    1445             : 
    1446         928 :                IF (.NOT. (do_kpoints_cubic_RPA .OR. do_kpoints_from_Gamma)) THEN
    1447             : 
    1448        1784 :                   DO ispin = 1, SIZE(mat_P_omega, 3)
    1449             :                      CALL contract_P_omega_with_mat_L(mat_P_omega(jquad, 1, ispin)%matrix, mat_L%matrix, mat_work, &
    1450             :                                                       eps_filter_im_time, fm_mat_work, dimen_RI, dimen_RI_red, &
    1451        1784 :                                                       fm_mat_Minv_L_kpoints(1, 1), fm_mat_Q(ispin))
    1452             :                   END DO
    1453             :                END IF
    1454             : 
    1455             :             ELSE
    1456             : 
    1457        7604 :                IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3, A, 1X, I3, 1X, A, 1X, I3)") &
    1458        3802 :                   "INTEG_INFO| Started with Integration point", jquad, "of", num_integ_points
    1459             : 
    1460        7604 :                IF (first_cycle .AND. count_ev_sc_gw > 1) THEN
    1461         100 :                   IF (iter_sc_gw0 == 1) THEN
    1462         140 :                      DO ispin = 1, nspins
    1463             :                         CALL remove_scaling_factor_rpa(fm_mat_S(ispin), virtual(ispin), &
    1464         140 :                                                        Eigenval_last(:, 1, ispin), homo(ispin), omega_old)
    1465             :                      END DO
    1466             :                   ELSE
    1467          68 :                      DO ispin = 1, nspins
    1468             :                         CALL remove_scaling_factor_rpa(fm_mat_S(ispin), virtual(ispin), &
    1469          68 :                                                        Eigenval_scf(:, 1, ispin), homo(ispin), omega_old)
    1470             :                      END DO
    1471             :                   END IF
    1472             :                END IF
    1473             : 
    1474        7604 :                IF (iter_sc_GW0 > 1) THEN
    1475        6140 :                DO ispin = 1, nspins
    1476             :                   CALL calc_mat_Q(fm_mat_S(ispin), do_ri_sos_laplace_mp2, first_cycle, virtual(ispin), &
    1477             :                                   Eigenval_scf(:, 1, ispin), homo(ispin), omega, omega_old, jquad, mm_style, &
    1478             :                                   dimen_RI_red, dimen_ia(ispin), alpha, fm_mat_Q(ispin), &
    1479             :                                   fm_mat_Q_gemm(ispin), do_bse, fm_mat_Q_static_bse_gemm, dgemm_counter, &
    1480        6140 :                                   num_integ_points, count_ev_sc_GW)
    1481             :                END DO
    1482             : 
    1483             :                ! For SOS-MP2 we need both matrices separately
    1484        3070 :                IF (.NOT. do_ri_sos_laplace_mp2) THEN
    1485        3070 :                DO ispin = 2, nspins
    1486        3070 :                   CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_mat_Q(1), beta=1.0_dp, matrix_b=fm_mat_Q(ispin))
    1487             :                END DO
    1488             :                END IF
    1489             :                ELSE
    1490        9220 :                DO ispin = 1, nspins
    1491             :                   CALL calc_mat_Q(fm_mat_S(ispin), do_ri_sos_laplace_mp2, first_cycle, virtual(ispin), &
    1492             :                                   Eigenval(:, 1, ispin), homo(ispin), omega, omega_old, jquad, mm_style, &
    1493             :                                   dimen_RI_red, dimen_ia(ispin), alpha, fm_mat_Q(ispin), &
    1494             :                                   fm_mat_Q_gemm(ispin), do_bse, fm_mat_Q_static_bse_gemm, dgemm_counter, &
    1495        9220 :                                   num_integ_points, count_ev_sc_GW)
    1496             :                END DO
    1497             : 
    1498             :                ! For SOS-MP2 we need both matrices separately
    1499        4534 :                IF (.NOT. do_ri_sos_laplace_mp2) THEN
    1500        4558 :                DO ispin = 2, nspins
    1501        4558 :                   CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_mat_Q(1), beta=1.0_dp, matrix_b=fm_mat_Q(ispin))
    1502             :                END DO
    1503             :                END IF
    1504             : 
    1505             :                END IF
    1506             : 
    1507             :             END IF ! im time
    1508             : 
    1509             :             ! Calculate RPA exchange energy correction
    1510        8532 :             IF (mp2_env%ri_rpa%exchange_correction /= rpa_exchange_none) THEN
    1511          12 :                e_exchange_corr = 0.0_dp
    1512          12 :                CALL exchange_work%compute(fm_mat_Q(1), Eigenval(:, 1, :), fm_mat_S, omega, e_exchange_corr, mp2_env)
    1513             : 
    1514             :                ! Evaluate the final exchange energy correction
    1515          12 :                e_exchange = e_exchange + e_exchange_corr*wj(jquad)
    1516             :             END IF
    1517             : 
    1518        8532 :             IF (do_ri_sos_laplace_mp2) THEN
    1519         206 :                CALL SOS_MP2_postprocessing(fm_mat_Q, Erpa, tau_wj(jquad))
    1520             : 
    1521         206 :                IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_matrix_operations(mp2_env, rpa_grad, do_ri_sos_laplace_mp2, &
    1522             :                                                            fm_mat_Q, fm_mat_Q_gemm, dgemm_counter, fm_mat_S, omega, homo, virtual, &
    1523          60 :                                                                                        Eigenval(:, 1, :), tau_wj(jquad), unit_nr)
    1524             :             ELSE
    1525        8326 :                IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_copy_Q(fm_mat_Q(1), rpa_grad)
    1526             : 
    1527        8326 :                CALL Q_trace_and_add_unit_matrix(dimen_RI_red, trace_Qomega, fm_mat_Q(1))
    1528             : 
    1529        8326 :                IF (do_kpoints_cubic_RPA .OR. do_kpoints_from_Gamma) THEN
    1530             :                   CALL invert_eps_compute_W_and_Erpa_kp(dimen_RI, num_integ_points, jquad, nkp, count_ev_sc_GW, para_env, &
    1531             :                                                         Erpa, tau_tj, tj, wj, weights_cos_tf_w_to_t, &
    1532             :                                                         wkp_W, do_gw_im_time, do_ri_Sigma_x, do_kpoints_from_Gamma, &
    1533             :                                                         cfm_mat_Q, ikp_local, &
    1534             :                                                         mat_P_omega(:, :, 1), mat_P_omega_kp, qs_env, eps_filter_im_time, unit_nr, &
    1535             :                                                         kpoints, fm_mat_Minv_L_kpoints, fm_mat_L_kpoints, &
    1536             :                                                         fm_mat_W, fm_mat_RI_global_work, mat_MinvVMinv, &
    1537         132 :                                                         fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv)
    1538             :                ELSE
    1539        8194 :                   CALL compute_Erpa_by_freq_int(dimen_RI_red, trace_Qomega, fm_mat_Q(1), para_env_RPA, Erpa, wj(jquad))
    1540             :                END IF
    1541             : 
    1542        8326 :                IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_matrix_operations(mp2_env, rpa_grad, do_ri_sos_laplace_mp2, &
    1543             :                                                            fm_mat_Q, fm_mat_Q_gemm, dgemm_counter, fm_mat_S, omega, homo, virtual, &
    1544          48 :                                                                                        Eigenval(:, 1, :), wj(jquad), unit_nr)
    1545             :             END IF ! do_ri_sos_laplace_mp2
    1546             : 
    1547             :             ! save omega and reset the first_cycle flag
    1548        8532 :             first_cycle = .FALSE.
    1549        8532 :             omega_old = omega
    1550             : 
    1551        8532 :             CALL timestop(handle3)
    1552             : 
    1553        8532 :             IF (my_do_gw) THEN
    1554             : 
    1555        7788 :                CALL get_fermi_level_offset(fermi_level_offset, fermi_level_offset_input, Eigenval(:, 1, :), homo)
    1556             : 
    1557             :                ! do_im_time = TRUE means low-scaling calculation
    1558        7788 :                IF (do_im_time) THEN
    1559             :                   ! only for molecules
    1560         578 :                   IF (.NOT. (do_kpoints_cubic_RPA .OR. do_kpoints_from_Gamma)) THEN
    1561             :                     CALL compute_W_cubic_GW(fm_mat_W, fm_mat_Q(1), fm_mat_work, dimen_RI, fm_mat_Minv_L_kpoints, num_integ_points, &
    1562         470 :                                              tj, tau_tj, weights_cos_tf_w_to_t, jquad, omega)
    1563             :                   END IF
    1564             :                ELSE
    1565             :                   CALL compute_GW_self_energy(vec_Sigma_c_gw, dimen_nm_gw, dimen_RI_red, gw_corr_lev_occ, &
    1566             :                                               gw_corr_lev_virt, homo, jquad, nmo, num_fit_points, &
    1567             :                                               do_im_time, do_periodic, first_cycle_periodic_correction, &
    1568             :                                               fermi_level_offset, &
    1569             :                                               omega, Eigenval(:, 1, :), delta_corr, vec_omega_fit_gw, vec_W_gw, wj, &
    1570             :                                               fm_mat_Q(1), fm_mat_R_gw, fm_mat_S_gw, &
    1571             :                                               fm_mat_S_gw_work, mo_coeff(1), para_env, &
    1572             :                                               para_env_RPA, matrix_berry_im_mo_mo, matrix_berry_re_mo_mo, &
    1573        7210 :                                               kpoints, qs_env, mp2_env)
    1574             :                END IF
    1575             :             END IF
    1576             : 
    1577        8532 :             IF (unit_nr > 0) CALL m_flush(unit_nr)
    1578       18058 :             CALL para_env%sync() ! sync to see output
    1579             : 
    1580             :          END DO ! jquad
    1581             : 
    1582         384 :          CALL para_env%sum(Erpa)
    1583             : 
    1584         384 :          IF (.NOT. do_ri_sos_laplace_mp2) THEN
    1585         326 :             Erpa = Erpa/(pi*2.0_dp)
    1586         326 :             IF (do_minimax_quad) Erpa = Erpa/2.0_dp
    1587             :          END IF
    1588             : 
    1589         384 :          IF (mp2_env%ri_rpa%exchange_correction /= rpa_exchange_none) THEN
    1590          12 :             CALL para_env%sum(E_exchange)
    1591          12 :             E_exchange = E_exchange/(pi*2.0_dp)
    1592          12 :             IF (do_minimax_quad) E_exchange = E_exchange/2.0_dp
    1593          12 :             mp2_env%ri_rpa%ener_exchange = E_exchange
    1594             :          END IF
    1595             : 
    1596         384 :          IF (calc_forces .AND. do_ri_sos_laplace_mp2 .AND. do_im_time) THEN
    1597          22 :             IF (my_open_shell) THEN
    1598           4 :                Pspin = 1
    1599           4 :                Qspin = 2
    1600             :                CALL calc_laplace_loop_forces(force_data, mat_P_omega(:, 1, :), t_3c_M, t_3c_O(1, 1), &
    1601             :                                              t_3c_O_compressed(1, 1, :), t_3c_O_ind(1, 1, :), fm_scaled_dm_occ_tau, &
    1602             :                                              fm_scaled_dm_virt_tau, fm_mo_coeff_occ, fm_mo_coeff_virt, &
    1603             :                                              fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
    1604             :                                              starts_array_mc, ends_array_mc, starts_array_mc_block, &
    1605             :                                              ends_array_mc_block, num_integ_points, nmo, Eigenval(:, 1, :), &
    1606             :                                              tau_tj, tau_wj, cut_memory, Pspin, Qspin, my_open_shell, &
    1607           4 :                                              unit_nr, dbcsr_time, dbcsr_nflop, mp2_env, qs_env)
    1608           4 :                Pspin = 2
    1609           4 :                Qspin = 1
    1610             :                CALL calc_laplace_loop_forces(force_data, mat_P_omega(:, 1, :), t_3c_M, t_3c_O(1, 1), &
    1611             :                                              t_3c_O_compressed(1, 1, :), t_3c_O_ind(1, 1, :), fm_scaled_dm_occ_tau, &
    1612             :                                              fm_scaled_dm_virt_tau, fm_mo_coeff_occ, fm_mo_coeff_virt, &
    1613             :                                              fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
    1614             :                                              starts_array_mc, ends_array_mc, starts_array_mc_block, &
    1615             :                                              ends_array_mc_block, num_integ_points, nmo, Eigenval(:, 1, :), &
    1616             :                                              tau_tj, tau_wj, cut_memory, Pspin, Qspin, my_open_shell, &
    1617           4 :                                              unit_nr, dbcsr_time, dbcsr_nflop, mp2_env, qs_env)
    1618             : 
    1619             :             ELSE
    1620          18 :                Pspin = 1
    1621          18 :                Qspin = 1
    1622             :                CALL calc_laplace_loop_forces(force_data, mat_P_omega(:, 1, :), t_3c_M, t_3c_O(1, 1), &
    1623             :                                              t_3c_O_compressed(1, 1, :), t_3c_O_ind(1, 1, :), fm_scaled_dm_occ_tau, &
    1624             :                                              fm_scaled_dm_virt_tau, fm_mo_coeff_occ, fm_mo_coeff_virt, &
    1625             :                                              fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
    1626             :                                              starts_array_mc, ends_array_mc, starts_array_mc_block, &
    1627             :                                              ends_array_mc_block, num_integ_points, nmo, Eigenval(:, 1, :), &
    1628             :                                              tau_tj, tau_wj, cut_memory, Pspin, Qspin, my_open_shell, &
    1629          18 :                                              unit_nr, dbcsr_time, dbcsr_nflop, mp2_env, qs_env)
    1630             :             END IF
    1631          22 :             CALL calc_post_loop_forces(force_data, unit_nr, qs_env)
    1632             :          END IF !laplace SOS-MP2
    1633             : 
    1634         384 :          IF (calc_forces .AND. do_im_time .AND. .NOT. do_ri_sos_laplace_mp2) THEN
    1635          64 :             DO ispin = 1, nspins
    1636             :                CALL calc_rpa_loop_forces(force_data, mat_P_omega(:, 1, :), t_3c_M, t_3c_O(1, 1), &
    1637             :                                          t_3c_O_compressed(1, 1, :), t_3c_O_ind(1, 1, :), fm_scaled_dm_occ_tau, &
    1638             :                                          fm_scaled_dm_virt_tau, fm_mo_coeff_occ, fm_mo_coeff_virt, &
    1639             :                                          fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
    1640             :                                          starts_array_mc, ends_array_mc, starts_array_mc_block, &
    1641             :                                          ends_array_mc_block, num_integ_points, nmo, Eigenval(:, 1, :), &
    1642             :                                          e_fermi(ispin), weights_cos_tf_t_to_w, weights_cos_tf_w_to_t, tj, &
    1643             :                                          wj, tau_tj, cut_memory, ispin, my_open_shell, unit_nr, dbcsr_time, &
    1644          64 :                                          dbcsr_nflop, mp2_env, qs_env)
    1645             :             END DO
    1646          28 :             CALL calc_post_loop_forces(force_data, unit_nr, qs_env)
    1647             :          END IF
    1648             : 
    1649         384 :          IF (do_im_time) THEN
    1650             : 
    1651         146 :             my_flop_rate = REAL(dbcsr_nflop, dp)/(1.0E09_dp*dbcsr_time)
    1652         146 :             IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(/T3,A,T73,ES8.2)") &
    1653          73 :                "PERFORMANCE| DBCSR total number of flops:", REAL(dbcsr_nflop*para_env%num_pe, dp)
    1654         146 :             IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T66,F15.2)") &
    1655          73 :                "PERFORMANCE| DBCSR total execution time:", dbcsr_time
    1656         146 :             IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T66,F15.2)") &
    1657          73 :                "PERFORMANCE| DBCSR flop rate (Gflops / MPI rank):", my_flop_rate
    1658             : 
    1659             :          ELSE
    1660             : 
    1661         238 :             CALL dgemm_counter_write(dgemm_counter, para_env)
    1662             : 
    1663             :          END IF
    1664             : 
    1665             :          ! GW: for low-scaling calculation: Compute self-energy Sigma(i*tau), Sigma(i*omega)
    1666             :          ! for low-scaling and ordinary-scaling: analytic continuation from Sigma(iw) -> Sigma(w)
    1667             :          !                                       and correction of quasiparticle energies e_n^GW
    1668         656 :          IF (my_do_gw) THEN
    1669             : 
    1670             :             CALL compute_QP_energies(vec_Sigma_c_gw, count_ev_sc_GW, gw_corr_lev_occ, &
    1671             :                                      gw_corr_lev_tot, gw_corr_lev_virt, homo, &
    1672             :                                      nmo, num_fit_points, num_integ_points, &
    1673             :                                      unit_nr, do_apply_ic_corr_to_gw, do_im_time, &
    1674             :                                      do_periodic, do_ri_Sigma_x, first_cycle_periodic_correction, &
    1675             :                                      e_fermi, eps_filter, fermi_level_offset, &
    1676             :                                      delta_corr, Eigenval, &
    1677             :                                      Eigenval_last, Eigenval_scf, iter_sc_GW0, exit_ev_gw, tau_tj, tj, &
    1678             :                                      vec_omega_fit_gw, vec_Sigma_x_gw, mp2_env%ri_g0w0%ic_corr_list, &
    1679             :                                      weights_cos_tf_t_to_w, weights_sin_tf_t_to_w, &
    1680             :                                      fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, fm_mo_coeff_occ, &
    1681             :                                      fm_mo_coeff_virt, fm_scaled_dm_occ_tau, fm_scaled_dm_virt_tau, &
    1682             :                                      mo_coeff(1), fm_mat_W, para_env, para_env_RPA, mat_dm, mat_MinvVMinv, &
    1683             :                                      t_3c_O, t_3c_M, t_3c_overl_int_ao_mo, t_3c_O_compressed, t_3c_O_mo_compressed, &
    1684             :                                      t_3c_O_ind, t_3c_O_mo_ind, &
    1685             :                                      t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
    1686             :                                      matrix_berry_im_mo_mo, matrix_berry_re_mo_mo, mat_W, matrix_s, &
    1687             :                                      kpoints, mp2_env, qs_env, nkp_self_energy, do_kpoints_cubic_RPA, &
    1688         204 :                                      starts_array_mc, ends_array_mc)
    1689             : 
    1690             :             ! if HOMO-LUMO gap differs by less than mp2_env%ri_g0w0%eps_ev_sc_iter, exit ev sc GW loop
    1691         204 :             IF (exit_ev_gw) EXIT
    1692             : 
    1693             :          END IF ! my_do_gw if
    1694             : 
    1695             :       END DO ! evGW loop
    1696             : 
    1697         272 :       IF (do_ic_model) THEN
    1698             : 
    1699           2 :          IF (my_open_shell) THEN
    1700             : 
    1701             :             CALL calculate_ic_correction(Eigenval(:, 1, 1), mat_MinvVMinv%matrix, &
    1702             :                                          t_3c_overl_nnP_ic(1), t_3c_overl_nnP_ic_reflected(1), &
    1703             :                                          gw_corr_lev_tot, &
    1704             :                                          gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), unit_nr, &
    1705           0 :                                          print_ic_values, para_env, do_alpha=.TRUE.)
    1706             : 
    1707             :             CALL calculate_ic_correction(Eigenval(:, 1, 2), mat_MinvVMinv%matrix, &
    1708             :                                          t_3c_overl_nnP_ic(2), t_3c_overl_nnP_ic_reflected(2), &
    1709             :                                          gw_corr_lev_tot, &
    1710             :                                          gw_corr_lev_occ(2), gw_corr_lev_virt(2), homo(2), unit_nr, &
    1711           0 :                                          print_ic_values, para_env, do_beta=.TRUE.)
    1712             : 
    1713             :          ELSE
    1714             : 
    1715             :             CALL calculate_ic_correction(Eigenval(:, 1, 1), mat_MinvVMinv%matrix, &
    1716             :                                          t_3c_overl_nnP_ic(1), t_3c_overl_nnP_ic_reflected(1), &
    1717             :                                          gw_corr_lev_tot, &
    1718             :                                          gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), unit_nr, &
    1719           2 :                                          print_ic_values, para_env)
    1720             : 
    1721             :          END IF
    1722             : 
    1723             :       END IF
    1724             : 
    1725             :       ! postprocessing after GW for Bethe-Salpeter
    1726         272 :       IF (do_bse) THEN
    1727             :          ! Check used GW flavor; in Case of evGW we use W0 for BSE
    1728             :          ! Use environment variable, since local iter_evGW is overwritten if evGW0 is invoked
    1729          18 :          IF (mp2_env%ri_g0w0%iter_evGW > 1) THEN
    1730           6 :             IF (unit_nr > 0) THEN
    1731             :                CALL cp_warn(__LOCATION__, &
    1732             :                             "BSE@evGW applies W0, i.e. screening with DFT energies! "// &
    1733           3 :                             "Use BSE@evGW0 to avoid this warning!")
    1734             :             END IF
    1735             :          END IF
    1736             :          ! Create a copy of fm_mat_S for usage in BSE
    1737          18 :          CALL cp_fm_create(fm_mat_S_ia_bse, fm_mat_S(1)%matrix_struct)
    1738          18 :          CALL cp_fm_to_fm(fm_mat_S(1), fm_mat_S_ia_bse)
    1739             :          ! Remove energy/frequency factor from 3c-Integral for BSE
    1740          18 :          IF (iter_sc_gw0 == 1) THEN
    1741             :             CALL remove_scaling_factor_rpa(fm_mat_S_ia_bse, virtual(1), &
    1742          12 :                                            Eigenval_last(:, 1, 1), homo(1), omega)
    1743             :          ELSE
    1744             :             CALL remove_scaling_factor_rpa(fm_mat_S_ia_bse, virtual(1), &
    1745           6 :                                            Eigenval_scf(:, 1, 1), homo(1), omega)
    1746             :          END IF
    1747             :          ! Main routine for all BSE postprocessing
    1748             :          CALL start_bse_calculation(fm_mat_S_ia_bse, fm_mat_S_ij_bse, fm_mat_S_ab_bse, &
    1749             :                                     fm_mat_Q_static_bse_gemm, &
    1750             :                                     Eigenval, Eigenval_scf, &
    1751             :                                     homo, virtual, dimen_RI, dimen_RI_red, bse_lev_virt, &
    1752          18 :                                     gd_array, color_sub, mp2_env, qs_env, mo_coeff, unit_nr)
    1753             :          ! Release BSE-copy of fm_mat_S
    1754          18 :          CALL cp_fm_release(fm_mat_S_ia_bse)
    1755             :       END IF
    1756             : 
    1757         272 :       IF (my_do_gw) THEN
    1758             :          CALL deallocate_matrices_gw(fm_mat_S_gw_work, vec_W_gw, vec_Sigma_c_gw, vec_omega_fit_gw, &
    1759             :                                      mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw, &
    1760             :                                      Eigenval_last, Eigenval_scf, do_periodic, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
    1761          92 :                                      kpoints, vec_Sigma_x_gw,.NOT. do_im_time)
    1762             :       END IF
    1763             : 
    1764         272 :       IF (do_im_time) THEN
    1765             : 
    1766             :          CALL dealloc_im_time(fm_mo_coeff_occ, fm_mo_coeff_virt, &
    1767             :                               fm_scaled_dm_occ_tau, fm_scaled_dm_virt_tau, index_to_cell_3c, &
    1768             :                               cell_to_index_3c, do_ic_model, &
    1769             :                               do_kpoints_cubic_RPA, do_kpoints_from_Gamma, do_ri_Sigma_x, &
    1770             :                               has_mat_P_blocks, &
    1771             :                               wkp_W, cfm_mat_Q, fm_mat_Minv_L_kpoints, fm_mat_L_kpoints, &
    1772             :                               fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, fm_mat_RI_global_work, fm_mat_work, &
    1773             :                               fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, mat_dm, mat_L, &
    1774             :                               mat_MinvVMinv, mat_P_omega, mat_P_omega_kp, &
    1775         134 :                               t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, mat_work, qs_env)
    1776             : 
    1777         134 :          IF (my_do_gw) THEN
    1778             :             CALL deallocate_matrices_gw_im_time(weights_cos_tf_w_to_t, weights_sin_tf_t_to_w, do_ic_model, &
    1779             :                                                 do_kpoints_cubic_RPA, fm_mat_W, &
    1780             :                                                 t_3c_overl_int_ao_mo, t_3c_O_mo_compressed, t_3c_O_mo_ind, &
    1781             :                                                 t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
    1782             :                                                 t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected, &
    1783          46 :                                                 mat_W, qs_env)
    1784             :          END IF
    1785             : 
    1786             :       END IF
    1787             : 
    1788         272 :       IF (.NOT. do_im_time .AND. .NOT. do_ri_sos_laplace_mp2) CALL exchange_work%release()
    1789             : 
    1790         272 :       IF (.NOT. do_ri_sos_laplace_mp2) THEN
    1791         214 :          DEALLOCATE (tj)
    1792         214 :          DEALLOCATE (wj)
    1793         214 :          DEALLOCATE (trace_Qomega)
    1794             :       END IF
    1795             : 
    1796         272 :       IF (do_im_time .OR. do_ri_sos_laplace_mp2) THEN
    1797         162 :          DEALLOCATE (tau_tj)
    1798         162 :          DEALLOCATE (tau_wj)
    1799             :       END IF
    1800             : 
    1801         272 :       IF (do_im_time .AND. calc_forces) THEN
    1802          50 :          CALL im_time_force_release(force_data)
    1803             :       END IF
    1804             : 
    1805         272 :       IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_finalize(rpa_grad, mp2_env, para_env_sub, para_env, &
    1806             :                                                                      qs_env, gd_array, color_sub, do_ri_sos_laplace_mp2, &
    1807          40 :                                                                      homo, virtual)
    1808             : 
    1809         272 :       CALL timestop(handle)
    1810             : 
    1811        5570 :    END SUBROUTINE rpa_num_int
    1812             : 
    1813             : END MODULE rpa_main

Generated by: LCOV version 1.15