LCOV - code coverage report
Current view: top level - src - rpa_main.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 96.6 % 590 570
Test Date: 2025-12-04 06:27:48 Functions: 100.0 % 4 4

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

Generated by: LCOV version 2.0-1