LCOV - code coverage report
Current view: top level - src - rpa_gw.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:15a58fb) Lines: 2308 2463 93.7 %
Date: 2025-02-18 08:24:35 Functions: 50 50 100.0 %

          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 for GW, continuous development [Jan Wilhelm]
      10             : !> \par History
      11             : !>      03.2019 created [Frederick Stein]
      12             : !>      12.2022 added periodic GW routines [Jan Wilhelm]
      13             : ! **************************************************************************************************
      14             : MODULE rpa_gw
      15             :    USE ai_overlap,                      ONLY: overlap
      16             :    USE atomic_kind_types,               ONLY: atomic_kind_type
      17             :    USE basis_set_types,                 ONLY: gto_basis_set_p_type,&
      18             :                                               gto_basis_set_type
      19             :    USE cell_types,                      ONLY: cell_type,&
      20             :                                               get_cell
      21             :    USE core_ppnl,                       ONLY: build_core_ppnl
      22             :    USE cp_cfm_basic_linalg,             ONLY: cp_cfm_scale,&
      23             :                                               cp_cfm_scale_and_add,&
      24             :                                               cp_cfm_scale_and_add_fm,&
      25             :                                               cp_cfm_transpose
      26             :    USE cp_cfm_diag,                     ONLY: cp_cfm_geeig_canon
      27             :    USE cp_cfm_types,                    ONLY: cp_cfm_create,&
      28             :                                               cp_cfm_get_info,&
      29             :                                               cp_cfm_release,&
      30             :                                               cp_cfm_set_all,&
      31             :                                               cp_cfm_to_fm,&
      32             :                                               cp_cfm_type,&
      33             :                                               cp_fm_to_cfm
      34             :    USE cp_control_types,                ONLY: dft_control_type
      35             :    USE cp_dbcsr_api,                    ONLY: &
      36             :         dbcsr_add_on_diag, dbcsr_copy, dbcsr_create, dbcsr_desymmetrize, dbcsr_filter, &
      37             :         dbcsr_get_info, dbcsr_init_p, dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, &
      38             :         dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_multiply, &
      39             :         dbcsr_p_type, dbcsr_release, dbcsr_release_p, dbcsr_scale, dbcsr_set, dbcsr_type, &
      40             :         dbcsr_type_antisymmetric, dbcsr_type_no_symmetry
      41             :    USE cp_dbcsr_cp2k_link,              ONLY: cp_dbcsr_alloc_block_from_nbl
      42             :    USE cp_dbcsr_operations,             ONLY: copy_dbcsr_to_fm,&
      43             :                                               copy_fm_to_dbcsr,&
      44             :                                               dbcsr_allocate_matrix_set,&
      45             :                                               dbcsr_deallocate_matrix_set
      46             :    USE cp_files,                        ONLY: close_file,&
      47             :                                               open_file
      48             :    USE cp_fm_basic_linalg,              ONLY: cp_fm_scale_and_add,&
      49             :                                               cp_fm_uplo_to_full
      50             :    USE cp_fm_cholesky,                  ONLY: cp_fm_cholesky_decompose,&
      51             :                                               cp_fm_cholesky_invert
      52             :    USE cp_fm_diag,                      ONLY: cp_fm_syevd
      53             :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      54             :                                               cp_fm_struct_release,&
      55             :                                               cp_fm_struct_type
      56             :    USE cp_fm_types,                     ONLY: &
      57             :         cp_fm_copy_general, cp_fm_create, cp_fm_get_diag, cp_fm_get_info, cp_fm_release, &
      58             :         cp_fm_set_all, cp_fm_to_fm, cp_fm_to_fm_submat, cp_fm_type
      59             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      60             :                                               cp_logger_get_default_unit_nr,&
      61             :                                               cp_logger_type
      62             :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      63             :                                               cp_print_key_unit_nr
      64             :    USE cp_realspace_grid_cube,          ONLY: cp_pw_to_cube
      65             :    USE dbt_api,                         ONLY: &
      66             :         dbt_batched_contract_finalize, dbt_batched_contract_init, dbt_clear, dbt_contract, &
      67             :         dbt_copy, dbt_copy_matrix_to_tensor, dbt_copy_tensor_to_matrix, dbt_create, dbt_destroy, &
      68             :         dbt_get_block, dbt_get_info, dbt_iterator_blocks_left, dbt_iterator_next_block, &
      69             :         dbt_iterator_start, dbt_iterator_stop, dbt_iterator_type, dbt_nblks_total, &
      70             :         dbt_pgrid_create, dbt_pgrid_destroy, dbt_pgrid_type, dbt_type
      71             :    USE hfx_types,                       ONLY: block_ind_type,&
      72             :                                               dealloc_containers,&
      73             :                                               hfx_compression_type
      74             :    USE input_constants,                 ONLY: gw_pade_approx,&
      75             :                                               gw_two_pole_model,&
      76             :                                               ri_rpa_g0w0_crossing_bisection,&
      77             :                                               ri_rpa_g0w0_crossing_newton,&
      78             :                                               ri_rpa_g0w0_crossing_z_shot,&
      79             :                                               soc_none
      80             :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      81             :                                               section_vals_type
      82             :    USE kinds,                           ONLY: default_path_length,&
      83             :                                               dp
      84             :    USE kpoint_methods,                  ONLY: kpoint_density_matrices,&
      85             :                                               kpoint_density_transform,&
      86             :                                               kpoint_init_cell_index
      87             :    USE kpoint_types,                    ONLY: get_kpoint_info,&
      88             :                                               kpoint_create,&
      89             :                                               kpoint_release,&
      90             :                                               kpoint_sym_create,&
      91             :                                               kpoint_type
      92             :    USE machine,                         ONLY: m_walltime
      93             :    USE mathconstants,                   ONLY: fourpi,&
      94             :                                               gaussi,&
      95             :                                               pi,&
      96             :                                               twopi,&
      97             :                                               z_one,&
      98             :                                               z_zero
      99             :    USE message_passing,                 ONLY: mp_para_env_type
     100             :    USE mp2_types,                       ONLY: mp2_type,&
     101             :                                               one_dim_real_array,&
     102             :                                               two_dim_int_array
     103             :    USE parallel_gemm_api,               ONLY: parallel_gemm
     104             :    USE particle_list_types,             ONLY: particle_list_type
     105             :    USE particle_types,                  ONLY: particle_type
     106             :    USE physcon,                         ONLY: evolt
     107             :    USE pw_env_types,                    ONLY: pw_env_get,&
     108             :                                               pw_env_type
     109             :    USE pw_methods,                      ONLY: pw_axpy,&
     110             :                                               pw_copy,&
     111             :                                               pw_scale,&
     112             :                                               pw_zero
     113             :    USE pw_pool_types,                   ONLY: pw_pool_type
     114             :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
     115             :                                               pw_r3d_rs_type
     116             :    USE qs_band_structure,               ONLY: calculate_kp_orbitals
     117             :    USE qs_collocate_density,            ONLY: calculate_rho_elec
     118             :    USE qs_environment_types,            ONLY: get_qs_env,&
     119             :                                               qs_env_release,&
     120             :                                               qs_environment_type
     121             :    USE qs_force_types,                  ONLY: qs_force_type
     122             :    USE qs_gamma2kp,                     ONLY: create_kp_from_gamma
     123             :    USE qs_integral_utils,               ONLY: basis_set_list_setup
     124             :    USE qs_kind_types,                   ONLY: get_qs_kind,&
     125             :                                               qs_kind_type
     126             :    USE qs_ks_types,                     ONLY: qs_ks_env_type
     127             :    USE qs_mo_types,                     ONLY: get_mo_set
     128             :    USE qs_moments,                      ONLY: build_berry_moment_matrix
     129             :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type,&
     130             :                                               release_neighbor_list_sets
     131             :    USE qs_neighbor_lists,               ONLY: setup_neighbor_list
     132             :    USE qs_overlap,                      ONLY: build_overlap_matrix_simple
     133             :    USE qs_scf_types,                    ONLY: qs_scf_env_type
     134             :    USE qs_subsys_types,                 ONLY: qs_subsys_get,&
     135             :                                               qs_subsys_type
     136             :    USE qs_tensors,                      ONLY: decompress_tensor
     137             :    USE qs_tensors_types,                ONLY: create_2c_tensor
     138             :    USE rpa_gw_ic,                       ONLY: apply_ic_corr
     139             :    USE rpa_gw_im_time_util,             ONLY: get_tensor_3c_overl_int_gw
     140             :    USE rpa_gw_kpoints_util,             ONLY: get_mat_cell_T_from_mat_gamma,&
     141             :                                               mat_kp_from_mat_gamma,&
     142             :                                               real_space_to_kpoint_transform_rpa
     143             :    USE rpa_im_time,                     ONLY: compute_periodic_dm
     144             :    USE scf_control_types,               ONLY: scf_control_type
     145             :    USE util,                            ONLY: sort
     146             :    USE virial_types,                    ONLY: virial_type
     147             : #include "./base/base_uses.f90"
     148             : 
     149             :    IMPLICIT NONE
     150             : 
     151             :    PRIVATE
     152             : 
     153             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'rpa_gw'
     154             : 
     155             :    PUBLIC :: allocate_matrices_gw_im_time, allocate_matrices_gw, compute_GW_self_energy, compute_QP_energies, &
     156             :              deallocate_matrices_gw_im_time, deallocate_matrices_gw, compute_minus_vxc_kpoints, trafo_to_mo_and_kpoints, &
     157             :              get_fermi_level_offset, compute_W_cubic_GW, continuation_pade
     158             : 
     159             : CONTAINS
     160             : 
     161             : ! **************************************************************************************************
     162             : !> \brief ...
     163             : !> \param gw_corr_lev_occ ...
     164             : !> \param gw_corr_lev_virt ...
     165             : !> \param homo ...
     166             : !> \param nmo ...
     167             : !> \param num_integ_points ...
     168             : !> \param unit_nr ...
     169             : !> \param RI_blk_sizes ...
     170             : !> \param do_ic_model ...
     171             : !> \param para_env ...
     172             : !> \param fm_mat_W ...
     173             : !> \param fm_mat_Q ...
     174             : !> \param mo_coeff ...
     175             : !> \param t_3c_overl_int_ao_mo ...
     176             : !> \param t_3c_O_mo_compressed ...
     177             : !> \param t_3c_O_mo_ind ...
     178             : !> \param t_3c_overl_int_gw_RI ...
     179             : !> \param t_3c_overl_int_gw_AO ...
     180             : !> \param starts_array_mc ...
     181             : !> \param ends_array_mc ...
     182             : !> \param t_3c_overl_nnP_ic ...
     183             : !> \param t_3c_overl_nnP_ic_reflected ...
     184             : !> \param matrix_s ...
     185             : !> \param mat_W ...
     186             : !> \param t_3c_overl_int ...
     187             : !> \param t_3c_O_compressed ...
     188             : !> \param t_3c_O_ind ...
     189             : !> \param qs_env ...
     190             : ! **************************************************************************************************
     191          96 :    SUBROUTINE allocate_matrices_gw_im_time(gw_corr_lev_occ, gw_corr_lev_virt, homo, nmo, &
     192             :                                            num_integ_points, unit_nr, &
     193             :                                            RI_blk_sizes, do_ic_model, &
     194             :                                            para_env, fm_mat_W, fm_mat_Q, &
     195          48 :                                            mo_coeff, &
     196             :                                            t_3c_overl_int_ao_mo, t_3c_O_mo_compressed, t_3c_O_mo_ind, &
     197             :                                            t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
     198          48 :                                            starts_array_mc, ends_array_mc, &
     199             :                                            t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected, &
     200          48 :                                            matrix_s, mat_W, t_3c_overl_int, &
     201          48 :                                            t_3c_O_compressed, t_3c_O_ind, &
     202             :                                            qs_env)
     203             : 
     204             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: gw_corr_lev_occ, gw_corr_lev_virt, homo
     205             :       INTEGER, INTENT(IN)                                :: nmo, num_integ_points, unit_nr
     206             :       INTEGER, DIMENSION(:), POINTER                     :: RI_blk_sizes
     207             :       LOGICAL, INTENT(IN)                                :: do_ic_model
     208             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     209             :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
     210             :          INTENT(OUT)                                     :: fm_mat_W
     211             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mat_Q
     212             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: mo_coeff
     213             :       TYPE(dbt_type)                                     :: t_3c_overl_int_ao_mo
     214             :       TYPE(hfx_compression_type), ALLOCATABLE, &
     215             :          DIMENSION(:)                                    :: t_3c_O_mo_compressed
     216             :       TYPE(two_dim_int_array), ALLOCATABLE, &
     217             :          DIMENSION(:), INTENT(OUT)                       :: t_3c_O_mo_ind
     218             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:), &
     219             :          INTENT(INOUT)                                   :: t_3c_overl_int_gw_RI, &
     220             :                                                             t_3c_overl_int_gw_AO
     221             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: starts_array_mc, ends_array_mc
     222             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:), &
     223             :          INTENT(INOUT)                                   :: t_3c_overl_nnP_ic, &
     224             :                                                             t_3c_overl_nnP_ic_reflected
     225             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
     226             :       TYPE(dbcsr_type), POINTER                          :: mat_W
     227             :       TYPE(dbt_type), DIMENSION(:, :)                    :: t_3c_overl_int
     228             :       TYPE(hfx_compression_type), DIMENSION(:, :, :)     :: t_3c_O_compressed
     229             :       TYPE(block_ind_type), DIMENSION(:, :, :)           :: t_3c_O_ind
     230             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     231             : 
     232             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'allocate_matrices_gw_im_time'
     233             : 
     234             :       INTEGER                                            :: handle, jquad, nspins
     235             :       LOGICAL                                            :: my_open_shell
     236         432 :       TYPE(dbt_type)                                     :: t_3c_overl_int_ao_mo_beta
     237             : 
     238          48 :       CALL timeset(routineN, handle)
     239             : 
     240          48 :       nspins = SIZE(homo)
     241          48 :       my_open_shell = (nspins == 2)
     242             : 
     243           0 :       ALLOCATE (t_3c_O_mo_ind(nspins), t_3c_overl_int_gw_AO(nspins), t_3c_overl_int_gw_RI(nspins), &
     244      103932 :                 t_3c_overl_nnP_ic(nspins), t_3c_overl_nnP_ic_reflected(nspins), t_3c_O_mo_compressed(nspins))
     245             :       CALL get_tensor_3c_overl_int_gw(t_3c_overl_int, &
     246             :                                       t_3c_O_compressed, t_3c_O_ind, &
     247             :                                       t_3c_overl_int_ao_mo, t_3c_O_mo_compressed(1), t_3c_O_mo_ind(1)%array, &
     248             :                                       t_3c_overl_int_gw_RI(1), t_3c_overl_int_gw_AO(1), &
     249             :                                       starts_array_mc, ends_array_mc, &
     250             :                                       mo_coeff(1), matrix_s, &
     251             :                                       gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), nmo, &
     252             :                                       para_env, &
     253             :                                       do_ic_model, &
     254             :                                       t_3c_overl_nnP_ic(1), t_3c_overl_nnP_ic_reflected(1), &
     255          48 :                                       qs_env, unit_nr, do_alpha=.TRUE.)
     256             : 
     257          48 :       IF (my_open_shell) THEN
     258             : 
     259             :          CALL get_tensor_3c_overl_int_gw(t_3c_overl_int, &
     260             :                                          t_3c_O_compressed, t_3c_O_ind, &
     261             :                                          t_3c_overl_int_ao_mo_beta, t_3c_O_mo_compressed(2), t_3c_O_mo_ind(2)%array, &
     262             :                                          t_3c_overl_int_gw_RI(2), t_3c_overl_int_gw_AO(2), &
     263             :                                          starts_array_mc, ends_array_mc, &
     264             :                                          mo_coeff(2), matrix_s, &
     265             :                                          gw_corr_lev_occ(2), gw_corr_lev_virt(2), homo(2), nmo, &
     266             :                                          para_env, &
     267             :                                          do_ic_model, &
     268             :                                          t_3c_overl_nnP_ic(2), t_3c_overl_nnP_ic_reflected(2), &
     269          10 :                                          qs_env, unit_nr, do_alpha=.FALSE.)
     270             : 
     271          10 :          IF (.NOT. qs_env%mp2_env%ri_g0w0%do_kpoints_Sigma) THEN
     272           6 :             CALL dbt_destroy(t_3c_overl_int_ao_mo_beta)
     273             :          END IF
     274             : 
     275             :       END IF
     276             : 
     277         642 :       ALLOCATE (fm_mat_W(num_integ_points))
     278             : 
     279         546 :       DO jquad = 1, num_integ_points
     280             : 
     281         498 :          CALL cp_fm_create(fm_mat_W(jquad), fm_mat_Q%matrix_struct)
     282         498 :          CALL cp_fm_to_fm(fm_mat_Q, fm_mat_W(jquad))
     283         546 :          CALL cp_fm_set_all(fm_mat_W(jquad), 0.0_dp)
     284             : 
     285             :       END DO
     286             : 
     287          48 :       NULLIFY (mat_W)
     288          48 :       CALL dbcsr_init_p(mat_W)
     289             :       CALL dbcsr_create(matrix=mat_W, &
     290             :                         template=matrix_s(1)%matrix, &
     291             :                         matrix_type=dbcsr_type_no_symmetry, &
     292             :                         row_blk_size=RI_blk_sizes, &
     293          48 :                         col_blk_size=RI_blk_sizes)
     294             : 
     295          48 :       CALL timestop(handle)
     296             : 
     297          96 :    END SUBROUTINE allocate_matrices_gw_im_time
     298             : 
     299             : ! **************************************************************************************************
     300             : !> \brief ...
     301             : !> \param vec_Sigma_c_gw ...
     302             : !> \param color_rpa_group ...
     303             : !> \param dimen_nm_gw ...
     304             : !> \param gw_corr_lev_occ ...
     305             : !> \param gw_corr_lev_virt ...
     306             : !> \param homo ...
     307             : !> \param nmo ...
     308             : !> \param num_integ_group ...
     309             : !> \param num_integ_points ...
     310             : !> \param unit_nr ...
     311             : !> \param gw_corr_lev_tot ...
     312             : !> \param num_fit_points ...
     313             : !> \param omega_max_fit ...
     314             : !> \param do_minimax_quad ...
     315             : !> \param do_periodic ...
     316             : !> \param do_ri_Sigma_x ...
     317             : !> \param my_do_gw ...
     318             : !> \param first_cycle_periodic_correction ...
     319             : !> \param a_scaling ...
     320             : !> \param Eigenval ...
     321             : !> \param tj ...
     322             : !> \param vec_omega_fit_gw ...
     323             : !> \param vec_Sigma_x_gw ...
     324             : !> \param delta_corr ...
     325             : !> \param Eigenval_last ...
     326             : !> \param Eigenval_scf ...
     327             : !> \param vec_W_gw ...
     328             : !> \param fm_mat_S_gw ...
     329             : !> \param fm_mat_S_gw_work ...
     330             : !> \param para_env ...
     331             : !> \param mp2_env ...
     332             : !> \param kpoints ...
     333             : !> \param nkp ...
     334             : !> \param nkp_self_energy ...
     335             : !> \param do_kpoints_cubic_RPA ...
     336             : !> \param do_kpoints_from_Gamma ...
     337             : ! **************************************************************************************************
     338         118 :    SUBROUTINE allocate_matrices_gw(vec_Sigma_c_gw, color_rpa_group, dimen_nm_gw, &
     339         118 :                                    gw_corr_lev_occ, gw_corr_lev_virt, homo, &
     340             :                                    nmo, num_integ_group, num_integ_points, unit_nr, &
     341             :                                    gw_corr_lev_tot, num_fit_points, omega_max_fit, &
     342             :                                    do_minimax_quad, do_periodic, do_ri_Sigma_x, my_do_gw, &
     343             :                                    first_cycle_periodic_correction, &
     344             :                                    a_scaling, Eigenval, tj, vec_omega_fit_gw, vec_Sigma_x_gw, &
     345             :                                    delta_corr, Eigenval_last, Eigenval_scf, vec_W_gw, &
     346         118 :                                    fm_mat_S_gw, fm_mat_S_gw_work, &
     347             :                                    para_env, mp2_env, kpoints, nkp, nkp_self_energy, &
     348             :                                    do_kpoints_cubic_RPA, do_kpoints_from_Gamma)
     349             : 
     350             :       COMPLEX(KIND=dp), ALLOCATABLE, &
     351             :          DIMENSION(:, :, :, :), INTENT(OUT)              :: vec_Sigma_c_gw
     352             :       INTEGER, INTENT(IN)                                :: color_rpa_group, dimen_nm_gw
     353             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: gw_corr_lev_occ, gw_corr_lev_virt, homo
     354             :       INTEGER, INTENT(IN)                                :: nmo, num_integ_group, num_integ_points, &
     355             :                                                             unit_nr
     356             :       INTEGER, INTENT(INOUT)                             :: gw_corr_lev_tot, num_fit_points
     357             :       REAL(KIND=dp)                                      :: omega_max_fit
     358             :       LOGICAL, INTENT(IN)                                :: do_minimax_quad, do_periodic, &
     359             :                                                             do_ri_Sigma_x, my_do_gw
     360             :       LOGICAL, INTENT(OUT) :: first_cycle_periodic_correction
     361             :       REAL(KIND=dp), INTENT(IN)                          :: a_scaling
     362             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
     363             :          INTENT(INOUT)                                   :: Eigenval
     364             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
     365             :          INTENT(IN)                                      :: tj
     366             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
     367             :          INTENT(OUT)                                     :: vec_omega_fit_gw
     368             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
     369             :          INTENT(OUT)                                     :: vec_Sigma_x_gw
     370             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
     371             :          INTENT(INOUT)                                   :: delta_corr
     372             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
     373             :          INTENT(OUT)                                     :: Eigenval_last, Eigenval_scf
     374             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
     375             :          INTENT(OUT)                                     :: vec_W_gw
     376             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: fm_mat_S_gw
     377             :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
     378             :          INTENT(INOUT)                                   :: fm_mat_S_gw_work
     379             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     380             :       TYPE(mp2_type)                                     :: mp2_env
     381             :       TYPE(kpoint_type), POINTER                         :: kpoints
     382             :       INTEGER, INTENT(OUT)                               :: nkp, nkp_self_energy
     383             :       LOGICAL, INTENT(IN)                                :: do_kpoints_cubic_RPA, &
     384             :                                                             do_kpoints_from_Gamma
     385             : 
     386             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'allocate_matrices_gw'
     387             : 
     388             :       INTEGER                                            :: handle, iquad, ispin, jquad, nspins
     389             :       LOGICAL                                            :: my_open_shell
     390             :       REAL(KIND=dp)                                      :: omega
     391         118 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: vec_omega_gw
     392             : 
     393         118 :       CALL timeset(routineN, handle)
     394             : 
     395         118 :       nspins = SIZE(Eigenval, 3)
     396         118 :       my_open_shell = (nspins == 2)
     397             : 
     398         118 :       gw_corr_lev_tot = gw_corr_lev_occ(1) + gw_corr_lev_virt(1)
     399             : 
     400             :       ! fill the omega_frequency vector
     401         354 :       ALLOCATE (vec_omega_gw(num_integ_points))
     402        5156 :       vec_omega_gw = 0.0_dp
     403             : 
     404        5156 :       DO jquad = 1, num_integ_points
     405        5038 :          IF (do_minimax_quad) THEN
     406         498 :             omega = tj(jquad)
     407             :          ELSE
     408        4540 :             omega = a_scaling/TAN(tj(jquad))
     409             :          END IF
     410        5156 :          vec_omega_gw(jquad) = omega
     411             :       END DO
     412             : 
     413             :       ! determine number of fit points in the interval [0,w_max] for virt, or [-w_max,0] for occ
     414         118 :       num_fit_points = 0
     415             : 
     416        5156 :       DO jquad = 1, num_integ_points
     417        5156 :          IF (vec_omega_gw(jquad) < omega_max_fit) THEN
     418        4084 :             num_fit_points = num_fit_points + 1
     419             :          END IF
     420             :       END DO
     421             : 
     422         118 :       IF (mp2_env%ri_g0w0%analytic_continuation == gw_pade_approx) THEN
     423          82 :          IF (mp2_env%ri_g0w0%nparam_pade > num_fit_points) THEN
     424          36 :             IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A)") &
     425          18 :                "Pade approximation: more parameters than data points. Reset # of parameters."
     426          36 :             mp2_env%ri_g0w0%nparam_pade = num_fit_points
     427          36 :             IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T74,I7)") &
     428          18 :                "Number of pade parameters:", mp2_env%ri_g0w0%nparam_pade
     429             :          END IF
     430             :       END IF
     431             : 
     432             :       ! create new arrays containing omega values at which we calculate vec_Sigma_c_gw
     433         354 :       ALLOCATE (vec_omega_fit_gw(num_fit_points))
     434             : 
     435             :       ! fill the omega vector with frequencies, where we calculate the self-energy
     436         118 :       iquad = 0
     437        5156 :       DO jquad = 1, num_integ_points
     438        5156 :          IF (vec_omega_gw(jquad) < omega_max_fit) THEN
     439        4084 :             iquad = iquad + 1
     440        4084 :             vec_omega_fit_gw(iquad) = vec_omega_gw(jquad)
     441             :          END IF
     442             :       END DO
     443             : 
     444         118 :       DEALLOCATE (vec_omega_gw)
     445             : 
     446         118 :       IF (do_kpoints_cubic_RPA) THEN
     447           0 :          CALL get_kpoint_info(kpoints, nkp=nkp)
     448           0 :          IF (mp2_env%ri_g0w0%do_gamma_only_sigma) THEN
     449           0 :             nkp_self_energy = 1
     450             :          ELSE
     451           0 :             nkp_self_energy = nkp
     452             :          END IF
     453         118 :       ELSE IF (do_kpoints_from_Gamma) THEN
     454          18 :          CALL get_kpoint_info(kpoints, nkp=nkp)
     455          18 :          IF (mp2_env%ri_g0w0%do_kpoints_Sigma) THEN
     456          18 :             nkp_self_energy = mp2_env%ri_g0w0%nkp_self_energy
     457             :          ELSE
     458           0 :             nkp_self_energy = 1
     459             :          END IF
     460             :       ELSE
     461         100 :          nkp = 1
     462         100 :          nkp_self_energy = 1
     463             :       END IF
     464         708 :       ALLOCATE (vec_Sigma_c_gw(gw_corr_lev_tot, num_fit_points, nkp_self_energy, nspins))
     465       70844 :       vec_Sigma_c_gw = z_zero
     466             : 
     467         590 :       ALLOCATE (Eigenval_scf(nmo, nkp_self_energy, nspins))
     468        6454 :       Eigenval_scf(:, :, :) = Eigenval(:, :, :)
     469             : 
     470         472 :       ALLOCATE (Eigenval_last(nmo, nkp_self_energy, nspins))
     471        6454 :       Eigenval_last(:, :, :) = Eigenval(:, :, :)
     472             : 
     473         118 :       IF (do_periodic) THEN
     474             : 
     475          18 :          ALLOCATE (delta_corr(1 + homo(1) - gw_corr_lev_occ(1):homo(1) + gw_corr_lev_virt(1)))
     476          70 :          delta_corr(:) = 0.0_dp
     477             : 
     478           6 :          first_cycle_periodic_correction = .TRUE.
     479             : 
     480             :       END IF
     481             : 
     482         472 :       ALLOCATE (vec_Sigma_x_gw(nmo, nkp_self_energy, nspins))
     483        6454 :       vec_Sigma_x_gw = 0.0_dp
     484             : 
     485         118 :       IF (my_do_gw) THEN
     486             : 
     487             :          ! minimax grids not implemented for O(N^4) GW
     488          70 :          CPASSERT(.NOT. do_minimax_quad)
     489             : 
     490             :          ! create temporary matrix to store B*([1+Q(iw')]^-1-1), has the same size as B
     491         284 :          ALLOCATE (fm_mat_S_gw_work(nspins))
     492         144 :          DO ispin = 1, nspins
     493          74 :             CALL cp_fm_create(fm_mat_S_gw_work(ispin), fm_mat_S_gw(ispin)%matrix_struct)
     494         144 :             CALL cp_fm_set_all(matrix=fm_mat_S_gw_work(ispin), alpha=0.0_dp)
     495             :          END DO
     496             : 
     497         280 :          ALLOCATE (vec_W_gw(dimen_nm_gw, nspins))
     498       25848 :          vec_W_gw = 0.0_dp
     499             : 
     500             :          ! in case we do RI for Sigma_x, we calculate Sigma_x right here
     501          70 :          IF (do_ri_Sigma_x) THEN
     502             : 
     503             :             CALL get_vec_sigma_x(vec_Sigma_x_gw(:, :, 1), nmo, fm_mat_S_gw(1), para_env, num_integ_group, color_rpa_group, &
     504          52 :                                  homo(1), gw_corr_lev_occ(1), mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 1, 1))
     505             : 
     506          52 :             IF (my_open_shell) THEN
     507             :                CALL get_vec_sigma_x(vec_Sigma_x_gw(:, :, 2), nmo, fm_mat_S_gw(2), para_env, num_integ_group, &
     508             :                                     color_rpa_group, homo(2), gw_corr_lev_occ(2), &
     509           0 :                                     mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 2, 1))
     510             :             END IF
     511             : 
     512             :          END IF
     513             : 
     514             :       END IF
     515             : 
     516         118 :       CALL timestop(handle)
     517             : 
     518         118 :    END SUBROUTINE allocate_matrices_gw
     519             : 
     520             : ! **************************************************************************************************
     521             : !> \brief ...
     522             : !> \param vec_Sigma_x_gw ...
     523             : !> \param nmo ...
     524             : !> \param fm_mat_S_gw ...
     525             : !> \param para_env ...
     526             : !> \param num_integ_group ...
     527             : !> \param color_rpa_group ...
     528             : !> \param homo ...
     529             : !> \param gw_corr_lev_occ ...
     530             : !> \param vec_Sigma_x_minus_vxc_gw11 ...
     531             : ! **************************************************************************************************
     532          52 :    SUBROUTINE get_vec_sigma_x(vec_Sigma_x_gw, nmo, fm_mat_S_gw, para_env, num_integ_group, color_rpa_group, homo, &
     533          52 :                               gw_corr_lev_occ, vec_Sigma_x_minus_vxc_gw11)
     534             : 
     535             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: vec_Sigma_x_gw
     536             :       INTEGER, INTENT(IN)                                :: nmo
     537             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mat_S_gw
     538             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     539             :       INTEGER, INTENT(IN)                                :: num_integ_group, color_rpa_group, homo, &
     540             :                                                             gw_corr_lev_occ
     541             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: vec_Sigma_x_minus_vxc_gw11
     542             : 
     543             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'get_vec_sigma_x'
     544             : 
     545             :       INTEGER                                            :: handle, iiB, m_global, n_global, &
     546             :                                                             ncol_local, nm_global, nrow_local
     547          52 :       INTEGER, DIMENSION(:), POINTER                     :: col_indices
     548             : 
     549          52 :       CALL timeset(routineN, handle)
     550             : 
     551             :       CALL cp_fm_get_info(matrix=fm_mat_S_gw, &
     552             :                           nrow_local=nrow_local, &
     553             :                           ncol_local=ncol_local, &
     554          52 :                           col_indices=col_indices)
     555             : 
     556          52 :       CALL para_env%sync()
     557             : 
     558             :       ! loop over (nm) index
     559       18728 :       DO iiB = 1, ncol_local
     560             : 
     561             :          ! this is needed for correct values within parallelization
     562       18676 :          IF (MODULO(1, num_integ_group) /= color_rpa_group) CYCLE
     563             : 
     564       17066 :          nm_global = col_indices(iiB)
     565             : 
     566             :          ! transform the index nm to n and m, formulae copied from Mauro's code
     567       17066 :          n_global = MAX(1, nm_global - 1)/nmo + 1
     568       17066 :          m_global = nm_global - (n_global - 1)*nmo
     569       17066 :          n_global = n_global + homo - gw_corr_lev_occ
     570             : 
     571       17118 :          IF (m_global <= homo) THEN
     572             : 
     573             :             ! Sigma_x_n = -sum_m^occ sum_P (B_(nm)^P)^2
     574             :             vec_Sigma_x_gw(n_global, 1) = &
     575             :                vec_Sigma_x_gw(n_global, 1) - &
     576      137760 :                DOT_PRODUCT(fm_mat_S_gw%local_data(:, iiB), fm_mat_S_gw%local_data(:, iiB))
     577             : 
     578             :          END IF
     579             : 
     580             :       END DO
     581             : 
     582          52 :       CALL para_env%sync()
     583             : 
     584        2548 :       CALL para_env%sum(vec_Sigma_x_gw)
     585             : 
     586             :       vec_Sigma_x_minus_vxc_gw11(:) = &
     587             :          vec_Sigma_x_minus_vxc_gw11(:) + &
     588        1248 :          vec_Sigma_x_gw(:, 1)
     589             : 
     590          52 :       CALL timestop(handle)
     591             : 
     592          52 :    END SUBROUTINE get_vec_sigma_x
     593             : 
     594             : ! **************************************************************************************************
     595             : !> \brief ...
     596             : !> \param fm_mat_S_gw_work ...
     597             : !> \param vec_W_gw ...
     598             : !> \param vec_Sigma_c_gw ...
     599             : !> \param vec_omega_fit_gw ...
     600             : !> \param vec_Sigma_x_minus_vxc_gw ...
     601             : !> \param Eigenval_last ...
     602             : !> \param Eigenval_scf ...
     603             : !> \param do_periodic ...
     604             : !> \param matrix_berry_re_mo_mo ...
     605             : !> \param matrix_berry_im_mo_mo ...
     606             : !> \param kpoints ...
     607             : !> \param vec_Sigma_x_gw ...
     608             : !> \param my_do_gw ...
     609             : ! **************************************************************************************************
     610         118 :    SUBROUTINE deallocate_matrices_gw(fm_mat_S_gw_work, vec_W_gw, vec_Sigma_c_gw, vec_omega_fit_gw, &
     611             :                                      vec_Sigma_x_minus_vxc_gw, Eigenval_last, &
     612             :                                      Eigenval_scf, do_periodic, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, kpoints, &
     613             :                                      vec_Sigma_x_gw, my_do_gw)
     614             : 
     615             :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
     616             :          INTENT(INOUT)                                   :: fm_mat_S_gw_work
     617             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
     618             :          INTENT(INOUT)                                   :: vec_W_gw
     619             :       COMPLEX(KIND=dp), ALLOCATABLE, &
     620             :          DIMENSION(:, :, :, :), INTENT(INOUT)            :: vec_Sigma_c_gw
     621             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
     622             :          INTENT(INOUT)                                   :: vec_omega_fit_gw
     623             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
     624             :          INTENT(INOUT)                                   :: vec_Sigma_x_minus_vxc_gw, Eigenval_last, &
     625             :                                                             Eigenval_scf
     626             :       LOGICAL, INTENT(IN)                                :: do_periodic
     627             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_berry_re_mo_mo, &
     628             :                                                             matrix_berry_im_mo_mo
     629             :       TYPE(kpoint_type), POINTER                         :: kpoints
     630             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
     631             :          INTENT(INOUT)                                   :: vec_Sigma_x_gw
     632             :       LOGICAL, INTENT(IN)                                :: my_do_gw
     633             : 
     634             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'deallocate_matrices_gw'
     635             : 
     636             :       INTEGER                                            :: handle, nspins
     637             :       LOGICAL                                            :: my_open_shell
     638             : 
     639         118 :       CALL timeset(routineN, handle)
     640             : 
     641         118 :       nspins = SIZE(Eigenval_last, 3)
     642         118 :       my_open_shell = (nspins == 2)
     643             : 
     644         118 :       IF (my_do_gw) THEN
     645          70 :          CALL cp_fm_release(fm_mat_S_gw_work)
     646          70 :          DEALLOCATE (vec_Sigma_x_minus_vxc_gw)
     647          70 :          DEALLOCATE (vec_W_gw)
     648             :       END IF
     649             : 
     650         118 :       DEALLOCATE (vec_Sigma_c_gw)
     651         118 :       DEALLOCATE (vec_Sigma_x_gw)
     652         118 :       DEALLOCATE (vec_omega_fit_gw)
     653         118 :       DEALLOCATE (Eigenval_last)
     654         118 :       DEALLOCATE (Eigenval_scf)
     655             : 
     656         118 :       IF (do_periodic) THEN
     657           6 :          CALL dbcsr_deallocate_matrix_set(matrix_berry_re_mo_mo)
     658           6 :          CALL dbcsr_deallocate_matrix_set(matrix_berry_im_mo_mo)
     659           6 :          CALL kpoint_release(kpoints)
     660             :       END IF
     661             : 
     662         118 :       CALL timestop(handle)
     663             : 
     664         118 :    END SUBROUTINE deallocate_matrices_gw
     665             : 
     666             : ! **************************************************************************************************
     667             : !> \brief ...
     668             : !> \param weights_cos_tf_w_to_t ...
     669             : !> \param weights_sin_tf_t_to_w ...
     670             : !> \param do_ic_model ...
     671             : !> \param do_kpoints_cubic_RPA ...
     672             : !> \param fm_mat_W ...
     673             : !> \param t_3c_overl_int_ao_mo ...
     674             : !> \param t_3c_O_mo_compressed ...
     675             : !> \param t_3c_O_mo_ind ...
     676             : !> \param t_3c_overl_int_gw_RI ...
     677             : !> \param t_3c_overl_int_gw_AO ...
     678             : !> \param t_3c_overl_nnP_ic ...
     679             : !> \param t_3c_overl_nnP_ic_reflected ...
     680             : !> \param mat_W ...
     681             : !> \param qs_env ...
     682             : ! **************************************************************************************************
     683          48 :    SUBROUTINE deallocate_matrices_gw_im_time(weights_cos_tf_w_to_t, weights_sin_tf_t_to_w, do_ic_model, do_kpoints_cubic_RPA, &
     684             :                                              fm_mat_W, &
     685             :                                              t_3c_overl_int_ao_mo, t_3c_O_mo_compressed, t_3c_O_mo_ind, &
     686             :                                              t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
     687             :                                              t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected, mat_W, &
     688             :                                              qs_env)
     689             : 
     690             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
     691             :          INTENT(INOUT)                                   :: weights_cos_tf_w_to_t, &
     692             :                                                             weights_sin_tf_t_to_w
     693             :       LOGICAL, INTENT(IN)                                :: do_ic_model, do_kpoints_cubic_RPA
     694             :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
     695             :          INTENT(INOUT)                                   :: fm_mat_W
     696             :       TYPE(dbt_type), INTENT(INOUT)                      :: t_3c_overl_int_ao_mo
     697             :       TYPE(hfx_compression_type), ALLOCATABLE, &
     698             :          DIMENSION(:)                                    :: t_3c_O_mo_compressed
     699             :       TYPE(two_dim_int_array), ALLOCATABLE, DIMENSION(:) :: t_3c_O_mo_ind
     700             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:), &
     701             :          INTENT(INOUT)                                   :: t_3c_overl_int_gw_RI, &
     702             :                                                             t_3c_overl_int_gw_AO, &
     703             :                                                             t_3c_overl_nnP_ic, &
     704             :                                                             t_3c_overl_nnP_ic_reflected
     705             :       TYPE(dbcsr_type), POINTER                          :: mat_W
     706             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     707             : 
     708             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'deallocate_matrices_gw_im_time'
     709             : 
     710             :       INTEGER                                            :: handle, ispin, nspins, unused
     711             :       LOGICAL                                            :: my_open_shell
     712             : 
     713          48 :       CALL timeset(routineN, handle)
     714             : 
     715          48 :       nspins = SIZE(t_3c_overl_int_gw_RI)
     716          48 :       my_open_shell = (nspins == 2)
     717             : 
     718          48 :       IF (ALLOCATED(weights_cos_tf_w_to_t)) DEALLOCATE (weights_cos_tf_w_to_t)
     719          48 :       IF (ALLOCATED(weights_sin_tf_t_to_w)) DEALLOCATE (weights_sin_tf_t_to_w)
     720             : 
     721          48 :       IF (.NOT. do_kpoints_cubic_RPA) THEN
     722          48 :          CALL cp_fm_release(fm_mat_W)
     723          48 :          CALL dbcsr_release_P(mat_W)
     724             :       END IF
     725             : 
     726         106 :       DO ispin = 1, nspins
     727          58 :          CALL dbt_destroy(t_3c_overl_int_gw_RI(ispin))
     728         106 :          CALL dbt_destroy(t_3c_overl_int_gw_AO(ispin))
     729             :       END DO
     730         164 :       DEALLOCATE (t_3c_overl_int_gw_AO, t_3c_overl_int_gw_RI)
     731          48 :       IF (do_ic_model) THEN
     732           4 :          DO ispin = 1, nspins
     733           2 :             CALL dbt_destroy(t_3c_overl_nnP_ic(ispin))
     734           4 :             CALL dbt_destroy(t_3c_overl_nnP_ic_reflected(ispin))
     735             :          END DO
     736           6 :          DEALLOCATE (t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected)
     737             :       END IF
     738             : 
     739          48 :       IF (.NOT. qs_env%mp2_env%ri_g0w0%do_kpoints_Sigma) THEN
     740          66 :          DO ispin = 1, nspins
     741          36 :             DEALLOCATE (t_3c_O_mo_ind(ispin)%array)
     742          66 :             CALL dealloc_containers(t_3c_O_mo_compressed(ispin), unused)
     743             :          END DO
     744          66 :          DEALLOCATE (t_3c_O_mo_ind, t_3c_O_mo_compressed)
     745             : 
     746          30 :          CALL dbt_destroy(t_3c_overl_int_ao_mo)
     747             :       END IF
     748             : 
     749          48 :       IF (qs_env%mp2_env%ri_g0w0%do_kpoints_Sigma) THEN
     750          40 :          DO ispin = 1, nspins
     751          22 :             CALL dbcsr_release(qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc(ispin)%matrix)
     752          22 :             DEALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc(ispin)%matrix)
     753             : 
     754          22 :             CALL dbcsr_release(qs_env%mp2_env%ri_g0w0%matrix_ks(ispin)%matrix)
     755          40 :             DEALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_ks(ispin)%matrix)
     756             :          END DO
     757          18 :          DEALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc)
     758          18 :          DEALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_ks)
     759             :       END IF
     760             : 
     761          48 :       CALL timestop(handle)
     762             : 
     763          48 :    END SUBROUTINE deallocate_matrices_gw_im_time
     764             : 
     765             : ! **************************************************************************************************
     766             : !> \brief ...
     767             : !> \param vec_Sigma_c_gw ...
     768             : !> \param dimen_nm_gw ...
     769             : !> \param dimen_RI ...
     770             : !> \param gw_corr_lev_occ ...
     771             : !> \param gw_corr_lev_virt ...
     772             : !> \param homo ...
     773             : !> \param jquad ...
     774             : !> \param nmo ...
     775             : !> \param num_fit_points ...
     776             : !> \param do_im_time ...
     777             : !> \param do_periodic ...
     778             : !> \param first_cycle_periodic_correction ...
     779             : !> \param fermi_level_offset ...
     780             : !> \param omega ...
     781             : !> \param Eigenval ...
     782             : !> \param delta_corr ...
     783             : !> \param vec_omega_fit_gw ...
     784             : !> \param vec_W_gw ...
     785             : !> \param wj ...
     786             : !> \param fm_mat_Q ...
     787             : !> \param fm_mat_R_gw ...
     788             : !> \param fm_mat_S_gw ...
     789             : !> \param fm_mat_S_gw_work ...
     790             : !> \param mo_coeff ...
     791             : !> \param para_env ...
     792             : !> \param para_env_RPA ...
     793             : !> \param matrix_berry_im_mo_mo ...
     794             : !> \param matrix_berry_re_mo_mo ...
     795             : !> \param kpoints ...
     796             : !> \param qs_env ...
     797             : !> \param mp2_env ...
     798             : ! **************************************************************************************************
     799       76050 :    SUBROUTINE compute_GW_self_energy(vec_Sigma_c_gw, dimen_nm_gw, dimen_RI, gw_corr_lev_occ, &
     800       15210 :                                      gw_corr_lev_virt, homo, jquad, nmo, num_fit_points, &
     801             :                                      do_im_time, do_periodic, &
     802             :                                      first_cycle_periodic_correction, fermi_level_offset, &
     803       15210 :                                      omega, Eigenval, delta_corr, vec_omega_fit_gw, vec_W_gw, wj, &
     804       15210 :                                      fm_mat_Q, fm_mat_R_gw, fm_mat_S_gw, &
     805       15210 :                                      fm_mat_S_gw_work, mo_coeff, para_env, &
     806             :                                      para_env_RPA, matrix_berry_im_mo_mo, matrix_berry_re_mo_mo, &
     807             :                                      kpoints, qs_env, mp2_env)
     808             : 
     809             :       COMPLEX(KIND=dp), ALLOCATABLE, &
     810             :          DIMENSION(:, :, :, :), INTENT(INOUT)            :: vec_Sigma_c_gw
     811             :       INTEGER, INTENT(IN)                                :: dimen_nm_gw, dimen_RI
     812             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: gw_corr_lev_occ, gw_corr_lev_virt, homo
     813             :       INTEGER, INTENT(IN)                                :: jquad, nmo, num_fit_points
     814             :       LOGICAL, INTENT(IN)                                :: do_im_time, do_periodic
     815             :       LOGICAL, INTENT(INOUT) :: first_cycle_periodic_correction
     816             :       REAL(KIND=dp), INTENT(INOUT)                       :: fermi_level_offset, omega
     817             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: Eigenval
     818             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
     819             :          INTENT(INOUT)                                   :: delta_corr
     820             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
     821             :          INTENT(IN)                                      :: vec_omega_fit_gw
     822             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
     823             :          INTENT(INOUT)                                   :: vec_W_gw
     824             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
     825             :          INTENT(IN)                                      :: wj
     826             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mat_Q, fm_mat_R_gw
     827             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: fm_mat_S_gw, fm_mat_S_gw_work
     828             :       TYPE(cp_fm_type), INTENT(IN)                       :: mo_coeff
     829             :       TYPE(mp_para_env_type), POINTER                    :: para_env, para_env_RPA
     830             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_berry_im_mo_mo, &
     831             :                                                             matrix_berry_re_mo_mo
     832             :       TYPE(kpoint_type), POINTER                         :: kpoints
     833             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     834             :       TYPE(mp2_type)                                     :: mp2_env
     835             : 
     836             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_GW_self_energy'
     837             : 
     838             :       INTEGER                                            :: handle, i_global, iiB, ispin, j_global, &
     839             :                                                             jjB, ncol_local, nrow_local, nspins
     840       15210 :       INTEGER, DIMENSION(:), POINTER                     :: col_indices, row_indices
     841             : 
     842       15210 :       CALL timeset(routineN, handle)
     843             : 
     844       15210 :       nspins = SIZE(fm_mat_S_gw)
     845             : 
     846             :       CALL cp_fm_get_info(matrix=fm_mat_Q, &
     847             :                           nrow_local=nrow_local, &
     848             :                           ncol_local=ncol_local, &
     849             :                           row_indices=row_indices, &
     850       15210 :                           col_indices=col_indices)
     851             : 
     852       15210 :       IF (.NOT. do_im_time) THEN
     853             :          ! calculate [1+Q(iw')]^-1
     854       15210 :          CALL cp_fm_cholesky_invert(fm_mat_Q)
     855             :          ! symmetrize the result, fm_mat_R_gw is only temporary work matrix
     856       15210 :          CALL cp_fm_uplo_to_full(fm_mat_Q, fm_mat_R_gw)
     857             : 
     858             :          ! periodic correction for GW (paper Phys. Rev. B 95, 235123 (2017))
     859       15210 :          IF (do_periodic) THEN
     860             :             CALL calc_periodic_correction(delta_corr, qs_env, para_env, para_env_RPA, &
     861             :                                           mp2_env%ri_g0w0%kp_grid, homo(1), nmo, gw_corr_lev_occ(1), &
     862             :                                           gw_corr_lev_virt(1), omega, mo_coeff, Eigenval(:, 1), &
     863             :                                           matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
     864             :                                           first_cycle_periodic_correction, kpoints, &
     865             :                                           mp2_env%ri_g0w0%do_mo_coeff_gamma, &
     866             :                                           mp2_env%ri_g0w0%num_kp_grids, mp2_env%ri_g0w0%eps_kpoint, &
     867             :                                           mp2_env%ri_g0w0%do_extra_kpoints, &
     868         240 :                                           mp2_env%ri_g0w0%do_aux_bas_gw, mp2_env%ri_g0w0%frac_aux_mos)
     869             :          END IF
     870             : 
     871       15210 :          CALL para_env%sync()
     872             : 
     873             :          ! subtract 1 from the diagonal to get rid of exchange self-energy
     874             : !$OMP           PARALLEL DO DEFAULT(NONE) PRIVATE(jjB,iiB,i_global,j_global) &
     875       15210 : !$OMP                       SHARED(ncol_local,nrow_local,col_indices,row_indices,fm_mat_Q,dimen_RI)
     876             :          DO jjB = 1, ncol_local
     877             :             j_global = col_indices(jjB)
     878             :             DO iiB = 1, nrow_local
     879             :                i_global = row_indices(iiB)
     880             :                IF (j_global == i_global .AND. i_global <= dimen_RI) THEN
     881             :                   fm_mat_Q%local_data(iiB, jjB) = fm_mat_Q%local_data(iiB, jjB) - 1.0_dp
     882             :                END IF
     883             :             END DO
     884             :          END DO
     885             : 
     886       15210 :          CALL para_env%sync()
     887             : 
     888       30480 :          DO ispin = 1, nspins
     889             :             CALL compute_GW_self_energy_deep(vec_Sigma_c_gw(:, :, :, ispin), dimen_nm_gw, dimen_RI, &
     890             :                                              gw_corr_lev_occ(ispin), gw_corr_lev_virt(ispin), &
     891             :                                              homo(ispin), jquad, nmo, &
     892             :                                              num_fit_points, do_periodic, fermi_level_offset, omega, &
     893             :                                              Eigenval(:, ispin), delta_corr, &
     894             :                                              vec_omega_fit_gw, vec_W_gw(:, ispin), wj, fm_mat_Q, &
     895       30480 :                                              fm_mat_S_gw(ispin), fm_mat_S_gw_work(ispin))
     896             :          END DO
     897             : 
     898             :       END IF ! GW
     899             : 
     900       15210 :       CALL timestop(handle)
     901             : 
     902       15210 :    END SUBROUTINE compute_GW_self_energy
     903             : 
     904             : ! **************************************************************************************************
     905             : !> \brief ...
     906             : !> \param fermi_level_offset ...
     907             : !> \param fermi_level_offset_input ...
     908             : !> \param Eigenval ...
     909             : !> \param homo ...
     910             : ! **************************************************************************************************
     911       15808 :    SUBROUTINE get_fermi_level_offset(fermi_level_offset, fermi_level_offset_input, Eigenval, homo)
     912             : 
     913             :       REAL(KIND=dp), INTENT(INOUT)                       :: fermi_level_offset
     914             :       REAL(KIND=dp), INTENT(IN)                          :: fermi_level_offset_input
     915             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: Eigenval
     916             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: homo
     917             : 
     918             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'get_fermi_level_offset'
     919             : 
     920             :       INTEGER                                            :: handle, ispin, nspins
     921             : 
     922       15808 :       CALL timeset(routineN, handle)
     923             : 
     924       15808 :       nspins = SIZE(Eigenval, 2)
     925             : 
     926             :       ! Fermi level offset should have a maximum such that the Fermi level of occupied orbitals
     927             :       ! is always closer to occupied orbitals than to virtual orbitals and vice versa
     928             :       ! that means, the Fermi level offset is at most as big as half the bandgap
     929       15808 :       fermi_level_offset = fermi_level_offset_input
     930       31820 :       DO ispin = 1, nspins
     931       31820 :          fermi_level_offset = MIN(fermi_level_offset, (Eigenval(homo(ispin) + 1, ispin) - Eigenval(homo(ispin), ispin))*0.5_dp)
     932             :       END DO
     933             : 
     934       15808 :       CALL timestop(handle)
     935             : 
     936       15808 :    END SUBROUTINE get_fermi_level_offset
     937             : 
     938             : ! **************************************************************************************************
     939             : !> \brief ...
     940             : !> \param fm_mat_W ...
     941             : !> \param fm_mat_Q ...
     942             : !> \param fm_mat_work ...
     943             : !> \param dimen_RI ...
     944             : !> \param fm_mat_L ...
     945             : !> \param num_integ_points ...
     946             : !> \param tj ...
     947             : !> \param tau_tj ...
     948             : !> \param weights_cos_tf_w_to_t ...
     949             : !> \param jquad ...
     950             : !> \param omega ...
     951             : ! **************************************************************************************************
     952         490 :    SUBROUTINE compute_W_cubic_GW(fm_mat_W, fm_mat_Q, fm_mat_work, dimen_RI, fm_mat_L, num_integ_points, &
     953             :                                  tj, tau_tj, weights_cos_tf_w_to_t, jquad, omega)
     954             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: fm_mat_W
     955             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mat_Q, fm_mat_work
     956             :       INTEGER, INTENT(IN)                                :: dimen_RI
     957             :       TYPE(cp_fm_type), DIMENSION(:, :), INTENT(IN)      :: fm_mat_L
     958             :       INTEGER, INTENT(IN)                                :: num_integ_points
     959             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
     960             :          INTENT(IN)                                      :: tj, tau_tj
     961             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
     962             :          INTENT(IN)                                      :: weights_cos_tf_w_to_t
     963             :       INTEGER, INTENT(IN)                                :: jquad
     964             :       REAL(KIND=dp), INTENT(INOUT)                       :: omega
     965             : 
     966             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_W_cubic_GW'
     967             : 
     968             :       INTEGER                                            :: handle, i_global, iiB, iquad, j_global, &
     969             :                                                             jjB, ncol_local, nrow_local
     970         490 :       INTEGER, DIMENSION(:), POINTER                     :: col_indices, row_indices
     971             :       REAL(KIND=dp)                                      :: tau, weight
     972             : 
     973         490 :       CALL timeset(routineN, handle)
     974             : 
     975             :       CALL cp_fm_get_info(matrix=fm_mat_Q, &
     976             :                           nrow_local=nrow_local, &
     977             :                           ncol_local=ncol_local, &
     978             :                           row_indices=row_indices, &
     979         490 :                           col_indices=col_indices)
     980             :       ! calculate [1+Q(iw')]^-1
     981         490 :       CALL cp_fm_cholesky_invert(fm_mat_Q)
     982             : 
     983             :       ! symmetrize the result
     984         490 :       CALL cp_fm_uplo_to_full(fm_mat_Q, fm_mat_work)
     985             : 
     986             :       ! subtract 1 from the diagonal to get rid of exchange self-energy
     987             : !$OMP           PARALLEL DO DEFAULT(NONE) PRIVATE(jjB,iiB,i_global,j_global) &
     988         490 : !$OMP                       SHARED(ncol_local,nrow_local,col_indices,row_indices,fm_mat_Q,dimen_RI)
     989             :       DO jjB = 1, ncol_local
     990             :          j_global = col_indices(jjB)
     991             :          DO iiB = 1, nrow_local
     992             :             i_global = row_indices(iiB)
     993             :             IF (j_global == i_global .AND. i_global <= dimen_RI) THEN
     994             :                fm_mat_Q%local_data(iiB, jjB) = fm_mat_Q%local_data(iiB, jjB) - 1.0_dp
     995             :             END IF
     996             :          END DO
     997             :       END DO
     998             : 
     999             :       ! multiply with L from the left and the right to get the screened Coulomb interaction
    1000             :       CALL parallel_gemm('T', 'N', dimen_RI, dimen_RI, dimen_RI, 1.0_dp, fm_mat_L(1, 1), fm_mat_Q, &
    1001         490 :                          0.0_dp, fm_mat_work)
    1002             : 
    1003             :       CALL parallel_gemm('N', 'N', dimen_RI, dimen_RI, dimen_RI, 1.0_dp, fm_mat_work, fm_mat_L(1, 1), &
    1004         490 :                          0.0_dp, fm_mat_Q)
    1005             : 
    1006             :       ! Fourier transform from w to t
    1007        8640 :       DO iquad = 1, num_integ_points
    1008             : 
    1009        8150 :          omega = tj(jquad)
    1010        8150 :          tau = tau_tj(iquad)
    1011        8150 :          weight = weights_cos_tf_w_to_t(iquad, jquad)*COS(tau*omega)
    1012             : 
    1013        8150 :          IF (jquad == 1) THEN
    1014             : 
    1015         490 :             CALL cp_fm_set_all(matrix=fm_mat_W(iquad), alpha=0.0_dp)
    1016             : 
    1017             :          END IF
    1018             : 
    1019        8640 :          CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_mat_W(iquad), beta=weight, matrix_b=fm_mat_Q)
    1020             : 
    1021             :       END DO
    1022             : 
    1023         490 :       CALL timestop(handle)
    1024         490 :    END SUBROUTINE compute_W_cubic_GW
    1025             : 
    1026             : ! **************************************************************************************************
    1027             : !> \brief ...
    1028             : !> \param vec_Sigma_c_gw ...
    1029             : !> \param dimen_nm_gw ...
    1030             : !> \param dimen_RI ...
    1031             : !> \param gw_corr_lev_occ ...
    1032             : !> \param gw_corr_lev_virt ...
    1033             : !> \param homo ...
    1034             : !> \param jquad ...
    1035             : !> \param nmo ...
    1036             : !> \param num_fit_points ...
    1037             : !> \param do_periodic ...
    1038             : !> \param fermi_level_offset ...
    1039             : !> \param omega ...
    1040             : !> \param Eigenval ...
    1041             : !> \param delta_corr ...
    1042             : !> \param vec_omega_fit_gw ...
    1043             : !> \param vec_W_gw ...
    1044             : !> \param wj ...
    1045             : !> \param fm_mat_Q ...
    1046             : !> \param fm_mat_S_gw ...
    1047             : !> \param fm_mat_S_gw_work ...
    1048             : ! **************************************************************************************************
    1049       76350 :    SUBROUTINE compute_GW_self_energy_deep(vec_Sigma_c_gw, dimen_nm_gw, dimen_RI, &
    1050             :                                           gw_corr_lev_occ, gw_corr_lev_virt, &
    1051             :                                           homo, jquad, nmo, num_fit_points, &
    1052       30540 :                                           do_periodic, fermi_level_offset, omega, Eigenval, &
    1053       22785 :                                           delta_corr, vec_omega_fit_gw, vec_W_gw, &
    1054       15270 :                                           wj, fm_mat_Q, fm_mat_S_gw, fm_mat_S_gw_work)
    1055             : 
    1056             :       COMPLEX(KIND=dp), DIMENSION(:, :, :), &
    1057             :          INTENT(INOUT)                                   :: vec_Sigma_c_gw
    1058             :       INTEGER, INTENT(IN)                                :: dimen_nm_gw, dimen_RI, gw_corr_lev_occ, &
    1059             :                                                             gw_corr_lev_virt, homo, jquad, nmo, &
    1060             :                                                             num_fit_points
    1061             :       LOGICAL, INTENT(IN)                                :: do_periodic
    1062             :       REAL(KIND=dp), INTENT(IN)                          :: fermi_level_offset
    1063             :       REAL(KIND=dp), INTENT(INOUT)                       :: omega
    1064             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: Eigenval
    1065             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: delta_corr, vec_omega_fit_gw
    1066             :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: vec_W_gw
    1067             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: wj
    1068             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mat_Q, fm_mat_S_gw, fm_mat_S_gw_work
    1069             : 
    1070             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_GW_self_energy_deep'
    1071             : 
    1072             :       INTEGER                                            :: handle, iiB, iquad, m_global, n_global, &
    1073             :                                                             ncol_local, nm_global
    1074       15270 :       INTEGER, DIMENSION(:), POINTER                     :: col_indices, row_indices
    1075             :       REAL(KIND=dp)                                      :: delta_corr_nn, e_fermi, omega_i, &
    1076             :                                                             sign_occ_virt
    1077             : 
    1078       15270 :       CALL timeset(routineN, handle)
    1079             : 
    1080             :       ! S_work_(nm)Q = B_(nm)P * ([1+Q]^-1-1)_PQ
    1081             :       CALL parallel_gemm(transa="N", transb="N", m=dimen_RI, n=dimen_nm_gw, k=dimen_RI, alpha=1.0_dp, &
    1082             :                          matrix_a=fm_mat_Q, matrix_b=fm_mat_S_gw, beta=0.0_dp, &
    1083       15270 :                          matrix_c=fm_mat_S_gw_work)
    1084             : 
    1085             :       CALL cp_fm_get_info(matrix=fm_mat_S_gw, &
    1086             :                           ncol_local=ncol_local, &
    1087             :                           row_indices=row_indices, &
    1088       15270 :                           col_indices=col_indices)
    1089             : 
    1090             :       ! vector W_(nm) = S_work_(nm)Q * [B_(nm)Q]^T
    1091             : 
    1092     5655890 :       vec_W_gw = 0.0_dp
    1093             : 
    1094     5655890 :       DO iiB = 1, ncol_local
    1095     5640620 :          nm_global = col_indices(iiB)
    1096             :          vec_W_gw(nm_global) = vec_W_gw(nm_global) + &
    1097   244700480 :                                DOT_PRODUCT(fm_mat_S_gw_work%local_data(:, iiB), fm_mat_S_gw%local_data(:, iiB))
    1098             : 
    1099             :          ! transform the index nm of vec_W_gw back to n and m, formulae copied from Mauro's code
    1100     5640620 :          n_global = MAX(1, nm_global - 1)/nmo + 1
    1101     5640620 :          m_global = nm_global - (n_global - 1)*nmo
    1102     5640620 :          n_global = n_global + homo - gw_corr_lev_occ
    1103             : 
    1104             :          ! compute self-energy for imaginary frequencies
    1105   462825470 :          DO iquad = 1, num_fit_points
    1106             : 
    1107             :             ! for occ orbitals, we compute the self-energy for negative frequencies
    1108   457169580 :             IF (n_global <= homo) THEN
    1109             :                sign_occ_virt = -1.0_dp
    1110             :             ELSE
    1111   342677820 :                sign_occ_virt = 1.0_dp
    1112             :             END IF
    1113             : 
    1114   457169580 :             omega_i = vec_omega_fit_gw(iquad)*sign_occ_virt
    1115             : 
    1116             :             ! set the Fermi energy for occ orbitals slightly above the HOMO and
    1117             :             ! for virt orbitals slightly below the LUMO
    1118   457169580 :             IF (n_global <= homo) THEN
    1119   686921400 :                e_fermi = MAXVAL(Eigenval(homo - gw_corr_lev_occ + 1:homo)) + fermi_level_offset
    1120             :             ELSE
    1121  4789213560 :                e_fermi = MINVAL(Eigenval(homo + 1:homo + gw_corr_lev_virt)) - fermi_level_offset
    1122             :             END IF
    1123             : 
    1124             :             ! add here the periodic correction
    1125   457169580 :             IF (do_periodic .AND. row_indices(1) == 1 .AND. n_global == m_global) THEN
    1126       57120 :                delta_corr_nn = delta_corr(n_global)
    1127             :             ELSE
    1128             :                delta_corr_nn = 0.0_dp
    1129             :             END IF
    1130             : 
    1131             :             ! update the self-energy (use that vec_W_gw(iw) is symmetric), divide the integration
    1132             :             ! weight by 2, because the integration is from -infty to +infty and not just 0 to +infty
    1133             :             ! as for RPA, also we need for virtual orbitals a complex conjugate
    1134             :             vec_Sigma_c_gw(n_global - homo + gw_corr_lev_occ, iquad, 1) = &
    1135             :                vec_Sigma_c_gw(n_global - homo + gw_corr_lev_occ, iquad, 1) - &
    1136             :                0.5_dp/pi*wj(jquad)/2.0_dp*(vec_W_gw(nm_global) + delta_corr_nn)* &
    1137             :                (1.0_dp/(gaussi*(omega + omega_i) + e_fermi - Eigenval(m_global)) + &
    1138   462810200 :                 1.0_dp/(gaussi*(-omega + omega_i) + e_fermi - Eigenval(m_global)))
    1139             :          END DO
    1140             : 
    1141             :       END DO
    1142             : 
    1143       15270 :       CALL timestop(handle)
    1144             : 
    1145       15270 :    END SUBROUTINE compute_GW_self_energy_deep
    1146             : 
    1147             : ! **************************************************************************************************
    1148             : !> \brief ...
    1149             : !> \param vec_Sigma_c_gw ...
    1150             : !> \param count_ev_sc_GW ...
    1151             : !> \param gw_corr_lev_occ ...
    1152             : !> \param gw_corr_lev_tot ...
    1153             : !> \param gw_corr_lev_virt ...
    1154             : !> \param homo ...
    1155             : !> \param nmo ...
    1156             : !> \param num_fit_points ...
    1157             : !> \param num_integ_points ...
    1158             : !> \param unit_nr ...
    1159             : !> \param do_apply_ic_corr_to_gw ...
    1160             : !> \param do_im_time ...
    1161             : !> \param do_periodic ...
    1162             : !> \param do_ri_Sigma_x ...
    1163             : !> \param first_cycle_periodic_correction ...
    1164             : !> \param e_fermi ...
    1165             : !> \param eps_filter ...
    1166             : !> \param fermi_level_offset ...
    1167             : !> \param delta_corr ...
    1168             : !> \param Eigenval ...
    1169             : !> \param Eigenval_last ...
    1170             : !> \param Eigenval_scf ...
    1171             : !> \param iter_sc_GW0 ...
    1172             : !> \param exit_ev_gw ...
    1173             : !> \param tau_tj ...
    1174             : !> \param tj ...
    1175             : !> \param vec_omega_fit_gw ...
    1176             : !> \param vec_Sigma_x_gw ...
    1177             : !> \param ic_corr_list ...
    1178             : !> \param weights_cos_tf_t_to_w ...
    1179             : !> \param weights_sin_tf_t_to_w ...
    1180             : !> \param fm_mo_coeff_occ_scaled ...
    1181             : !> \param fm_mo_coeff_virt_scaled ...
    1182             : !> \param fm_mo_coeff_occ ...
    1183             : !> \param fm_mo_coeff_virt ...
    1184             : !> \param fm_scaled_dm_occ_tau ...
    1185             : !> \param fm_scaled_dm_virt_tau ...
    1186             : !> \param mo_coeff ...
    1187             : !> \param fm_mat_W ...
    1188             : !> \param para_env ...
    1189             : !> \param para_env_RPA ...
    1190             : !> \param mat_dm ...
    1191             : !> \param mat_MinvVMinv ...
    1192             : !> \param t_3c_O ...
    1193             : !> \param t_3c_M ...
    1194             : !> \param t_3c_overl_int_ao_mo ...
    1195             : !> \param t_3c_O_compressed ...
    1196             : !> \param t_3c_O_mo_compressed ...
    1197             : !> \param t_3c_O_ind ...
    1198             : !> \param t_3c_O_mo_ind ...
    1199             : !> \param t_3c_overl_int_gw_RI ...
    1200             : !> \param t_3c_overl_int_gw_AO ...
    1201             : !> \param matrix_berry_im_mo_mo ...
    1202             : !> \param matrix_berry_re_mo_mo ...
    1203             : !> \param mat_W ...
    1204             : !> \param matrix_s ...
    1205             : !> \param kpoints ...
    1206             : !> \param mp2_env ...
    1207             : !> \param qs_env ...
    1208             : !> \param nkp_self_energy ...
    1209             : !> \param do_kpoints_cubic_RPA ...
    1210             : !> \param starts_array_mc ...
    1211             : !> \param ends_array_mc ...
    1212             : ! **************************************************************************************************
    1213        1430 :    SUBROUTINE compute_QP_energies(vec_Sigma_c_gw, count_ev_sc_GW, gw_corr_lev_occ, &
    1214         572 :                                   gw_corr_lev_tot, gw_corr_lev_virt, homo, &
    1215             :                                   nmo, num_fit_points, num_integ_points, &
    1216             :                                   unit_nr, do_apply_ic_corr_to_gw, do_im_time, &
    1217             :                                   do_periodic, do_ri_Sigma_x, &
    1218         286 :                                   first_cycle_periodic_correction, e_fermi, eps_filter, &
    1219         286 :                                   fermi_level_offset, delta_corr, Eigenval, &
    1220             :                                   Eigenval_last, Eigenval_scf, iter_sc_GW0, exit_ev_gw, tau_tj, tj, &
    1221             :                                   vec_omega_fit_gw, vec_Sigma_x_gw, ic_corr_list, &
    1222             :                                   weights_cos_tf_t_to_w, weights_sin_tf_t_to_w, &
    1223         286 :                                   fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, fm_mo_coeff_occ, &
    1224         424 :                                   fm_mo_coeff_virt, fm_scaled_dm_occ_tau, fm_scaled_dm_virt_tau, &
    1225             :                                   mo_coeff, fm_mat_W, para_env, para_env_RPA, mat_dm, mat_MinvVMinv, &
    1226             :                                   t_3c_O, t_3c_M, t_3c_overl_int_ao_mo, &
    1227         286 :                                   t_3c_O_compressed, t_3c_O_mo_compressed, &
    1228         286 :                                   t_3c_O_ind, t_3c_O_mo_ind, &
    1229         738 :                                   t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, matrix_berry_im_mo_mo, &
    1230             :                                   matrix_berry_re_mo_mo, mat_W, matrix_s, &
    1231             :                                   kpoints, mp2_env, qs_env, nkp_self_energy, do_kpoints_cubic_RPA, &
    1232         288 :                                   starts_array_mc, ends_array_mc)
    1233             : 
    1234             :       COMPLEX(KIND=dp), DIMENSION(:, :, :, :), &
    1235             :          INTENT(OUT)                                     :: vec_Sigma_c_gw
    1236             :       INTEGER, INTENT(IN)                                :: count_ev_sc_GW
    1237             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: gw_corr_lev_occ
    1238             :       INTEGER, INTENT(IN)                                :: gw_corr_lev_tot
    1239             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: gw_corr_lev_virt, homo
    1240             :       INTEGER, INTENT(IN)                                :: nmo, num_fit_points, num_integ_points, &
    1241             :                                                             unit_nr
    1242             :       LOGICAL, INTENT(IN)                                :: do_apply_ic_corr_to_gw, do_im_time, &
    1243             :                                                             do_periodic, do_ri_Sigma_x
    1244             :       LOGICAL, INTENT(INOUT) :: first_cycle_periodic_correction
    1245             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: e_fermi
    1246             :       REAL(KIND=dp), INTENT(IN)                          :: eps_filter, fermi_level_offset
    1247             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
    1248             :          INTENT(INOUT)                                   :: delta_corr
    1249             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT)   :: Eigenval
    1250             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
    1251             :          INTENT(INOUT)                                   :: Eigenval_last, Eigenval_scf
    1252             :       INTEGER, INTENT(IN)                                :: iter_sc_GW0
    1253             :       LOGICAL, INTENT(INOUT)                             :: exit_ev_gw
    1254             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
    1255             :          INTENT(INOUT)                                   :: tau_tj, tj, vec_omega_fit_gw
    1256             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
    1257             :          INTENT(INOUT)                                   :: vec_Sigma_x_gw
    1258             :       TYPE(one_dim_real_array), DIMENSION(2), INTENT(IN) :: ic_corr_list
    1259             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
    1260             :          INTENT(IN)                                      :: weights_cos_tf_t_to_w, &
    1261             :                                                             weights_sin_tf_t_to_w
    1262             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mo_coeff_occ_scaled, &
    1263             :                                                             fm_mo_coeff_virt_scaled
    1264             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: fm_mo_coeff_occ, fm_mo_coeff_virt
    1265             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_scaled_dm_occ_tau, &
    1266             :                                                             fm_scaled_dm_virt_tau, mo_coeff
    1267             :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
    1268             :          INTENT(IN)                                      :: fm_mat_W
    1269             :       TYPE(mp_para_env_type), POINTER                    :: para_env, para_env_RPA
    1270             :       TYPE(dbcsr_p_type), INTENT(IN)                     :: mat_dm, mat_MinvVMinv
    1271             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_3c_O
    1272             :       TYPE(dbt_type)                                     :: t_3c_M, t_3c_overl_int_ao_mo
    1273             :       TYPE(hfx_compression_type), ALLOCATABLE, &
    1274             :          DIMENSION(:, :, :), INTENT(INOUT)               :: t_3c_O_compressed
    1275             :       TYPE(hfx_compression_type), DIMENSION(:)           :: t_3c_O_mo_compressed
    1276             :       TYPE(block_ind_type), ALLOCATABLE, &
    1277             :          DIMENSION(:, :, :), INTENT(INOUT)               :: t_3c_O_ind
    1278             :       TYPE(two_dim_int_array), DIMENSION(:)              :: t_3c_O_mo_ind
    1279             :       TYPE(dbt_type), DIMENSION(:)                       :: t_3c_overl_int_gw_RI, &
    1280             :                                                             t_3c_overl_int_gw_AO
    1281             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_berry_im_mo_mo, &
    1282             :                                                             matrix_berry_re_mo_mo
    1283             :       TYPE(dbcsr_type), POINTER                          :: mat_W
    1284             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
    1285             :       TYPE(kpoint_type), POINTER                         :: kpoints
    1286             :       TYPE(mp2_type)                                     :: mp2_env
    1287             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1288             :       INTEGER, INTENT(IN)                                :: nkp_self_energy
    1289             :       LOGICAL, INTENT(IN)                                :: do_kpoints_cubic_RPA
    1290             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: starts_array_mc, ends_array_mc
    1291             : 
    1292             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_QP_energies'
    1293             : 
    1294             :       INTEGER :: count_ev_sc_GW_print, count_sc_GW0, count_sc_GW0_print, crossing_search, handle, &
    1295             :          idos, ikp, ispin, iunit, n_level_gw, ndos, nspins, num_points_corr, num_poles
    1296             :       LOGICAL                                            :: do_kpoints_Sigma, my_open_shell
    1297             :       REAL(KIND=dp) :: dos_lower_bound, dos_precision, dos_upper_bound, E_CBM_GW, E_CBM_GW_beta, &
    1298             :          E_CBM_SCF, E_CBM_SCF_beta, E_VBM_GW, E_VBM_GW_beta, E_VBM_SCF, E_VBM_SCF_beta, stop_crit
    1299         286 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: vec_gw_dos
    1300         286 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: m_value, vec_gw_energ, z_value
    1301             :       TYPE(cp_logger_type), POINTER                      :: logger
    1302             :       TYPE(kpoint_type), POINTER                         :: kpoints_Sigma
    1303             : 
    1304         286 :       CALL timeset(routineN, handle)
    1305             : 
    1306         286 :       nspins = SIZE(homo)
    1307         286 :       my_open_shell = (nspins == 2)
    1308             : 
    1309         286 :       do_kpoints_Sigma = mp2_env%ri_g0w0%do_kpoints_Sigma
    1310             : 
    1311         356 :       DO count_sc_GW0 = 1, iter_sc_GW0
    1312             : 
    1313             :          ! postprocessing for cubic scaling GW calculation
    1314         300 :          IF (do_im_time .AND. .NOT. do_kpoints_cubic_RPA .AND. .NOT. do_kpoints_Sigma) THEN
    1315          56 :             num_points_corr = mp2_env%ri_g0w0%num_omega_points
    1316             : 
    1317         118 :             DO ispin = 1, nspins
    1318             :                CALL compute_self_energy_cubic_gw(num_integ_points, nmo, tau_tj, tj, &
    1319             :                                                  matrix_s, fm_mo_coeff_occ(ispin), &
    1320             :                                                  fm_mo_coeff_virt(ispin), fm_mo_coeff_occ_scaled, &
    1321             :                                                  fm_mo_coeff_virt_scaled, fm_scaled_dm_occ_tau, &
    1322             :                                                  fm_scaled_dm_virt_tau, Eigenval(:, 1, ispin), eps_filter, &
    1323             :                                                  e_fermi(ispin), fm_mat_W, &
    1324             :                                                  gw_corr_lev_tot, gw_corr_lev_occ(ispin), gw_corr_lev_virt(ispin), homo(ispin), &
    1325             :                                                  count_ev_sc_GW, count_sc_GW0, &
    1326             :                                                  t_3c_overl_int_ao_mo, t_3c_O_mo_compressed(ispin), &
    1327             :                                                  t_3c_O_mo_ind(ispin)%array, &
    1328             :                                                  t_3c_overl_int_gw_RI(ispin), t_3c_overl_int_gw_AO(ispin), &
    1329             :                                                  mat_W, mat_MinvVMinv, mat_dm, &
    1330             :                                                  weights_cos_tf_t_to_w, weights_sin_tf_t_to_w, vec_Sigma_c_gw(:, :, :, ispin), &
    1331             :                                                  do_periodic, num_points_corr, delta_corr, qs_env, para_env, para_env_RPA, &
    1332             :                                                  mp2_env, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
    1333             :                                                  first_cycle_periodic_correction, kpoints, num_fit_points, mo_coeff, &
    1334         118 :                                                  do_ri_Sigma_x, vec_Sigma_x_gw(:, :, ispin), unit_nr, ispin)
    1335             :             END DO
    1336             : 
    1337             :          END IF
    1338             : 
    1339         282 :          IF (do_kpoints_Sigma) THEN
    1340             :             CALL compute_self_energy_cubic_gw_kpoints(num_integ_points, tau_tj, tj, &
    1341             :                                                       matrix_s, Eigenval(:, :, :), e_fermi, fm_mat_W, &
    1342             :                                                       gw_corr_lev_tot, gw_corr_lev_occ, gw_corr_lev_virt, homo, &
    1343             :                                                       count_ev_sc_GW, count_sc_GW0, &
    1344             :                                                       t_3c_O, t_3c_M, t_3c_O_compressed, t_3c_O_ind, &
    1345             :                                                       mat_W, mat_MinvVMinv, &
    1346             :                                                       weights_cos_tf_t_to_w, weights_sin_tf_t_to_w, vec_Sigma_c_gw(:, :, :, :), &
    1347             :                                                       qs_env, para_env, &
    1348             :                                                       mp2_env, num_fit_points, mo_coeff, &
    1349             :                                                       do_ri_Sigma_x, vec_Sigma_x_gw(:, :, :), unit_nr, nspins, &
    1350          18 :                                                       starts_array_mc, ends_array_mc, eps_filter)
    1351             : 
    1352             :          END IF
    1353             : 
    1354         300 :          IF (do_periodic .AND. mp2_env%ri_g0w0%do_average_deg_levels) THEN
    1355             : 
    1356          20 :             DO ispin = 1, nspins
    1357             :                CALL average_degenerate_levels(vec_Sigma_c_gw(:, :, :, ispin), &
    1358             :                                               Eigenval(1 + homo(ispin) - gw_corr_lev_occ(ispin): &
    1359             :                                                        homo(ispin) + gw_corr_lev_virt(ispin), 1, ispin), &
    1360          20 :                                               mp2_env%ri_g0w0%eps_eigenval)
    1361             :             END DO
    1362             :          END IF
    1363             : 
    1364         300 :          IF (.NOT. do_im_time) THEN
    1365      447494 :             CALL para_env%sum(vec_Sigma_c_gw)
    1366             :          END IF
    1367             : 
    1368         300 :          CALL para_env%sync()
    1369             : 
    1370         300 :          stop_crit = 1.0e-7
    1371         300 :          num_poles = mp2_env%ri_g0w0%num_poles
    1372         300 :          crossing_search = mp2_env%ri_g0w0%crossing_search
    1373             : 
    1374             :          ! arrays storing the correlation self-energy, stat. error and z-shot value
    1375        1500 :          ALLOCATE (vec_gw_energ(gw_corr_lev_tot, nkp_self_energy, nspins))
    1376        5562 :          vec_gw_energ = 0.0_dp
    1377        1200 :          ALLOCATE (z_value(gw_corr_lev_tot, nkp_self_energy, nspins))
    1378        5562 :          z_value = 0.0_dp
    1379        1200 :          ALLOCATE (m_value(gw_corr_lev_tot, nkp_self_energy, nspins))
    1380        5562 :          m_value = 0.0_dp
    1381         300 :          E_VBM_GW = -1.0E3
    1382         300 :          E_CBM_GW = 1.0E3
    1383         300 :          E_VBM_SCF = -1.0E3
    1384         300 :          E_CBM_SCF = 1.0E3
    1385         300 :          E_VBM_GW_beta = -1.0E3
    1386         300 :          E_CBM_GW_beta = 1.0E3
    1387         300 :          E_VBM_SCF_beta = -1.0E3
    1388         300 :          E_CBM_SCF_beta = 1.0E3
    1389             : 
    1390         300 :          ndos = 0
    1391         300 :          dos_precision = mp2_env%ri_g0w0%dos_prec
    1392         300 :          dos_upper_bound = mp2_env%ri_g0w0%dos_upper
    1393         300 :          dos_lower_bound = mp2_env%ri_g0w0%dos_lower
    1394             : 
    1395         300 :          IF (dos_lower_bound >= dos_upper_bound) THEN
    1396           0 :             CALL cp_abort(__LOCATION__, "Invalid settings for GW_DOS calculation!")
    1397             :          END IF
    1398             : 
    1399         300 :          IF (dos_precision /= 0) THEN
    1400           0 :             ndos = INT((dos_upper_bound - dos_lower_bound)/dos_precision)
    1401           0 :             ALLOCATE (vec_gw_dos(ndos))
    1402           0 :             vec_gw_dos = 0.0_dp
    1403             :          END IF
    1404             : 
    1405             :          ! for the normal code for molecules or Gamma only: nkp = 1
    1406         718 :          DO ikp = 1, nkp_self_energy
    1407             : 
    1408         418 :             kpoints_Sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
    1409             : 
    1410             :             ! fit the self-energy on imaginary frequency axis and evaluate the fit on the MO energy of the SCF
    1411        4574 :             DO n_level_gw = 1, gw_corr_lev_tot
    1412             :                ! processes perform different fits
    1413        4156 :                IF (MODULO(n_level_gw, para_env%num_pe) /= para_env%mepos) CYCLE
    1414             : 
    1415        2520 :                SELECT CASE (mp2_env%ri_g0w0%analytic_continuation)
    1416             :                CASE (gw_two_pole_model)
    1417             :                   CALL fit_and_continuation_2pole(vec_gw_energ(:, ikp, 1), vec_omega_fit_gw, &
    1418             :                                                   z_value(:, ikp, 1), m_value(:, ikp, 1), vec_Sigma_c_gw(:, :, ikp, 1), &
    1419             :                                                   mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 1, ikp), &
    1420             :                                                   Eigenval(:, ikp, 1), Eigenval_scf(:, ikp, 1), n_level_gw, &
    1421             :                                                   gw_corr_lev_occ(1), gw_corr_lev_virt(1), num_poles, &
    1422             :                                                   num_fit_points, crossing_search, homo(1), stop_crit, &
    1423         442 :                                                   fermi_level_offset, do_im_time)
    1424             : 
    1425             :                CASE (gw_pade_approx)
    1426             :                   CALL continuation_pade(vec_gw_energ(:, ikp, 1), vec_omega_fit_gw, &
    1427             :                                          z_value(:, ikp, 1), m_value(:, ikp, 1), vec_Sigma_c_gw(:, :, ikp, 1), &
    1428             :                                          mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 1, ikp), &
    1429             :                                          Eigenval(:, ikp, 1), Eigenval_scf(:, ikp, 1), &
    1430             :                                          mp2_env%ri_g0w0%do_hedin_shift, n_level_gw, &
    1431             :                                          gw_corr_lev_occ(1), gw_corr_lev_virt(1), mp2_env%ri_g0w0%nparam_pade, &
    1432             :                                          num_fit_points, crossing_search, homo(1), fermi_level_offset, &
    1433             :                                          do_im_time, mp2_env%ri_g0w0%print_self_energy, count_ev_sc_GW, &
    1434             :                                          vec_gw_dos, dos_lower_bound, dos_precision, ndos, &
    1435             :                                          mp2_env%ri_g0w0%min_level_self_energy, &
    1436             :                                          mp2_env%ri_g0w0%max_level_self_energy, mp2_env%ri_g0w0%dos_eta, &
    1437        1636 :                                          mp2_env%ri_g0w0%dos_min, mp2_env%ri_g0w0%dos_max)
    1438             :                CASE DEFAULT
    1439        2078 :                   CPABORT("Only two-model and Pade approximation are implemented.")
    1440             :                END SELECT
    1441             : 
    1442        2496 :                IF (my_open_shell) THEN
    1443         284 :                   SELECT CASE (mp2_env%ri_g0w0%analytic_continuation)
    1444             :                   CASE (gw_two_pole_model)
    1445             :                      CALL fit_and_continuation_2pole( &
    1446             :                         vec_gw_energ(:, ikp, 2), vec_omega_fit_gw, &
    1447             :                         z_value(:, ikp, 2), m_value(:, ikp, 2), vec_Sigma_c_gw(:, :, ikp, 2), &
    1448             :                         mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 2, ikp), &
    1449             :                         Eigenval(:, ikp, 2), Eigenval_scf(:, ikp, 2), n_level_gw, &
    1450             :                         gw_corr_lev_occ(2), gw_corr_lev_virt(2), num_poles, &
    1451             :                         num_fit_points, crossing_search, homo(2), stop_crit, &
    1452         126 :                         fermi_level_offset, do_im_time)
    1453             :                   CASE (gw_pade_approx)
    1454             :                      CALL continuation_pade(vec_gw_energ(:, ikp, 2), vec_omega_fit_gw, &
    1455             :                                             z_value(:, ikp, 2), m_value(:, ikp, 2), vec_Sigma_c_gw(:, :, ikp, 2), &
    1456             :                                             mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 2, ikp), &
    1457             :                                             Eigenval(:, ikp, 2), Eigenval_scf(:, ikp, 2), &
    1458             :                                             mp2_env%ri_g0w0%do_hedin_shift, n_level_gw, &
    1459             :                                             gw_corr_lev_occ(2), gw_corr_lev_virt(2), mp2_env%ri_g0w0%nparam_pade, &
    1460             :                                             num_fit_points, crossing_search, homo(2), &
    1461             :                                             fermi_level_offset, do_im_time, &
    1462             :                                             mp2_env%ri_g0w0%print_self_energy, count_ev_sc_GW, &
    1463             :                                             vec_gw_dos, dos_lower_bound, dos_precision, ndos, &
    1464             :                                             mp2_env%ri_g0w0%min_level_self_energy, &
    1465             :                                             mp2_env%ri_g0w0%max_level_self_energy, mp2_env%ri_g0w0%dos_eta, &
    1466          32 :                                             mp2_env%ri_g0w0%dos_min, mp2_env%ri_g0w0%dos_max)
    1467             :                   CASE DEFAULT
    1468         158 :                      CPABORT("Only two-pole model and Pade approximation are implemented.")
    1469             :                   END SELECT
    1470             : 
    1471             :                END IF
    1472             : 
    1473             :             END DO ! n_level_gw
    1474             : 
    1475         418 :             CALL para_env%sum(vec_gw_energ)
    1476         418 :             CALL para_env%sum(z_value)
    1477         418 :             CALL para_env%sum(m_value)
    1478             : 
    1479         418 :             IF (dos_precision /= 0.0_dp) THEN
    1480           0 :                CALL para_env%sum(vec_gw_dos)
    1481             :             END IF
    1482             : 
    1483         418 :             CALL check_NaN(vec_gw_energ, 0.0_dp)
    1484         418 :             CALL check_NaN(z_value, 1.0_dp)
    1485         418 :             CALL check_NaN(m_value, 0.0_dp)
    1486             : 
    1487         418 :             IF (do_im_time .OR. mp2_env%ri_g0w0%iter_sc_GW0 == 1) THEN
    1488         314 :                count_ev_sc_GW_print = count_ev_sc_GW
    1489         314 :                count_sc_GW0_print = count_sc_GW0
    1490             :             ELSE
    1491         104 :                count_ev_sc_GW_print = count_sc_GW0
    1492         104 :                count_sc_GW0_print = count_ev_sc_GW
    1493             :             END IF
    1494             : 
    1495             :             ! print the quasiparticle energies and update Eigenval in case you do eigenvalue self-consistent GW
    1496         718 :             IF (my_open_shell) THEN
    1497             : 
    1498             :                CALL print_and_update_for_ev_sc( &
    1499             :                   vec_gw_energ(:, ikp, 1), &
    1500             :                   z_value(:, ikp, 1), m_value(:, ikp, 1), mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 1, ikp), &
    1501             :                   Eigenval(:, ikp, 1), Eigenval_last(:, ikp, 1), Eigenval_scf(:, ikp, 1), &
    1502             :                   gw_corr_lev_occ(1), gw_corr_lev_virt(1), gw_corr_lev_tot, &
    1503             :                   crossing_search, homo(1), unit_nr, count_ev_sc_GW_print, count_sc_GW0_print, &
    1504          50 :                   ikp, nkp_self_energy, kpoints_Sigma, 1, E_VBM_GW, E_CBM_GW, E_VBM_SCF, E_CBM_SCF)
    1505             : 
    1506             :                CALL print_and_update_for_ev_sc( &
    1507             :                   vec_gw_energ(:, ikp, 2), &
    1508             :                   z_value(:, ikp, 2), m_value(:, ikp, 2), mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 2, ikp), &
    1509             :                   Eigenval(:, ikp, 2), Eigenval_last(:, ikp, 2), Eigenval_scf(:, ikp, 2), &
    1510             :                   gw_corr_lev_occ(2), gw_corr_lev_virt(2), gw_corr_lev_tot, &
    1511             :                   crossing_search, homo(2), unit_nr, count_ev_sc_GW_print, count_sc_GW0_print, &
    1512          50 :                   ikp, nkp_self_energy, kpoints_Sigma, 2, E_VBM_GW_beta, E_CBM_GW_beta, E_VBM_SCF_beta, E_CBM_SCF_beta)
    1513             : 
    1514          50 :                IF (do_apply_ic_corr_to_gw .AND. count_ev_sc_GW == 1) THEN
    1515             : 
    1516             :                   CALL apply_ic_corr(Eigenval(:, ikp, 1), Eigenval_scf(:, ikp, 1), ic_corr_list(1)%array, &
    1517             :                                      gw_corr_lev_occ(1), gw_corr_lev_virt(1), gw_corr_lev_tot, &
    1518           0 :                                      homo(1), nmo, unit_nr, do_alpha=.TRUE.)
    1519             : 
    1520             :                   CALL apply_ic_corr(Eigenval(:, ikp, 2), Eigenval_scf(:, ikp, 2), ic_corr_list(2)%array, &
    1521             :                                      gw_corr_lev_occ(2), gw_corr_lev_virt(2), gw_corr_lev_tot, &
    1522           0 :                                      homo(2), nmo, unit_nr, do_beta=.TRUE.)
    1523             : 
    1524             :                END IF
    1525             : 
    1526             :             ELSE
    1527             : 
    1528             :                CALL print_and_update_for_ev_sc( &
    1529             :                   vec_gw_energ(:, ikp, 1), &
    1530             :                   z_value(:, ikp, 1), m_value(:, ikp, 1), mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 1, ikp), &
    1531             :                   Eigenval(:, ikp, 1), Eigenval_last(:, ikp, 1), Eigenval_scf(:, ikp, 1), &
    1532             :                   gw_corr_lev_occ(1), gw_corr_lev_virt(1), gw_corr_lev_tot, &
    1533             :                   crossing_search, homo(1), unit_nr, count_ev_sc_GW_print, count_sc_GW0_print, &
    1534         368 :                   ikp, nkp_self_energy, kpoints_Sigma, 0, E_VBM_GW, E_CBM_GW, E_VBM_SCF, E_CBM_SCF)
    1535             : 
    1536         368 :                IF (do_apply_ic_corr_to_gw .AND. count_ev_sc_GW == 1) THEN
    1537             : 
    1538             :                   CALL apply_ic_corr(Eigenval(:, ikp, 1), Eigenval_scf(:, ikp, 1), ic_corr_list(1)%array, &
    1539             :                                      gw_corr_lev_occ(1), gw_corr_lev_virt(1), gw_corr_lev_tot, &
    1540           0 :                                      homo(1), nmo, unit_nr)
    1541             : 
    1542             :                END IF
    1543             : 
    1544             :             END IF
    1545             : 
    1546             :          END DO ! ikp
    1547             : 
    1548         300 :          IF (nkp_self_energy > 1 .AND. unit_nr > 0) THEN
    1549             : 
    1550             :             CALL print_gaps(E_VBM_SCF, E_CBM_SCF, E_VBM_SCF_beta, E_CBM_SCF_beta, &
    1551           9 :                             E_VBM_GW, E_CBM_GW, E_VBM_GW_beta, E_CBM_GW_beta, my_open_shell, unit_nr)
    1552             : 
    1553             :          END IF
    1554             : 
    1555             :          ! Decide whether to add spin-orbit splitting of bands, spin-orbit coupling strength comes from
    1556             :          ! Hartwigsen parametrization (1999) of GTH pseudopotentials
    1557         300 :          IF (mp2_env%ri_g0w0%soc_type /= soc_none) THEN
    1558             :             CALL calculate_and_print_soc(qs_env, Eigenval_scf, Eigenval_scf, gw_corr_lev_occ, gw_corr_lev_virt, &
    1559           2 :                                          homo, unit_nr, do_soc_gw=.FALSE., do_soc_scf=.TRUE.)
    1560             :             CALL calculate_and_print_soc(qs_env, Eigenval, Eigenval_scf, gw_corr_lev_occ, gw_corr_lev_virt, &
    1561           2 :                                          homo, unit_nr, do_soc_gw=.TRUE., do_soc_scf=.FALSE.)
    1562             :          END IF
    1563             : 
    1564         300 :          logger => cp_get_default_logger()
    1565         300 :          IF (logger%para_env%is_source()) THEN
    1566         297 :             iunit = cp_logger_get_default_unit_nr()
    1567             :          ELSE
    1568           3 :             iunit = -1
    1569             :          END IF
    1570             : 
    1571         300 :          IF (dos_precision /= 0.0_dp) THEN
    1572           0 :             IF (iunit > 0) THEN
    1573           0 :                CALL open_file('spectral.dat', unit_number=iunit, file_status="UNKNOWN", file_action="WRITE")
    1574           0 :                DO idos = 1, ndos
    1575             :                   ! 1/pi
    1576             :                   ! [1/Hartree] -> [1/evolt]
    1577           0 :                   WRITE (iunit, '(E17.10, E17.10)') (dos_lower_bound + REAL(idos - 1, KIND=dp)*dos_precision)*evolt, &
    1578           0 :                      vec_gw_dos(idos)/evolt/pi
    1579             :                END DO
    1580           0 :                CALL close_file(iunit)
    1581             :             END IF
    1582           0 :             DEALLOCATE (vec_gw_dos)
    1583             :          END IF
    1584             : 
    1585         300 :          DEALLOCATE (z_value)
    1586         300 :          DEALLOCATE (m_value)
    1587         300 :          DEALLOCATE (vec_gw_energ)
    1588             : 
    1589         300 :          exit_ev_gw = .FALSE.
    1590             : 
    1591             :          ! if HOMO-LUMO gap differs by less than mp2_env%ri_g0w0%eps_sc_iter, exit ev sc GW loop
    1592         300 :          IF (ABS(Eigenval(homo(1), 1, 1) - Eigenval_last(homo(1), 1, 1) - &
    1593             :                  Eigenval(homo(1) + 1, 1, 1) + Eigenval_last(homo(1) + 1, 1, 1)) &
    1594             :              < mp2_env%ri_g0w0%eps_iter) THEN
    1595          32 :             IF (count_sc_GW0 == 1) exit_ev_gw = .TRUE.
    1596             :             EXIT
    1597             :          END IF
    1598             : 
    1599         558 :          DO ispin = 1, nspins
    1600             :             CALL shift_unshifted_levels(Eigenval(:, 1, ispin), Eigenval_last(:, 1, ispin), gw_corr_lev_occ(ispin), &
    1601         558 :                                         gw_corr_lev_virt(ispin), homo(ispin), nmo)
    1602             :          END DO
    1603             : 
    1604         268 :          IF (do_im_time .AND. do_kpoints_Sigma .AND. mp2_env%ri_g0w0%print_local_bandgap) THEN
    1605           2 :             CALL print_local_bandgap(qs_env, Eigenval, gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), "GW")
    1606           2 :             CALL print_local_bandgap(qs_env, Eigenval_scf, gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), "DFT")
    1607             :          END IF
    1608             : 
    1609             :          ! in case of N^4 scaling GW, the scGW0 cycle is the eigenvalue sc cycle
    1610         324 :          IF (.NOT. do_im_time) EXIT
    1611             : 
    1612             :       END DO ! scGW0
    1613             : 
    1614         286 :       CALL timestop(handle)
    1615             : 
    1616         286 :    END SUBROUTINE compute_QP_energies
    1617             : 
    1618             : ! **************************************************************************************************
    1619             : !> \brief ...
    1620             : !> \param qs_env ...
    1621             : !> \param Eigenval ...
    1622             : !> \param Eigenval_scf ...
    1623             : !> \param gw_corr_lev_occ ...
    1624             : !> \param gw_corr_lev_virt ...
    1625             : !> \param homo ...
    1626             : !> \param unit_nr ...
    1627             : !> \param do_soc_gw ...
    1628             : !> \param do_soc_scf ...
    1629             : ! **************************************************************************************************
    1630           4 :    SUBROUTINE calculate_and_print_soc(qs_env, Eigenval, Eigenval_scf, gw_corr_lev_occ, gw_corr_lev_virt, &
    1631           4 :                                       homo, unit_nr, do_soc_gw, do_soc_scf)
    1632             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1633             :       REAL(KIND=dp), DIMENSION(:, :, :)                  :: Eigenval, Eigenval_scf
    1634             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: gw_corr_lev_occ, gw_corr_lev_virt, homo
    1635             :       INTEGER                                            :: unit_nr
    1636             :       LOGICAL                                            :: do_soc_gw, do_soc_scf
    1637             : 
    1638             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_and_print_soc'
    1639             : 
    1640             :       INTEGER :: handle, i_dim, i_glob, i_row, ikp, j_col, j_glob, n_level_gw, nao, ncol_local, &
    1641             :          nder, nkind, nkp_self_energy, nrow_local, periodic(3), size_real_space
    1642           4 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: index0
    1643           4 :       INTEGER, DIMENSION(:), POINTER                     :: col_indices, row_indices
    1644             :       LOGICAL                                            :: calculate_forces, use_virial
    1645             :       REAL(KIND=dp) :: avg_occ_QP_shift, avg_virt_QP_shift, E_CBM_GW_SOC, E_GAP_GW_SOC, E_HOMO, &
    1646             :          E_HOMO_GW_SOC, E_i, E_j, E_LUMO, E_LUMO_GW_SOC, E_VBM_GW_SOC, E_window, eps_ppnl
    1647           4 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: eigenvalues_without_soc_sorted
    1648           4 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: eigenvalues
    1649           4 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1650             :       TYPE(cell_type), POINTER                           :: cell
    1651             :       TYPE(cp_cfm_type)                                  :: cfm_mat_h_double, cfm_mat_h_ks, &
    1652             :                                                             cfm_mat_s_double, cfm_mat_work_double, &
    1653             :                                                             cfm_mo_coeff, cfm_mo_coeff_double
    1654             :       TYPE(cp_fm_type), POINTER                          :: imos, rmos
    1655           4 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s, matrix_s_desymm
    1656           4 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: mat_VSOC_l_nosymm, mat_VSOC_lx_kp, &
    1657           4 :                                                             mat_VSOC_ly_kp, mat_VSOC_lz_kp, &
    1658           4 :                                                             matrix_dummy, matrix_l, &
    1659           4 :                                                             matrix_pot_dummy
    1660             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1661             :       TYPE(kpoint_type), POINTER                         :: kpoints_Sigma
    1662             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1663             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1664           4 :          POINTER                                         :: sab_orb, sap_ppnl
    1665           4 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1666           4 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    1667           4 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1668             :       TYPE(scf_control_type), POINTER                    :: scf_control
    1669             :       TYPE(virial_type), POINTER                         :: virial
    1670             : 
    1671           4 :       CALL timeset(routineN, handle)
    1672             : 
    1673           4 :       CPASSERT(do_soc_gw .NEQV. do_soc_scf)
    1674             : 
    1675             :       CALL get_qs_env(qs_env=qs_env, &
    1676             :                       matrix_s=matrix_s, &
    1677             :                       para_env=para_env, &
    1678             :                       qs_kind_set=qs_kind_set, &
    1679             :                       sab_orb=sab_orb, &
    1680             :                       atomic_kind_set=atomic_kind_set, &
    1681             :                       particle_set=particle_set, &
    1682             :                       sap_ppnl=sap_ppnl, &
    1683             :                       dft_control=dft_control, &
    1684             :                       cell=cell, &
    1685             :                       nkind=nkind, &
    1686           4 :                       scf_control=scf_control)
    1687             : 
    1688           4 :       calculate_forces = .FALSE.
    1689           4 :       use_virial = .FALSE.
    1690           4 :       nder = 0
    1691           4 :       eps_ppnl = dft_control%qs_control%eps_ppnl
    1692             : 
    1693           4 :       CALL get_cell(cell=cell, periodic=periodic)
    1694             : 
    1695           4 :       size_real_space = 3**(periodic(1) + periodic(2) + periodic(3))
    1696             : 
    1697           4 :       NULLIFY (matrix_l)
    1698           4 :       CALL dbcsr_allocate_matrix_set(matrix_l, 3, 1)
    1699          16 :       DO i_dim = 1, 3
    1700          12 :          ALLOCATE (matrix_l(i_dim, 1)%matrix)
    1701             :          CALL dbcsr_create(matrix_l(i_dim, 1)%matrix, template=matrix_s(1)%matrix, &
    1702          12 :                            matrix_type=dbcsr_type_antisymmetric)
    1703          12 :          CALL cp_dbcsr_alloc_block_from_nbl(matrix_l(i_dim, 1)%matrix, sab_orb)
    1704          16 :          CALL dbcsr_set(matrix_l(i_dim, 1)%matrix, 0.0_dp)
    1705             :       END DO
    1706             : 
    1707           4 :       NULLIFY (matrix_pot_dummy)
    1708           4 :       CALL dbcsr_allocate_matrix_set(matrix_pot_dummy, 1, 1)
    1709           4 :       ALLOCATE (matrix_pot_dummy(1, 1)%matrix)
    1710           4 :       CALL dbcsr_create(matrix_pot_dummy(1, 1)%matrix, template=matrix_s(1)%matrix)
    1711           4 :       CALL cp_dbcsr_alloc_block_from_nbl(matrix_pot_dummy(1, 1)%matrix, sab_orb)
    1712           4 :       CALL dbcsr_set(matrix_pot_dummy(1, 1)%matrix, 0.0_dp)
    1713             : 
    1714             :       CALL build_core_ppnl(matrix_pot_dummy, matrix_dummy, force, virial, calculate_forces, use_virial, nder, &
    1715             :                            qs_kind_set, atomic_kind_set, particle_set, sab_orb, sap_ppnl, eps_ppnl, &
    1716           4 :                            nimages=1, basis_type="ORB", matrix_l=matrix_l)
    1717             : 
    1718           4 :       CALL alloc_mat_set_2d(mat_VSOC_l_nosymm, 3, size_real_space, matrix_s(1)%matrix, explicitly_no_symmetry=.TRUE.)
    1719          16 :       DO i_dim = 1, 3
    1720          16 :          CALL dbcsr_desymmetrize(matrix_l(i_dim, 1)%matrix, mat_VSOC_l_nosymm(i_dim, 1)%matrix)
    1721             :       END DO
    1722             : 
    1723           4 :       kpoints_Sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
    1724             : 
    1725           4 :       CALL mat_kp_from_mat_gamma(qs_env, mat_VSOC_lx_kp, mat_VSOC_l_nosymm(1, 1)%matrix, kpoints_Sigma, 1, .FALSE.)
    1726           4 :       CALL mat_kp_from_mat_gamma(qs_env, mat_VSOC_ly_kp, mat_VSOC_l_nosymm(2, 1)%matrix, kpoints_Sigma, 1, .FALSE.)
    1727           4 :       CALL mat_kp_from_mat_gamma(qs_env, mat_VSOC_lz_kp, mat_VSOC_l_nosymm(3, 1)%matrix, kpoints_Sigma, 1, .FALSE.)
    1728             : 
    1729           4 :       nkp_self_energy = kpoints_Sigma%nkp
    1730             : 
    1731           4 :       CALL get_mo_set(kpoints_Sigma%kp_env(1)%kpoint_env%mos(1, 1), mo_coeff=rmos)
    1732             : 
    1733           4 :       CALL create_cfm_double_row_col_size(rmos, cfm_mat_h_double)
    1734           4 :       CALL create_cfm_double_row_col_size(rmos, cfm_mat_s_double)
    1735           4 :       CALL create_cfm_double_row_col_size(rmos, cfm_mo_coeff_double)
    1736           4 :       CALL create_cfm_double_row_col_size(rmos, cfm_mat_work_double)
    1737             : 
    1738           4 :       CALL cp_cfm_set_all(cfm_mo_coeff_double, z_zero)
    1739             : 
    1740           4 :       CALL cp_cfm_create(cfm_mo_coeff, rmos%matrix_struct)
    1741           4 :       CALL cp_cfm_create(cfm_mat_h_ks, rmos%matrix_struct)
    1742             : 
    1743           4 :       CALL cp_fm_get_info(matrix=rmos, nrow_global=nao)
    1744             : 
    1745           4 :       NULLIFY (matrix_s_desymm)
    1746           4 :       CALL dbcsr_allocate_matrix_set(matrix_s_desymm, 1)
    1747           4 :       ALLOCATE (matrix_s_desymm(1)%matrix)
    1748             :       CALL dbcsr_create(matrix=matrix_s_desymm(1)%matrix, template=matrix_s(1)%matrix, &
    1749           4 :                         matrix_type=dbcsr_type_no_symmetry)
    1750           4 :       CALL dbcsr_desymmetrize(matrix_s(1)%matrix, matrix_s_desymm(1)%matrix)
    1751             : 
    1752          12 :       ALLOCATE (eigenvalues(2*nao))
    1753          76 :       eigenvalues = 0.0_dp
    1754           8 :       ALLOCATE (eigenvalues_without_soc_sorted(2*nao))
    1755             : 
    1756           4 :       E_window = qs_env%mp2_env%ri_g0w0%soc_energy_window
    1757           4 :       IF (unit_nr > 0) THEN
    1758           2 :          WRITE (unit_nr, '(T3,A)') ' '
    1759           2 :          WRITE (unit_nr, '(T3,A)') '------------------------------------------------------------------------------'
    1760           2 :          WRITE (unit_nr, '(T3,A)') ' '
    1761           2 :          WRITE (unit_nr, '(T3,A,F42.1)') 'GW_SOC_INFO | SOC energy window (eV)', E_window*evolt
    1762             :       END IF
    1763             : 
    1764           4 :       E_VBM_GW_SOC = -1000.0_dp
    1765           4 :       E_CBM_GW_SOC = 1000.0_dp
    1766             : 
    1767          20 :       DO ikp = 1, nkp_self_energy
    1768             : 
    1769          16 :          CALL get_mo_set(kpoints_Sigma%kp_env(ikp)%kpoint_env%mos(1, 1), mo_coeff=rmos)
    1770          16 :          CALL get_mo_set(kpoints_Sigma%kp_env(ikp)%kpoint_env%mos(2, 1), mo_coeff=imos)
    1771          16 :          CALL cp_fm_to_cfm(rmos, imos, cfm_mo_coeff)
    1772             : 
    1773             :          ! ispin = 1
    1774             :          avg_occ_QP_shift = SUM(Eigenval(homo(1) - gw_corr_lev_occ(1) + 1:homo(1), ikp, 1) - &
    1775          32 :                                 Eigenval_scf(homo(1) - gw_corr_lev_occ(1) + 1:homo(1), ikp, 1))/gw_corr_lev_occ(1)
    1776             :          avg_virt_QP_shift = SUM(Eigenval(homo(1):homo(1) + gw_corr_lev_virt(1), ikp, 1) - &
    1777          48 :                                  Eigenval_scf(homo(1):homo(1) + gw_corr_lev_virt(1), ikp, 1))/gw_corr_lev_virt(1)
    1778             : 
    1779          16 :          IF (gw_corr_lev_occ(1) < homo(1)) THEN
    1780             :             Eigenval(1:homo(1) - gw_corr_lev_occ(1), ikp, 1) = Eigenval_scf(1:homo(1) - gw_corr_lev_occ(1), ikp, 1) &
    1781          64 :                                                                + avg_occ_QP_shift
    1782             :          END IF
    1783          16 :          IF (gw_corr_lev_virt(1) < nao - homo(1) + 1) THEN
    1784             :             Eigenval(homo(1) + gw_corr_lev_virt(1) + 1:nao, ikp, 1) = Eigenval_scf(homo(1) + gw_corr_lev_virt(1) + 1:nao, ikp, 1) &
    1785          80 :                                                                       + avg_virt_QP_shift
    1786             :          END IF
    1787             : 
    1788          16 :          CALL cp_cfm_set_all(cfm_mat_h_double, z_zero)
    1789          16 :          CALL add_dbcsr_submatrix(cfm_mat_h_double, mat_VSOC_lx_kp(ikp, 1:2), cfm_mat_h_ks, nao + 1, 1, z_one, .TRUE.)
    1790          16 :          CALL add_dbcsr_submatrix(cfm_mat_h_double, mat_VSOC_ly_kp(ikp, 1:2), cfm_mat_h_ks, nao + 1, 1, gaussi, .TRUE.)
    1791          16 :          CALL add_dbcsr_submatrix(cfm_mat_h_double, mat_VSOC_lz_kp(ikp, 1:2), cfm_mat_h_ks, 1, 1, z_one, .FALSE.)
    1792          16 :          CALL add_dbcsr_submatrix(cfm_mat_h_double, mat_VSOC_lz_kp(ikp, 1:2), cfm_mat_h_ks, nao + 1, nao + 1, -z_one, .FALSE.)
    1793             : 
    1794             :          ! trafo to MO basis
    1795        2896 :          cfm_mo_coeff_double%local_data = z_zero
    1796          16 :          CALL add_cfm_submatrix(cfm_mo_coeff_double, cfm_mo_coeff, 1, 1)
    1797          16 :          CALL add_cfm_submatrix(cfm_mo_coeff_double, cfm_mo_coeff, nao + 1, nao + 1)
    1798             : 
    1799             :          CALL cp_cfm_get_info(matrix=cfm_mat_h_double, &
    1800             :                               nrow_local=nrow_local, &
    1801             :                               ncol_local=ncol_local, &
    1802             :                               row_indices=row_indices, &
    1803          16 :                               col_indices=col_indices)
    1804             : 
    1805             :          CALL parallel_gemm(transa="N", transb="N", m=2*nao, n=2*nao, k=2*nao, alpha=z_one, &
    1806             :                             matrix_a=cfm_mat_h_double, matrix_b=cfm_mo_coeff_double, beta=z_zero, &
    1807          16 :                             matrix_c=cfm_mat_work_double)
    1808             : 
    1809             :          CALL parallel_gemm(transa="C", transb="N", m=2*nao, n=2*nao, k=2*nao, alpha=z_one, &
    1810             :                             matrix_a=cfm_mo_coeff_double, matrix_b=cfm_mat_work_double, beta=z_zero, &
    1811          16 :                             matrix_c=cfm_mat_h_double)
    1812             : 
    1813             :          CALL cp_cfm_get_info(matrix=cfm_mat_h_double, &
    1814             :                               nrow_local=nrow_local, &
    1815             :                               ncol_local=ncol_local, &
    1816             :                               row_indices=row_indices, &
    1817          16 :                               col_indices=col_indices)
    1818             : 
    1819          16 :          CALL cp_cfm_set_all(cfm_mat_s_double, z_zero)
    1820             : 
    1821          16 :          E_HOMO = Eigenval(homo(1), ikp, 1)
    1822          16 :          E_LUMO = Eigenval(homo(1) + 1, ikp, 1)
    1823             : 
    1824          16 :          CALL para_env%sync()
    1825             : 
    1826         160 :          DO i_row = 1, nrow_local
    1827        2752 :          DO j_col = 1, ncol_local
    1828        2592 :             i_glob = row_indices(i_row)
    1829        2592 :             j_glob = col_indices(j_col)
    1830        2592 :             IF (i_glob .LE. nao) THEN
    1831        1296 :                E_i = Eigenval(i_glob, ikp, 1)
    1832             :             ELSE
    1833        1296 :                E_i = Eigenval(i_glob - nao, ikp, 1)
    1834             :             END IF
    1835        2592 :             IF (j_glob .LE. nao) THEN
    1836        1296 :                E_j = Eigenval(j_glob, ikp, 1)
    1837             :             ELSE
    1838        1296 :                E_j = Eigenval(j_glob - nao, ikp, 1)
    1839             :             END IF
    1840             : 
    1841             :             ! add eigenvalues to diagonal entries
    1842        2736 :             IF (i_glob == j_glob) THEN
    1843         144 :                cfm_mat_h_double%local_data(i_row, j_col) = cfm_mat_h_double%local_data(i_row, j_col) + E_i*z_one
    1844         144 :                cfm_mat_s_double%local_data(i_row, j_col) = z_one
    1845             :             ELSE
    1846             :                IF (E_i < E_HOMO - 0.5_dp*E_window .OR. E_i > E_LUMO + 0.5_dp*E_window .OR. &
    1847        2448 :                    E_j < E_HOMO - 0.5_dp*E_window .OR. E_j > E_LUMO + 0.5_dp*E_window) THEN
    1848        2000 :                   cfm_mat_h_double%local_data(i_row, j_col) = z_zero
    1849             :                END IF
    1850             :             END IF
    1851             : 
    1852             :          END DO
    1853             :          END DO
    1854             : 
    1855          16 :          CALL para_env%sync()
    1856             : 
    1857         304 :          eigenvalues = 0.0_dp
    1858             :          CALL cp_cfm_geeig_canon(cfm_mat_h_double, cfm_mat_s_double, cfm_mo_coeff_double, eigenvalues, &
    1859          16 :                                  cfm_mat_work_double, scf_control%eps_eigval)
    1860             : 
    1861         160 :          eigenvalues_without_soc_sorted(1:nao) = Eigenval(:, ikp, 1)
    1862         160 :          eigenvalues_without_soc_sorted(nao + 1:2*nao) = Eigenval(:, ikp, 1)
    1863          48 :          ALLOCATE (index0(2*nao))
    1864          16 :          CALL sort(eigenvalues_without_soc_sorted, 2*nao, index0)
    1865          16 :          DEALLOCATE (index0)
    1866             : 
    1867          64 :          E_HOMO_GW_SOC = MAXVAL(eigenvalues(2*homo(1) - 2*gw_corr_lev_occ(1) + 1:2*homo(1)))
    1868          64 :          E_LUMO_GW_SOC = MINVAL(eigenvalues(2*homo(1) + 1:2*homo(1) + 2*gw_corr_lev_virt(1)))
    1869          16 :          E_GAP_GW_SOC = E_LUMO_GW_SOC - E_HOMO_GW_SOC
    1870          16 :          IF (E_HOMO_GW_SOC > E_VBM_GW_SOC) E_VBM_GW_SOC = E_HOMO_GW_SOC
    1871          16 :          IF (E_LUMO_GW_SOC < E_CBM_GW_SOC) E_CBM_GW_SOC = E_LUMO_GW_SOC
    1872             : 
    1873          52 :          IF (unit_nr > 0) THEN
    1874           8 :             WRITE (unit_nr, '(T3,A)') ' '
    1875           8 :             WRITE (unit_nr, '(T3,A7,I3,A3,I3,A8,3F7.3,A12,3F7.3)') 'Kpoint ', ikp, '  /', nkp_self_energy, &
    1876           8 :                '   xkp =', kpoints_Sigma%xkp(1, ikp), kpoints_Sigma%xkp(2, ikp), kpoints_Sigma%xkp(3, ikp), &
    1877          16 :                '  and  xkp =', -kpoints_Sigma%xkp(1, ikp), -kpoints_Sigma%xkp(2, ikp), -kpoints_Sigma%xkp(3, ikp)
    1878           8 :             WRITE (unit_nr, '(T3,A)') ' '
    1879           8 :             IF (do_soc_gw) THEN
    1880           4 :                WRITE (unit_nr, '(T3,A)') ' '
    1881           4 :                WRITE (unit_nr, '(T3,A,F13.4)') 'GW_SOC_INFO | Average GW shift of occupied levels compared to SCF', &
    1882           8 :                   avg_occ_QP_shift*evolt
    1883           4 :                WRITE (unit_nr, '(T3,A,F11.4)') 'GW_SOC_INFO | Average GW shift of unoccupied levels compared to SCF', &
    1884           8 :                   avg_virt_QP_shift*evolt
    1885           4 :                WRITE (unit_nr, '(T3,A)') ' '
    1886           4 :                WRITE (unit_nr, '(T3,2A)') 'Molecular orbital   E_GW with SOC (eV)   E_GW without SOC (eV)  SOC shift (eV)'
    1887             :             ELSE
    1888           4 :                WRITE (unit_nr, '(T3,2A)') 'Molecular orbital  E_SCF with SOC (eV)  E_SCF without SOC (eV)  SOC shift (eV)'
    1889             :             END IF
    1890             : 
    1891          24 :             DO n_level_gw = 2*(homo(1) - gw_corr_lev_occ(1)) + 1, 2*homo(1)
    1892          16 :                WRITE (unit_nr, '(T3,I4,A,3F21.4)') n_level_gw, ' ( occ )   ', eigenvalues(n_level_gw)*evolt, &
    1893          16 :                   eigenvalues_without_soc_sorted(n_level_gw)*evolt, &
    1894          40 :                   (eigenvalues(n_level_gw) - eigenvalues_without_soc_sorted(n_level_gw))*evolt
    1895             :             END DO
    1896          24 :             DO n_level_gw = 2*homo(1) + 1, 2*(homo(1) + gw_corr_lev_virt(1))
    1897          16 :                WRITE (unit_nr, '(T3,I4,A,3F21.4)') n_level_gw, ' ( vir )   ', eigenvalues(n_level_gw)*evolt, &
    1898          16 :                   eigenvalues_without_soc_sorted(n_level_gw)*evolt, &
    1899          40 :                   (eigenvalues(n_level_gw) - eigenvalues_without_soc_sorted(n_level_gw))*evolt
    1900             :             END DO
    1901           8 :             WRITE (unit_nr, '(T3,A)') ' '
    1902           8 :             IF (do_soc_gw) THEN
    1903           4 :                WRITE (unit_nr, '(T3,A,F38.4)') 'GW+SOC direct gap at current kpoint (eV)', E_GAP_GW_SOC*evolt
    1904             :             ELSE
    1905           4 :                WRITE (unit_nr, '(T3,A,F37.4)') 'SCF+SOC direct gap at current kpoint (eV)', E_GAP_GW_SOC*evolt
    1906             :             END IF
    1907           8 :             WRITE (unit_nr, '(T3,A)') ' '
    1908           8 :             WRITE (unit_nr, '(T3,A)') '------------------------------------------------------------------------------'
    1909             :          END IF
    1910             : 
    1911             :       END DO
    1912             : 
    1913           4 :       IF (unit_nr > 0) THEN
    1914           2 :          WRITE (unit_nr, '(T3,A)') ' '
    1915           2 :          IF (do_soc_gw) THEN
    1916           1 :             WRITE (unit_nr, '(T3,A,F46.4)') 'GW+SOC valence band maximum (eV)', E_VBM_GW_SOC*evolt
    1917           1 :             WRITE (unit_nr, '(T3,A,F43.4)') 'GW+SOC conduction band minimum (eV)', E_CBM_GW_SOC*evolt
    1918           1 :             WRITE (unit_nr, '(T3,A,F59.4)') 'GW+SOC bandgap (eV)', (E_CBM_GW_SOC - E_VBM_GW_SOC)*evolt
    1919             :          ELSE
    1920           1 :             WRITE (unit_nr, '(T3,A,F45.4)') 'SCF+SOC valence band maximum (eV)', E_VBM_GW_SOC*evolt
    1921           1 :             WRITE (unit_nr, '(T3,A,F42.4)') 'SCF+SOC conduction band minimum (eV)', E_CBM_GW_SOC*evolt
    1922           1 :             WRITE (unit_nr, '(T3,A,F58.4)') 'SCF+SOC bandgap (eV)', (E_CBM_GW_SOC - E_VBM_GW_SOC)*evolt
    1923             :          END IF
    1924             :       END IF
    1925             : 
    1926           4 :       CALL dbcsr_deallocate_matrix_set(matrix_l)
    1927           4 :       CALL dbcsr_deallocate_matrix_set(mat_VSOC_l_nosymm)
    1928           4 :       CALL dbcsr_deallocate_matrix_set(matrix_pot_dummy)
    1929           4 :       CALL dbcsr_deallocate_matrix_set(mat_VSOC_lx_kp)
    1930           4 :       CALL dbcsr_deallocate_matrix_set(mat_VSOC_ly_kp)
    1931           4 :       CALL dbcsr_deallocate_matrix_set(mat_VSOC_lz_kp)
    1932           4 :       CALL dbcsr_deallocate_matrix_set(matrix_s_desymm)
    1933             : 
    1934           4 :       CALL cp_cfm_release(cfm_mat_h_double)
    1935           4 :       CALL cp_cfm_release(cfm_mat_s_double)
    1936           4 :       CALL cp_cfm_release(cfm_mo_coeff_double)
    1937           4 :       CALL cp_cfm_release(cfm_mo_coeff)
    1938           4 :       CALL cp_cfm_release(cfm_mat_h_ks)
    1939           4 :       CALL cp_cfm_release(cfm_mat_work_double)
    1940           4 :       DEALLOCATE (eigenvalues)
    1941             : 
    1942           4 :       CALL timestop(handle)
    1943             : 
    1944          12 :    END SUBROUTINE calculate_and_print_soc
    1945             : 
    1946             : ! **************************************************************************************************
    1947             : !> \brief ...
    1948             : !> \param cfm_mat_target ...
    1949             : !> \param mat_source ...
    1950             : !> \param cfm_source_template ...
    1951             : !> \param nstart_row ...
    1952             : !> \param nstart_col ...
    1953             : !> \param factor ...
    1954             : !> \param add_also_herm_conj ...
    1955             : ! **************************************************************************************************
    1956          64 :    SUBROUTINE add_dbcsr_submatrix(cfm_mat_target, mat_source, cfm_source_template, &
    1957             :                                   nstart_row, nstart_col, factor, add_also_herm_conj)
    1958             :       TYPE(cp_cfm_type)                                  :: cfm_mat_target
    1959             :       TYPE(dbcsr_p_type), DIMENSION(:)                   :: mat_source
    1960             :       TYPE(cp_cfm_type)                                  :: cfm_source_template
    1961             :       INTEGER                                            :: nstart_row, nstart_col
    1962             :       COMPLEX(KIND=dp)                                   :: factor
    1963             :       LOGICAL                                            :: add_also_herm_conj
    1964             : 
    1965             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'add_dbcsr_submatrix'
    1966             : 
    1967             :       INTEGER                                            :: handle, nao
    1968             :       TYPE(cp_cfm_type)                                  :: cfm_mat_work_double, &
    1969             :                                                             cfm_mat_work_double_2
    1970             :       TYPE(cp_fm_type)                                   :: fm_mat_work_double_im, &
    1971             :                                                             fm_mat_work_double_re, fm_mat_work_im, &
    1972             :                                                             fm_mat_work_re
    1973             : 
    1974          64 :       CALL timeset(routineN, handle)
    1975             : 
    1976          64 :       CALL cp_fm_create(fm_mat_work_double_re, cfm_mat_target%matrix_struct)
    1977          64 :       CALL cp_fm_create(fm_mat_work_double_im, cfm_mat_target%matrix_struct)
    1978          64 :       CALL cp_fm_set_all(fm_mat_work_double_re, 0.0_dp)
    1979          64 :       CALL cp_fm_set_all(fm_mat_work_double_im, 0.0_dp)
    1980             : 
    1981          64 :       CALL cp_cfm_create(cfm_mat_work_double, cfm_mat_target%matrix_struct)
    1982          64 :       CALL cp_cfm_create(cfm_mat_work_double_2, cfm_mat_target%matrix_struct)
    1983          64 :       CALL cp_cfm_set_all(cfm_mat_work_double, z_zero)
    1984          64 :       CALL cp_cfm_set_all(cfm_mat_work_double_2, z_zero)
    1985             : 
    1986          64 :       CALL cp_fm_create(fm_mat_work_re, cfm_source_template%matrix_struct)
    1987          64 :       CALL cp_fm_create(fm_mat_work_im, cfm_source_template%matrix_struct)
    1988             : 
    1989          64 :       CALL copy_dbcsr_to_fm(mat_source(1)%matrix, fm_mat_work_re)
    1990          64 :       CALL copy_dbcsr_to_fm(mat_source(2)%matrix, fm_mat_work_im)
    1991             : 
    1992          64 :       CALL cp_cfm_get_info(cfm_source_template, nrow_global=nao)
    1993             : 
    1994             :       CALL cp_fm_to_fm_submat(msource=fm_mat_work_re, mtarget=fm_mat_work_double_re, &
    1995             :                               nrow=nao, ncol=nao, &
    1996             :                               s_firstrow=1, s_firstcol=1, &
    1997          64 :                               t_firstrow=nstart_row, t_firstcol=nstart_col)
    1998             : 
    1999             :       CALL cp_fm_to_fm_submat(msource=fm_mat_work_im, mtarget=fm_mat_work_double_im, &
    2000             :                               nrow=nao, ncol=nao, &
    2001             :                               s_firstrow=1, s_firstcol=1, &
    2002          64 :                               t_firstrow=nstart_row, t_firstcol=nstart_col)
    2003             : 
    2004          64 :       CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_work_double, z_one, fm_mat_work_double_re)
    2005          64 :       CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_work_double, gaussi, fm_mat_work_double_im)
    2006             : 
    2007          64 :       CALL cp_cfm_scale(factor, cfm_mat_work_double)
    2008             : 
    2009          64 :       CALL cp_cfm_scale_and_add(z_one, cfm_mat_target, z_one, cfm_mat_work_double)
    2010             : 
    2011          64 :       IF (add_also_herm_conj) THEN
    2012          32 :          CALL cp_cfm_transpose(cfm_mat_work_double, 'C', cfm_mat_work_double_2)
    2013          32 :          CALL cp_cfm_scale_and_add(z_one, cfm_mat_target, z_one, cfm_mat_work_double_2)
    2014             :       END IF
    2015             : 
    2016          64 :       CALL cp_fm_release(fm_mat_work_double_re)
    2017          64 :       CALL cp_fm_release(fm_mat_work_double_im)
    2018          64 :       CALL cp_cfm_release(cfm_mat_work_double)
    2019          64 :       CALL cp_cfm_release(cfm_mat_work_double_2)
    2020          64 :       CALL cp_fm_release(fm_mat_work_re)
    2021          64 :       CALL cp_fm_release(fm_mat_work_im)
    2022             : 
    2023          64 :       CALL timestop(handle)
    2024             : 
    2025          64 :    END SUBROUTINE
    2026             : 
    2027             : ! **************************************************************************************************
    2028             : !> \brief ...
    2029             : !> \param cfm_mat_target ...
    2030             : !> \param cfm_mat_source ...
    2031             : !> \param nstart_row ...
    2032             : !> \param nstart_col ...
    2033             : ! **************************************************************************************************
    2034         192 :    SUBROUTINE add_cfm_submatrix(cfm_mat_target, cfm_mat_source, nstart_row, nstart_col)
    2035             : 
    2036             :       TYPE(cp_cfm_type)                                  :: cfm_mat_target, cfm_mat_source
    2037             :       INTEGER                                            :: nstart_row, nstart_col
    2038             : 
    2039             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'add_cfm_submatrix'
    2040             : 
    2041             :       INTEGER                                            :: handle, nao
    2042             :       TYPE(cp_fm_type)                                   :: fm_mat_work_double_im, &
    2043             :                                                             fm_mat_work_double_re, fm_mat_work_im, &
    2044             :                                                             fm_mat_work_re
    2045             : 
    2046          32 :       CALL timeset(routineN, handle)
    2047             : 
    2048          32 :       CALL cp_fm_create(fm_mat_work_double_re, cfm_mat_target%matrix_struct)
    2049          32 :       CALL cp_fm_create(fm_mat_work_double_im, cfm_mat_target%matrix_struct)
    2050          32 :       CALL cp_fm_set_all(fm_mat_work_double_re, 0.0_dp)
    2051          32 :       CALL cp_fm_set_all(fm_mat_work_double_im, 0.0_dp)
    2052             : 
    2053          32 :       CALL cp_fm_create(fm_mat_work_re, cfm_mat_source%matrix_struct)
    2054          32 :       CALL cp_fm_create(fm_mat_work_im, cfm_mat_source%matrix_struct)
    2055          32 :       CALL cp_cfm_to_fm(cfm_mat_source, fm_mat_work_re, fm_mat_work_im)
    2056             : 
    2057          32 :       CALL cp_cfm_get_info(cfm_mat_source, nrow_global=nao)
    2058             : 
    2059             :       CALL cp_fm_to_fm_submat(msource=fm_mat_work_re, mtarget=fm_mat_work_double_re, &
    2060             :                               nrow=nao, ncol=nao, &
    2061             :                               s_firstrow=1, s_firstcol=1, &
    2062          32 :                               t_firstrow=nstart_row, t_firstcol=nstart_col)
    2063             : 
    2064             :       CALL cp_fm_to_fm_submat(msource=fm_mat_work_im, mtarget=fm_mat_work_double_im, &
    2065             :                               nrow=nao, ncol=nao, &
    2066             :                               s_firstrow=1, s_firstcol=1, &
    2067          32 :                               t_firstrow=nstart_row, t_firstcol=nstart_col)
    2068             : 
    2069          32 :       CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_target, z_one, fm_mat_work_double_re)
    2070          32 :       CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_target, gaussi, fm_mat_work_double_im)
    2071             : 
    2072          32 :       CALL cp_fm_release(fm_mat_work_double_re)
    2073          32 :       CALL cp_fm_release(fm_mat_work_double_im)
    2074          32 :       CALL cp_fm_release(fm_mat_work_re)
    2075          32 :       CALL cp_fm_release(fm_mat_work_im)
    2076             : 
    2077          32 :       CALL timestop(handle)
    2078             : 
    2079          32 :    END SUBROUTINE add_cfm_submatrix
    2080             : 
    2081             : ! **************************************************************************************************
    2082             : !> \brief ...
    2083             : !> \param fm_orig ...
    2084             : !> \param cfm_double ...
    2085             : ! **************************************************************************************************
    2086          48 :    SUBROUTINE create_cfm_double_row_col_size(fm_orig, cfm_double)
    2087             :       TYPE(cp_fm_type)                                   :: fm_orig
    2088             :       TYPE(cp_cfm_type)                                  :: cfm_double
    2089             : 
    2090             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'create_cfm_double_row_col_size'
    2091             : 
    2092             :       INTEGER                                            :: handle, ncol_global_orig, &
    2093             :                                                             nrow_global_orig
    2094             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct_double
    2095             : 
    2096          16 :       CALL timeset(routineN, handle)
    2097             : 
    2098          16 :       CALL cp_fm_get_info(matrix=fm_orig, nrow_global=nrow_global_orig, ncol_global=ncol_global_orig)
    2099             : 
    2100             :       CALL cp_fm_struct_create(fm_struct_double, &
    2101             :                                nrow_global=2*nrow_global_orig, &
    2102             :                                ncol_global=2*ncol_global_orig, &
    2103          16 :                                template_fmstruct=fm_orig%matrix_struct)
    2104             : 
    2105          16 :       CALL cp_cfm_create(cfm_double, fm_struct_double)
    2106             : 
    2107          16 :       CALL cp_fm_struct_release(fm_struct_double)
    2108             : 
    2109          16 :       CALL timestop(handle)
    2110             : 
    2111          16 :    END SUBROUTINE
    2112             : 
    2113             : ! **************************************************************************************************
    2114             : !> \brief ...
    2115             : !> \param E_VBM_SCF ...
    2116             : !> \param E_CBM_SCF ...
    2117             : !> \param E_VBM_SCF_beta ...
    2118             : !> \param E_CBM_SCF_beta ...
    2119             : !> \param E_VBM_GW ...
    2120             : !> \param E_CBM_GW ...
    2121             : !> \param E_VBM_GW_beta ...
    2122             : !> \param E_CBM_GW_beta ...
    2123             : !> \param my_open_shell ...
    2124             : !> \param unit_nr ...
    2125             : ! **************************************************************************************************
    2126           9 :    SUBROUTINE print_gaps(E_VBM_SCF, E_CBM_SCF, E_VBM_SCF_beta, E_CBM_SCF_beta, &
    2127             :                          E_VBM_GW, E_CBM_GW, E_VBM_GW_beta, E_CBM_GW_beta, my_open_shell, unit_nr)
    2128             : 
    2129             :       REAL(KIND=dp)                                      :: E_VBM_SCF, E_CBM_SCF, E_VBM_SCF_beta, &
    2130             :                                                             E_CBM_SCF_beta, E_VBM_GW, E_CBM_GW, &
    2131             :                                                             E_VBM_GW_beta, E_CBM_GW_beta
    2132             :       LOGICAL                                            :: my_open_shell
    2133             :       INTEGER                                            :: unit_nr
    2134             : 
    2135           9 :       IF (my_open_shell) THEN
    2136           2 :          WRITE (unit_nr, '(T3,A)') ' '
    2137           2 :          WRITE (unit_nr, '(T3,A,F43.4)') 'Alpha SCF valence band maximum (eV)', E_VBM_SCF*evolt
    2138           2 :          WRITE (unit_nr, '(T3,A,F40.4)') 'Alpha SCF conduction band minimum (eV)', E_CBM_SCF*evolt
    2139           2 :          WRITE (unit_nr, '(T3,A,F56.4)') 'Alpha SCF bandgap (eV)', (E_CBM_SCF - E_VBM_SCF)*evolt
    2140           2 :          WRITE (unit_nr, '(T3,A)') ' '
    2141           2 :          WRITE (unit_nr, '(T3,A,F44.4)') 'Beta SCF valence band maximum (eV)', E_VBM_SCF_beta*evolt
    2142           2 :          WRITE (unit_nr, '(T3,A,F41.4)') 'Beta SCF conduction band minimum (eV)', E_CBM_SCF_beta*evolt
    2143           2 :          WRITE (unit_nr, '(T3,A,F57.4)') 'Beta SCF bandgap (eV)', (E_CBM_SCF_beta - E_VBM_SCF_beta)*evolt
    2144           2 :          WRITE (unit_nr, '(T3,A)') ' '
    2145           2 :          WRITE (unit_nr, '(T3,A,F44.4)') 'Alpha GW valence band maximum (eV)', E_VBM_GW*evolt
    2146           2 :          WRITE (unit_nr, '(T3,A,F41.4)') 'Alpha GW conduction band minimum (eV)', E_CBM_GW*evolt
    2147           2 :          WRITE (unit_nr, '(T3,A,F57.4)') 'Alpha GW bandgap (eV)', (E_CBM_GW - E_VBM_GW)*evolt
    2148           2 :          WRITE (unit_nr, '(T3,A)') ' '
    2149           2 :          WRITE (unit_nr, '(T3,A,F45.4)') 'Beta GW valence band maximum (eV)', E_VBM_GW_beta*evolt
    2150           2 :          WRITE (unit_nr, '(T3,A,F42.4)') 'Beta GW conduction band minimum (eV)', E_CBM_GW_beta*evolt
    2151           2 :          WRITE (unit_nr, '(T3,A,F58.4)') 'Beta GW bandgap (eV)', (E_CBM_GW_beta - E_VBM_GW_beta)*evolt
    2152             :       ELSE
    2153           7 :          WRITE (unit_nr, '(T3,A)') ' '
    2154           7 :          WRITE (unit_nr, '(T3,A,F49.4)') 'SCF valence band maximum (eV)', E_VBM_SCF*evolt
    2155           7 :          WRITE (unit_nr, '(T3,A,F46.4)') 'SCF conduction band minimum (eV)', E_CBM_SCF*evolt
    2156           7 :          WRITE (unit_nr, '(T3,A,F62.4)') 'SCF bandgap (eV)', (E_CBM_SCF - E_VBM_SCF)*evolt
    2157           7 :          WRITE (unit_nr, '(T3,A)') ' '
    2158           7 :          WRITE (unit_nr, '(T3,A,F50.4)') 'GW valence band maximum (eV)', E_VBM_GW*evolt
    2159           7 :          WRITE (unit_nr, '(T3,A,F47.4)') 'GW conduction band minimum (eV)', E_CBM_GW*evolt
    2160           7 :          WRITE (unit_nr, '(T3,A,F63.4)') 'GW bandgap (eV)', (E_CBM_GW - E_VBM_GW)*evolt
    2161             :       END IF
    2162             : 
    2163           9 :    END SUBROUTINE print_gaps
    2164             : 
    2165             : ! **************************************************************************************************
    2166             : !> \brief ...
    2167             : !> \param array ...
    2168             : !> \param real_value ...
    2169             : ! **************************************************************************************************
    2170        1254 :    SUBROUTINE check_NaN(array, real_value)
    2171             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
    2172             :          INTENT(INOUT)                                   :: array
    2173             :       REAL(KIND=dp), INTENT(IN)                          :: real_value
    2174             : 
    2175             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'check_NaN'
    2176             : 
    2177             :       INTEGER                                            :: handle, i, j, k
    2178             : 
    2179        1254 :       CALL timeset(routineN, handle)
    2180             : 
    2181       13722 :       DO i = 1, SIZE(array, 1)
    2182       31710 :       DO j = 1, SIZE(array, 2)
    2183       50736 :       DO k = 1, SIZE(array, 3)
    2184             : 
    2185             :          ! check for NaN
    2186       38268 :          IF (array(i, j, k) .NE. array(i, j, k)) array(i, j, k) = real_value
    2187             : 
    2188             :       END DO
    2189             :       END DO
    2190             :       END DO
    2191             : 
    2192        1254 :       CALL timestop(handle)
    2193             : 
    2194        1254 :    END SUBROUTINE
    2195             : 
    2196             : ! **************************************************************************************************
    2197             : !> \brief ...
    2198             : !> \param qs_env ...
    2199             : !> \param Eigenval ...
    2200             : !> \param gw_corr_lev_occ ...
    2201             : !> \param gw_corr_lev_virt ...
    2202             : !> \param homo ...
    2203             : !> \param dft_gw_char ...
    2204             : ! **************************************************************************************************
    2205           4 :    SUBROUTINE print_local_bandgap(qs_env, Eigenval, gw_corr_lev_occ, gw_corr_lev_virt, homo, dft_gw_char)
    2206             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2207             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: Eigenval
    2208             :       INTEGER                                            :: gw_corr_lev_occ, gw_corr_lev_virt, homo
    2209             :       CHARACTER(len=*)                                   :: dft_gw_char
    2210             : 
    2211             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'print_local_bandgap'
    2212             : 
    2213             :       INTEGER                                            :: handle, i_E
    2214             :       TYPE(pw_c1d_gs_type)                               :: rho_g_dummy
    2215             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    2216             :       TYPE(pw_r3d_rs_type)                               :: E_CBM_rspace, E_gap_rspace, E_VBM_rspace
    2217           4 :       TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:)    :: LDOS
    2218             : 
    2219           4 :       CALL timeset(routineN, handle)
    2220             : 
    2221           4 :       CALL create_real_space_grids(E_gap_rspace, E_VBM_rspace, E_CBM_rspace, rho_g_dummy, LDOS, auxbas_pw_pool, qs_env)
    2222             : 
    2223             :       CALL calculate_E_gap_rspace(E_gap_rspace, E_VBM_rspace, E_CBM_rspace, rho_g_dummy, &
    2224           4 :                                   LDOS, qs_env, Eigenval, gw_corr_lev_occ, gw_corr_lev_virt, homo, dft_gw_char)
    2225             : 
    2226           4 :       CALL auxbas_pw_pool%give_back_pw(E_gap_rspace)
    2227           4 :       CALL auxbas_pw_pool%give_back_pw(E_VBM_rspace)
    2228           4 :       CALL auxbas_pw_pool%give_back_pw(E_CBM_rspace)
    2229           4 :       CALL auxbas_pw_pool%give_back_pw(rho_g_dummy)
    2230          20 :       DO i_E = 1, SIZE(LDOS)
    2231          20 :          CALL auxbas_pw_pool%give_back_pw(LDOS(i_E))
    2232             :       END DO
    2233           4 :       DEALLOCATE (LDOS)
    2234             : 
    2235           4 :       CALL timestop(handle)
    2236             : 
    2237           4 :    END SUBROUTINE print_local_bandgap
    2238             : 
    2239             : ! **************************************************************************************************
    2240             : !> \brief ...
    2241             : !> \param E_gap_rspace ...
    2242             : !> \param E_VBM_rspace ...
    2243             : !> \param E_CBM_rspace ...
    2244             : !> \param rho_g_dummy ...
    2245             : !> \param LDOS ...
    2246             : !> \param qs_env ...
    2247             : !> \param Eigenval ...
    2248             : !> \param gw_corr_lev_occ ...
    2249             : !> \param gw_corr_lev_virt ...
    2250             : !> \param homo ...
    2251             : !> \param dft_gw_char ...
    2252             : ! **************************************************************************************************
    2253           4 :    SUBROUTINE calculate_E_gap_rspace(E_gap_rspace, E_VBM_rspace, E_CBM_rspace, rho_g_dummy, &
    2254           4 :                                      LDOS, qs_env, Eigenval, gw_corr_lev_occ, gw_corr_lev_virt, homo, dft_gw_char)
    2255             :       TYPE(pw_r3d_rs_type)                               :: E_gap_rspace, E_VBM_rspace, E_CBM_rspace
    2256             :       TYPE(pw_c1d_gs_type)                               :: rho_g_dummy
    2257             :       TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:)    :: LDOS
    2258             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2259             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: Eigenval
    2260             :       INTEGER                                            :: gw_corr_lev_occ, gw_corr_lev_virt, homo
    2261             :       CHARACTER(len=*)                                   :: dft_gw_char
    2262             : 
    2263             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_E_gap_rspace'
    2264             : 
    2265             :       INTEGER :: handle, i_E, i_img, i_spin, i_x, i_y, i_z, ikp, imo, n_E, n_E_occ, n_x_end, &
    2266             :          n_x_start, n_y_end, n_y_start, n_z_end, n_z_start, nimg, nkp, nkp_self_energy
    2267             :       REAL(KIND=dp)                                      :: avg_LDOS_occ, avg_LDOS_virt, d_E, E_CBM, &
    2268             :                                                             E_CBM_at_k, E_diff, E_VBM, E_VBM_at_k
    2269           4 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: E_array
    2270           4 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: occupation
    2271             :       TYPE(cp_fm_struct_type), POINTER                   :: matrix_struct
    2272           4 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:)        :: fm_work
    2273           4 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s, rho_ao
    2274           4 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: rho_ao_weighted
    2275             :       TYPE(dft_control_type), POINTER                    :: dft_control
    2276             :       TYPE(kpoint_type), POINTER                         :: kpoints_Sigma
    2277             :       TYPE(mp2_type), POINTER                            :: mp2_env
    2278             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2279             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    2280           4 :          POINTER                                         :: sab_orb
    2281             :       TYPE(particle_list_type), POINTER                  :: particles
    2282             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    2283             :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
    2284             :       TYPE(qs_subsys_type), POINTER                      :: subsys
    2285             :       TYPE(section_vals_type), POINTER                   :: gw_section
    2286             : 
    2287           4 :       CALL timeset(routineN, handle)
    2288             : 
    2289             :       CALL get_qs_env(qs_env=qs_env, para_env=para_env, mp2_env=mp2_env, ks_env=ks_env, matrix_s=matrix_s, &
    2290           4 :                       scf_env=scf_env, sab_orb=sab_orb, dft_control=dft_control, subsys=subsys)
    2291             : 
    2292             :       ! compute valence band maximum (VBM) and conduction band minimum (CBM)
    2293           4 :       nkp = SIZE(Eigenval, 2)
    2294           4 :       E_VBM = -1.0E3_dp
    2295           4 :       E_CBM = 1.0E3_dp
    2296             : 
    2297          36 :       DO ikp = 1, nkp
    2298             : 
    2299          96 :          E_VBM_at_k = MAXVAL(Eigenval(homo - gw_corr_lev_occ + 1:homo, ikp, 1))
    2300          32 :          IF (E_VBM_at_k > E_VBM) E_VBM = E_VBM_at_k
    2301             : 
    2302          96 :          E_CBM_at_k = MINVAL(Eigenval(homo + 1:homo + gw_corr_lev_virt, ikp, 1))
    2303          36 :          IF (E_CBM_at_k < E_CBM) E_CBM = E_CBM_at_k
    2304             : 
    2305             :       END DO
    2306             : 
    2307           4 :       d_E = mp2_env%ri_g0w0%energy_spacing_print_loc_bandgap
    2308             : 
    2309           4 :       n_E = INT(mp2_env%ri_g0w0%energy_window_print_loc_bandgap/d_E)
    2310             : 
    2311           4 :       n_E_occ = n_E/2
    2312          12 :       ALLOCATE (E_array(n_E))
    2313          12 :       DO i_E = 1, n_E_occ
    2314          12 :          E_array(i_E) = E_VBM - REAL(n_E_occ - i_E, KIND=dp)*d_E
    2315             :       END DO
    2316          12 :       DO i_E = n_E_occ + 1, n_E
    2317          12 :          E_array(i_E) = E_CBM + REAL(i_E - n_E_occ - 1, KIND=dp)*d_E
    2318             :       END DO
    2319             : 
    2320           4 :       kpoints_Sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
    2321             : 
    2322           4 :       nkp_self_energy = kpoints_Sigma%nkp
    2323           4 :       CPASSERT(nkp == nkp_self_energy)
    2324             : 
    2325           4 :       kpoints_Sigma%sab_nl => sab_orb
    2326             : 
    2327           4 :       DEALLOCATE (kpoints_Sigma%cell_to_index)
    2328             :       NULLIFY (kpoints_Sigma%cell_to_index)
    2329           4 :       CALL kpoint_init_cell_index(kpoints_Sigma, sab_orb, para_env, dft_control)
    2330             : 
    2331         424 :       nimg = MAXVAL(kpoints_Sigma%cell_to_index)
    2332             : 
    2333           4 :       NULLIFY (rho_ao_weighted)
    2334           4 :       CALL dbcsr_allocate_matrix_set(rho_ao_weighted, 2, nimg)
    2335             : 
    2336          12 :       DO i_spin = 1, 2
    2337         236 :          DO i_img = 1, nimg
    2338         224 :             ALLOCATE (rho_ao_weighted(i_spin, i_img)%matrix)
    2339         224 :             CALL dbcsr_create(matrix=rho_ao_weighted(i_spin, i_img)%matrix, template=matrix_s(1)%matrix)
    2340         224 :             CALL cp_dbcsr_alloc_block_from_nbl(rho_ao_weighted(i_spin, i_img)%matrix, sab_orb)
    2341         232 :             CALL dbcsr_set(rho_ao_weighted(i_spin, i_img)%matrix, 0.0_dp)
    2342             :          END DO
    2343             :       END DO
    2344             : 
    2345         124 :       ALLOCATE (fm_work(nimg))
    2346           4 :       matrix_struct => kpoints_Sigma%kp_env(1)%kpoint_env%mos(1, 1)%mo_coeff%matrix_struct
    2347         116 :       DO i_img = 1, nimg
    2348         116 :          CALL cp_fm_create(fm_work(i_img), matrix_struct)
    2349             :       END DO
    2350             : 
    2351          20 :       DO i_E = 1, n_E
    2352             : 
    2353             :          ! occupation = weight factor for computing LDOS
    2354         144 :          DO ikp = 1, nkp
    2355             :             CALL get_mo_set(kpoints_Sigma%kp_env(ikp)%kpoint_env%mos(1, 1), &
    2356         128 :                             occupation_numbers=occupation)
    2357             : 
    2358        3072 :             occupation(:) = 0.0_dp
    2359         400 :             DO imo = homo - gw_corr_lev_occ + 1, homo + gw_corr_lev_virt
    2360         256 :                E_diff = E_array(i_E) - Eigenval(imo, ikp, 1)
    2361         384 :                occupation(imo) = EXP(-(E_diff/d_E)**2)
    2362             :             END DO
    2363             : 
    2364             :          END DO
    2365             : 
    2366             :          CALL get_mo_set(kpoints_Sigma%kp_env(1)%kpoint_env%mos(1, 1), &
    2367          16 :                          occupation_numbers=occupation)
    2368             : 
    2369             :          ! density matrices
    2370          16 :          CALL kpoint_density_matrices(kpoints_Sigma)
    2371             : 
    2372             :          ! density matrices in real space
    2373             :          CALL kpoint_density_transform(kpoints_Sigma, rho_ao_weighted, .FALSE., &
    2374          16 :                                        matrix_s(1)%matrix, sab_orb, fm_work)
    2375             : 
    2376          16 :          rho_ao => rho_ao_weighted(1, :)
    2377             : 
    2378             :          CALL calculate_rho_elec(matrix_p_kp=rho_ao, &
    2379             :                                  rho=LDOS(i_E), &
    2380             :                                  rho_gspace=rho_g_dummy, &
    2381          16 :                                  ks_env=ks_env)
    2382             : 
    2383          52 :          DO i_spin = 1, 2
    2384         944 :             DO i_img = 1, nimg
    2385         928 :                CALL dbcsr_set(rho_ao_weighted(i_spin, i_img)%matrix, 0.0_dp)
    2386             :             END DO
    2387             :          END DO
    2388             : 
    2389             :       END DO
    2390             : 
    2391           4 :       n_x_start = LBOUND(LDOS(1)%array, 1)
    2392           4 :       n_x_end = UBOUND(LDOS(1)%array, 1)
    2393           4 :       n_y_start = LBOUND(LDOS(1)%array, 2)
    2394           4 :       n_y_end = UBOUND(LDOS(1)%array, 2)
    2395           4 :       n_z_start = LBOUND(LDOS(1)%array, 3)
    2396           4 :       n_z_end = UBOUND(LDOS(1)%array, 3)
    2397             : 
    2398           4 :       CALL pw_zero(E_VBM_rspace)
    2399           4 :       CALL pw_zero(E_CBM_rspace)
    2400             : 
    2401          68 :       DO i_x = n_x_start, n_x_end
    2402        2116 :          DO i_y = n_y_start, n_y_end
    2403       94272 :             DO i_z = n_z_start, n_z_end
    2404             :                ! compute average occ and virt LDOS
    2405             :                avg_LDOS_occ = 0.0_dp
    2406      276480 :                DO i_E = 1, n_E_occ
    2407      276480 :                   avg_LDOS_occ = avg_LDOS_occ + LDOS(i_E)%array(i_x, i_y, i_z)
    2408             :                END DO
    2409       92160 :                avg_LDOS_occ = avg_LDOS_occ/REAL(n_E_occ, KIND=dp)
    2410             : 
    2411       92160 :                avg_LDOS_virt = 0.0_dp
    2412      276480 :                DO i_E = n_E_occ + 1, n_E
    2413      276480 :                   avg_LDOS_virt = avg_LDOS_virt + LDOS(i_E)%array(i_x, i_y, i_z)
    2414             :                END DO
    2415       92160 :                avg_LDOS_virt = avg_LDOS_virt/REAL(n_E - n_E_occ, KIND=dp)
    2416             : 
    2417             :                ! compute local valence band maximum (VBM)
    2418      117630 :                DO i_E = n_E_occ, 1, -1
    2419      117630 :                   IF (LDOS(i_E)%array(i_x, i_y, i_z) > mp2_env%ri_g0w0%ldos_thresh_print_loc_bandgap*avg_LDOS_occ) THEN
    2420       79632 :                      E_VBM_rspace%array(i_x, i_y, i_z) = E_array(i_E)
    2421       79632 :                      EXIT
    2422             :                   END IF
    2423             :                END DO
    2424             : 
    2425             :                ! compute local valence band maximum (VBM)
    2426       94304 :                DO i_E = n_E_occ + 1, n_E
    2427       92256 :                   IF (LDOS(i_E)%array(i_x, i_y, i_z) > mp2_env%ri_g0w0%ldos_thresh_print_loc_bandgap*avg_LDOS_virt) THEN
    2428       92112 :                      E_CBM_rspace%array(i_x, i_y, i_z) = E_array(i_E)
    2429       92112 :                      EXIT
    2430             :                   END IF
    2431             :                END DO
    2432             : 
    2433             :             END DO
    2434             :          END DO
    2435             :       END DO
    2436             : 
    2437           4 :       CALL pw_scale(E_VBM_rspace, evolt)
    2438           4 :       CALL pw_scale(E_CBM_rspace, evolt)
    2439             : 
    2440           4 :       CALL pw_copy(E_CBM_rspace, E_gap_rspace)
    2441           4 :       CALL pw_axpy(E_VBM_rspace, E_gap_rspace, -1.0_dp)
    2442             : 
    2443           4 :       gw_section => section_vals_get_subs_vals(qs_env%input, "DFT%XC%WF_CORRELATION%RI_RPA%GW")
    2444           4 :       CALL qs_subsys_get(subsys, particles=particles)
    2445             : 
    2446           4 :       CALL print_file(E_gap_rspace, dft_gw_char//"_Gap_in_eV", gw_section, particles, mp2_env)
    2447           4 :       CALL print_file(E_VBM_rspace, dft_gw_char//"_VBM_in_eV", gw_section, particles, mp2_env)
    2448           4 :       CALL print_file(E_CBM_rspace, dft_gw_char//"_CBM_in_eV", gw_section, particles, mp2_env)
    2449           4 :       CALL print_file(LDOS(n_E_occ), dft_gw_char//"_LDOS_VBM_in_eV", gw_section, particles, mp2_env)
    2450           4 :       CALL print_file(LDOS(n_E_occ + 1), dft_gw_char//"_LDOS_CBM_in_eV", gw_section, particles, mp2_env)
    2451             : 
    2452           4 :       CALL dbcsr_deallocate_matrix_set(rho_ao_weighted)
    2453             : 
    2454           4 :       CALL cp_fm_release(fm_work)
    2455             : 
    2456           4 :       DEALLOCATE (E_array)
    2457             : 
    2458           4 :       NULLIFY (kpoints_Sigma%sab_nl)
    2459             : 
    2460           4 :       CALL timestop(handle)
    2461             : 
    2462           8 :    END SUBROUTINE calculate_E_gap_rspace
    2463             : 
    2464             : ! **************************************************************************************************
    2465             : !> \brief ...
    2466             : !> \param pw_print ...
    2467             : !> \param middle_name ...
    2468             : !> \param gw_section ...
    2469             : !> \param particles ...
    2470             : !> \param mp2_env ...
    2471             : ! **************************************************************************************************
    2472          20 :    SUBROUTINE print_file(pw_print, middle_name, gw_section, particles, mp2_env)
    2473             :       TYPE(pw_r3d_rs_type)                               :: pw_print
    2474             :       CHARACTER(len=*)                                   :: middle_name
    2475             :       TYPE(section_vals_type), POINTER                   :: gw_section
    2476             :       TYPE(particle_list_type), POINTER                  :: particles
    2477             :       TYPE(mp2_type), POINTER                            :: mp2_env
    2478             : 
    2479             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'print_file'
    2480             : 
    2481             :       INTEGER                                            :: handle, unit_nr_cube
    2482             :       LOGICAL                                            :: mpi_io
    2483             :       TYPE(cp_logger_type), POINTER                      :: logger
    2484             : 
    2485          20 :       CALL timeset(routineN, handle)
    2486             : 
    2487          20 :       NULLIFY (logger)
    2488          20 :       logger => cp_get_default_logger()
    2489          20 :       mpi_io = .TRUE.
    2490             :       unit_nr_cube = cp_print_key_unit_nr(logger, gw_section, "PRINT%LOCAL_BANDGAP", extension=".cube", &
    2491          20 :                                           middle_name=middle_name, file_form="FORMATTED", mpi_io=mpi_io)
    2492             :       CALL cp_pw_to_cube(pw_print, unit_nr_cube, middle_name, particles=particles, &
    2493          20 :                          stride=mp2_env%ri_g0w0%stride_loc_bandgap, mpi_io=mpi_io)
    2494             :       CALL cp_print_key_finished_output(unit_nr_cube, logger, gw_section, &
    2495          20 :                                         "PRINT%LOCAL_BANDGAP", mpi_io=mpi_io)
    2496             : 
    2497          20 :       CALL timestop(handle)
    2498             : 
    2499          20 :    END SUBROUTINE print_file
    2500             : 
    2501             : ! **************************************************************************************************
    2502             : !> \brief ...
    2503             : !> \param E_gap_rspace ...
    2504             : !> \param E_VBM_rspace ...
    2505             : !> \param E_CBM_rspace ...
    2506             : !> \param rho_g_dummy ...
    2507             : !> \param LDOS ...
    2508             : !> \param auxbas_pw_pool ...
    2509             : !> \param qs_env ...
    2510             : ! **************************************************************************************************
    2511           4 :    SUBROUTINE create_real_space_grids(E_gap_rspace, E_VBM_rspace, E_CBM_rspace, rho_g_dummy, LDOS, auxbas_pw_pool, qs_env)
    2512             :       TYPE(pw_r3d_rs_type)                               :: E_gap_rspace, E_VBM_rspace, E_CBM_rspace
    2513             :       TYPE(pw_c1d_gs_type)                               :: rho_g_dummy
    2514             :       TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:)    :: LDOS
    2515             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    2516             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2517             : 
    2518             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'create_real_space_grids'
    2519             : 
    2520             :       INTEGER                                            :: handle, i_E, n_E
    2521             :       TYPE(mp2_type), POINTER                            :: mp2_env
    2522             :       TYPE(pw_env_type), POINTER                         :: pw_env
    2523             : 
    2524           4 :       CALL timeset(routineN, handle)
    2525             : 
    2526           4 :       CALL get_qs_env(qs_env=qs_env, mp2_env=mp2_env, pw_env=pw_env)
    2527             : 
    2528           4 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
    2529             : 
    2530           4 :       CALL auxbas_pw_pool%create_pw(E_gap_rspace)
    2531           4 :       CALL auxbas_pw_pool%create_pw(E_VBM_rspace)
    2532           4 :       CALL auxbas_pw_pool%create_pw(E_CBM_rspace)
    2533           4 :       CALL auxbas_pw_pool%create_pw(rho_g_dummy)
    2534             : 
    2535             :       n_E = INT(mp2_env%ri_g0w0%energy_window_print_loc_bandgap/ &
    2536           4 :                 mp2_env%ri_g0w0%energy_spacing_print_loc_bandgap)
    2537             : 
    2538          28 :       ALLOCATE (LDOS(n_E))
    2539             : 
    2540          20 :       DO i_E = 1, n_E
    2541          20 :          CALL auxbas_pw_pool%create_pw(LDOS(i_E))
    2542             :       END DO
    2543             : 
    2544           4 :       CALL timestop(handle)
    2545             : 
    2546           4 :    END SUBROUTINE create_real_space_grids
    2547             : 
    2548             : ! **************************************************************************************************
    2549             : !> \brief ...
    2550             : !> \param delta_corr ...
    2551             : !> \param qs_env ...
    2552             : !> \param para_env ...
    2553             : !> \param para_env_RPA ...
    2554             : !> \param kp_grid ...
    2555             : !> \param homo ...
    2556             : !> \param nmo ...
    2557             : !> \param gw_corr_lev_occ ...
    2558             : !> \param gw_corr_lev_virt ...
    2559             : !> \param omega ...
    2560             : !> \param fm_mo_coeff ...
    2561             : !> \param Eigenval ...
    2562             : !> \param matrix_berry_re_mo_mo ...
    2563             : !> \param matrix_berry_im_mo_mo ...
    2564             : !> \param first_cycle_periodic_correction ...
    2565             : !> \param kpoints ...
    2566             : !> \param do_mo_coeff_Gamma_only ...
    2567             : !> \param num_kp_grids ...
    2568             : !> \param eps_kpoint ...
    2569             : !> \param do_extra_kpoints ...
    2570             : !> \param do_aux_bas ...
    2571             : !> \param frac_aux_mos ...
    2572             : ! **************************************************************************************************
    2573         260 :    SUBROUTINE calc_periodic_correction(delta_corr, qs_env, para_env, para_env_RPA, kp_grid, homo, nmo, &
    2574         260 :                                        gw_corr_lev_occ, gw_corr_lev_virt, omega, fm_mo_coeff, Eigenval, &
    2575             :                                        matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
    2576             :                                        first_cycle_periodic_correction, kpoints, do_mo_coeff_Gamma_only, &
    2577             :                                        num_kp_grids, eps_kpoint, do_extra_kpoints, do_aux_bas, frac_aux_mos)
    2578             : 
    2579             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
    2580             :          INTENT(INOUT)                                   :: delta_corr
    2581             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2582             :       TYPE(mp_para_env_type), POINTER                    :: para_env, para_env_RPA
    2583             :       INTEGER, DIMENSION(:), POINTER                     :: kp_grid
    2584             :       INTEGER, INTENT(IN)                                :: homo, nmo, gw_corr_lev_occ, &
    2585             :                                                             gw_corr_lev_virt
    2586             :       REAL(KIND=dp), INTENT(IN)                          :: omega
    2587             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mo_coeff
    2588             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: Eigenval
    2589             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_berry_re_mo_mo, &
    2590             :                                                             matrix_berry_im_mo_mo
    2591             :       LOGICAL, INTENT(INOUT) :: first_cycle_periodic_correction
    2592             :       TYPE(kpoint_type), POINTER                         :: kpoints
    2593             :       LOGICAL, INTENT(IN)                                :: do_mo_coeff_Gamma_only
    2594             :       INTEGER, INTENT(IN)                                :: num_kp_grids
    2595             :       REAL(KIND=dp), INTENT(IN)                          :: eps_kpoint
    2596             :       LOGICAL, INTENT(IN)                                :: do_extra_kpoints, do_aux_bas
    2597             :       REAL(KIND=dp), INTENT(IN)                          :: frac_aux_mos
    2598             : 
    2599             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'calc_periodic_correction'
    2600             : 
    2601             :       INTEGER                                            :: handle
    2602         260 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: eps_head, eps_inv_head
    2603             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: h_inv
    2604             : 
    2605         260 :       CALL timeset(routineN, handle)
    2606             : 
    2607         260 :       IF (first_cycle_periodic_correction) THEN
    2608             : 
    2609             :          CALL get_kpoints(qs_env, kpoints, kp_grid, num_kp_grids, para_env, h_inv, nmo, do_mo_coeff_Gamma_only, &
    2610           6 :                           do_extra_kpoints)
    2611             : 
    2612             :          CALL get_berry_phase(qs_env, kpoints, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, fm_mo_coeff, &
    2613             :                               para_env, do_mo_coeff_Gamma_only, homo, nmo, gw_corr_lev_virt, eps_kpoint, do_aux_bas, &
    2614           6 :                               frac_aux_mos)
    2615             : 
    2616             :       END IF
    2617             : 
    2618             :       CALL compute_eps_head_Berry(eps_head, kpoints, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, para_env_RPA, &
    2619         260 :                                   qs_env, homo, Eigenval, omega)
    2620             : 
    2621             :       CALL compute_eps_inv_head(eps_inv_head, eps_head, kpoints)
    2622             : 
    2623             :       CALL kpoint_sum_for_eps_inv_head_Berry(delta_corr, eps_inv_head, kpoints, qs_env, &
    2624             :                                              matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
    2625             :                                              homo, gw_corr_lev_occ, gw_corr_lev_virt, para_env_RPA, &
    2626         260 :                                              do_extra_kpoints)
    2627             : 
    2628         260 :       DEALLOCATE (eps_head, eps_inv_head)
    2629             : 
    2630         260 :       first_cycle_periodic_correction = .FALSE.
    2631             : 
    2632         260 :       CALL timestop(handle)
    2633             : 
    2634         260 :    END SUBROUTINE calc_periodic_correction
    2635             : 
    2636             : ! **************************************************************************************************
    2637             : !> \brief ...
    2638             : !> \param eps_head ...
    2639             : !> \param kpoints ...
    2640             : !> \param matrix_berry_re_mo_mo ...
    2641             : !> \param matrix_berry_im_mo_mo ...
    2642             : !> \param para_env_RPA ...
    2643             : !> \param qs_env ...
    2644             : !> \param homo ...
    2645             : !> \param Eigenval ...
    2646             : !> \param omega ...
    2647             : ! **************************************************************************************************
    2648         260 :    SUBROUTINE compute_eps_head_Berry(eps_head, kpoints, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, para_env_RPA, &
    2649         260 :                                      qs_env, homo, Eigenval, omega)
    2650             : 
    2651             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
    2652             :          INTENT(OUT)                                     :: eps_head
    2653             :       TYPE(kpoint_type), POINTER                         :: kpoints
    2654             :       TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN)       :: matrix_berry_re_mo_mo, &
    2655             :                                                             matrix_berry_im_mo_mo
    2656             :       TYPE(mp_para_env_type), INTENT(IN)                 :: para_env_RPA
    2657             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2658             :       INTEGER, INTENT(IN)                                :: homo
    2659             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: Eigenval
    2660             :       REAL(KIND=dp), INTENT(IN)                          :: omega
    2661             : 
    2662             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_eps_head_Berry'
    2663             : 
    2664             :       INTEGER :: col, col_end_in_block, col_offset, col_size, handle, i_col, i_row, ikp, nkp, nmo, &
    2665             :          row, row_offset, row_size, row_start_in_block
    2666             :       REAL(KIND=dp)                                      :: abs_k_square, cell_volume, &
    2667             :                                                             correct_kpoint(3), cos_square, &
    2668             :                                                             eigen_diff, relative_kpoint(3), &
    2669             :                                                             sin_square
    2670             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: P_head
    2671         260 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: data_block
    2672             :       TYPE(cell_type), POINTER                           :: cell
    2673             :       TYPE(dbcsr_iterator_type)                          :: iter
    2674             : 
    2675         260 :       CALL timeset(routineN, handle)
    2676             : 
    2677         260 :       CALL get_qs_env(qs_env=qs_env, cell=cell)
    2678         260 :       CALL get_cell(cell=cell, deth=cell_volume)
    2679             : 
    2680         260 :       NULLIFY (data_block)
    2681             : 
    2682         260 :       nkp = kpoints%nkp
    2683             : 
    2684         260 :       nmo = SIZE(Eigenval)
    2685             : 
    2686         780 :       ALLOCATE (P_head(nkp))
    2687      279620 :       P_head(:) = 0.0_dp
    2688             : 
    2689         520 :       ALLOCATE (eps_head(nkp))
    2690      279620 :       eps_head(:) = 0.0_dp
    2691             : 
    2692      279620 :       DO ikp = 1, nkp
    2693             : 
    2694     3631680 :          relative_kpoint(1:3) = MATMUL(cell%hmat, kpoints%xkp(1:3, ikp))
    2695             : 
    2696     1117440 :          correct_kpoint(1:3) = twopi*kpoints%xkp(1:3, ikp)
    2697             : 
    2698      279360 :          abs_k_square = (correct_kpoint(1))**2 + (correct_kpoint(2))**2 + (correct_kpoint(3))**2
    2699             : 
    2700             :          ! real part of the Berry phase
    2701      279360 :          CALL dbcsr_iterator_start(iter, matrix_berry_re_mo_mo(ikp)%matrix)
    2702      465120 :          DO WHILE (dbcsr_iterator_blocks_left(iter))
    2703             : 
    2704             :             CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
    2705             :                                            row_size=row_size, col_size=col_size, &
    2706      185760 :                                            row_offset=row_offset, col_offset=col_offset)
    2707             : 
    2708      185760 :             IF (row_offset + row_size <= homo .OR. col_offset > homo) CYCLE
    2709             : 
    2710      185760 :             IF (row_offset <= homo) THEN
    2711      139680 :                row_start_in_block = homo - row_offset + 2
    2712             :             ELSE
    2713             :                row_start_in_block = 1
    2714             :             END IF
    2715             : 
    2716      185760 :             IF (col_offset + col_size - 1 > homo) THEN
    2717      185760 :                col_end_in_block = homo - col_offset + 1
    2718             :             ELSE
    2719             :                col_end_in_block = col_size
    2720             :             END IF
    2721             : 
    2722     1929600 :             DO i_row = row_start_in_block, MIN(row_size, nmo - row_offset + 1)
    2723             : 
    2724     7508160 :                DO i_col = 1, MIN(col_end_in_block, nmo - col_offset + 1)
    2725             : 
    2726     5857920 :                   eigen_diff = Eigenval(i_col + col_offset - 1) - Eigenval(i_row + row_offset - 1)
    2727             : 
    2728     5857920 :                   cos_square = (data_block(i_row, i_col))**2
    2729             : 
    2730     7322400 :                   P_head(ikp) = P_head(ikp) + 2.0_dp*eigen_diff/(omega**2 + eigen_diff**2)*cos_square/abs_k_square
    2731             : 
    2732             :                END DO
    2733             : 
    2734             :             END DO
    2735             : 
    2736             :          END DO
    2737             : 
    2738      279360 :          CALL dbcsr_iterator_stop(iter)
    2739             : 
    2740             :          ! imaginary part of the Berry phase
    2741      279360 :          CALL dbcsr_iterator_start(iter, matrix_berry_im_mo_mo(ikp)%matrix)
    2742      465120 :          DO WHILE (dbcsr_iterator_blocks_left(iter))
    2743             : 
    2744             :             CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
    2745             :                                            row_size=row_size, col_size=col_size, &
    2746      185760 :                                            row_offset=row_offset, col_offset=col_offset)
    2747             : 
    2748      185760 :             IF (row_offset + row_size <= homo .OR. col_offset > homo) CYCLE
    2749             : 
    2750      185760 :             IF (row_offset <= homo) THEN
    2751      139680 :                row_start_in_block = homo - row_offset + 2
    2752             :             ELSE
    2753             :                row_start_in_block = 1
    2754             :             END IF
    2755             : 
    2756      185760 :             IF (col_offset + col_size - 1 > homo) THEN
    2757      185760 :                col_end_in_block = homo - col_offset + 1
    2758             :             ELSE
    2759             :                col_end_in_block = col_size
    2760             :             END IF
    2761             : 
    2762     1929600 :             DO i_row = row_start_in_block, MIN(row_size, nmo - row_offset + 1)
    2763             : 
    2764     7508160 :                DO i_col = 1, MIN(col_end_in_block, nmo - col_offset + 1)
    2765             : 
    2766     5857920 :                   eigen_diff = Eigenval(i_col + col_offset - 1) - Eigenval(i_row + row_offset - 1)
    2767             : 
    2768     5857920 :                   sin_square = (data_block(i_row, i_col))**2
    2769             : 
    2770     7322400 :                   P_head(ikp) = P_head(ikp) + 2.0_dp*eigen_diff/(omega**2 + eigen_diff**2)*sin_square/abs_k_square
    2771             : 
    2772             :                END DO
    2773             : 
    2774             :             END DO
    2775             : 
    2776             :          END DO
    2777             : 
    2778      838340 :          CALL dbcsr_iterator_stop(iter)
    2779             : 
    2780             :       END DO
    2781             : 
    2782         260 :       CALL para_env_RPA%sum(P_head)
    2783             : 
    2784             :       ! normalize eps_head
    2785             :       ! 2.0_dp due to closed shell
    2786      279620 :       eps_head(:) = 1.0_dp - 2.0_dp*P_head(:)/cell_volume*fourpi
    2787             : 
    2788         260 :       DEALLOCATE (P_head)
    2789             : 
    2790         260 :       CALL timestop(handle)
    2791             : 
    2792         520 :    END SUBROUTINE compute_eps_head_Berry
    2793             : 
    2794             : ! **************************************************************************************************
    2795             : !> \brief ...
    2796             : !> \param qs_env ...
    2797             : !> \param kpoints ...
    2798             : !> \param matrix_berry_re_mo_mo ...
    2799             : !> \param matrix_berry_im_mo_mo ...
    2800             : !> \param fm_mo_coeff ...
    2801             : !> \param para_env ...
    2802             : !> \param do_mo_coeff_Gamma_only ...
    2803             : !> \param homo ...
    2804             : !> \param nmo ...
    2805             : !> \param gw_corr_lev_virt ...
    2806             : !> \param eps_kpoint ...
    2807             : !> \param do_aux_bas ...
    2808             : !> \param frac_aux_mos ...
    2809             : ! **************************************************************************************************
    2810           6 :    SUBROUTINE get_berry_phase(qs_env, kpoints, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, fm_mo_coeff, para_env, &
    2811             :                               do_mo_coeff_Gamma_only, homo, nmo, gw_corr_lev_virt, eps_kpoint, do_aux_bas, &
    2812             :                               frac_aux_mos)
    2813             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2814             :       TYPE(kpoint_type), POINTER                         :: kpoints
    2815             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_berry_re_mo_mo, &
    2816             :                                                             matrix_berry_im_mo_mo
    2817             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mo_coeff
    2818             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2819             :       LOGICAL, INTENT(IN)                                :: do_mo_coeff_Gamma_only
    2820             :       INTEGER, INTENT(IN)                                :: homo, nmo, gw_corr_lev_virt
    2821             :       REAL(KIND=dp), INTENT(IN)                          :: eps_kpoint
    2822             :       LOGICAL, INTENT(IN)                                :: do_aux_bas
    2823             :       REAL(KIND=dp), INTENT(IN)                          :: frac_aux_mos
    2824             : 
    2825             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'get_berry_phase'
    2826             : 
    2827             :       INTEGER                                            :: col_index, handle, i_col_local, ikind, &
    2828             :                                                             ikp, nao_aux, ncol_local, nkind, nkp, &
    2829             :                                                             nmo_for_aux_bas
    2830           6 :       INTEGER, DIMENSION(:), POINTER                     :: col_indices
    2831             :       REAL(dp)                                           :: abs_kpoint, correct_kpoint(3), &
    2832             :                                                             scale_kpoint
    2833           6 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: evals_P, evals_P_sqrt_inv
    2834             :       TYPE(cell_type), POINTER                           :: cell
    2835             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct_aux_aux
    2836             :       TYPE(cp_fm_type) :: fm_mat_eigv_P, fm_mat_P, fm_mat_P_sqrt_inv, fm_mat_s_aux_aux_inv, &
    2837             :          fm_mat_scaled_eigv_P, fm_mat_work_aux_aux
    2838           6 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s, matrix_s_aux_aux, &
    2839           6 :                                                             matrix_s_aux_orb
    2840             :       TYPE(dbcsr_type), POINTER :: cosmat, cosmat_desymm, mat_mo_coeff_aux, mat_mo_coeff_aux_2, &
    2841             :          mat_mo_coeff_Gamma_all, mat_mo_coeff_Gamma_occ_and_GW, mat_mo_coeff_im, mat_mo_coeff_re, &
    2842             :          mat_work_aux_orb, mat_work_aux_orb_2, matrix_P, matrix_P_sqrt, matrix_P_sqrt_inv, &
    2843             :          matrix_s_inv_aux_aux, sinmat, sinmat_desymm, tmp
    2844           6 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: gw_aux_basis_set_list, orb_basis_set_list
    2845             :       TYPE(gto_basis_set_type), POINTER                  :: basis_set_gw_aux
    2846             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    2847           6 :          POINTER                                         :: sab_orb, sab_orb_mic, sgwgw_list, &
    2848           6 :                                                             sgworb_list
    2849           6 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    2850             :       TYPE(qs_kind_type), POINTER                        :: qs_kind
    2851             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    2852             : 
    2853           6 :       CALL timeset(routineN, handle)
    2854             : 
    2855           6 :       nkp = kpoints%nkp
    2856             : 
    2857           6 :       NULLIFY (matrix_berry_re_mo_mo, matrix_s, cell, matrix_berry_im_mo_mo, sinmat, cosmat, tmp, &
    2858           6 :                cosmat_desymm, sinmat_desymm, qs_kind_set, orb_basis_set_list, sab_orb_mic)
    2859             : 
    2860             :       CALL get_qs_env(qs_env=qs_env, &
    2861             :                       cell=cell, &
    2862             :                       matrix_s=matrix_s, &
    2863             :                       qs_kind_set=qs_kind_set, &
    2864             :                       nkind=nkind, &
    2865             :                       ks_env=ks_env, &
    2866           6 :                       sab_orb=sab_orb)
    2867             : 
    2868          30 :       ALLOCATE (orb_basis_set_list(nkind))
    2869           6 :       CALL basis_set_list_setup(orb_basis_set_list, "ORB", qs_kind_set)
    2870             : 
    2871           6 :       CALL setup_neighbor_list(sab_orb_mic, orb_basis_set_list, qs_env=qs_env, mic=.FALSE.)
    2872             : 
    2873             :       ! create dbcsr matrix of mo_coeff for multiplcation
    2874           6 :       NULLIFY (mat_mo_coeff_re)
    2875           6 :       CALL dbcsr_init_p(mat_mo_coeff_re)
    2876             :       CALL dbcsr_create(matrix=mat_mo_coeff_re, &
    2877             :                         template=matrix_s(1)%matrix, &
    2878           6 :                         matrix_type=dbcsr_type_no_symmetry)
    2879             : 
    2880           6 :       NULLIFY (mat_mo_coeff_im)
    2881           6 :       CALL dbcsr_init_p(mat_mo_coeff_im)
    2882             :       CALL dbcsr_create(matrix=mat_mo_coeff_im, &
    2883             :                         template=matrix_s(1)%matrix, &
    2884           6 :                         matrix_type=dbcsr_type_no_symmetry)
    2885             : 
    2886           6 :       NULLIFY (mat_mo_coeff_Gamma_all)
    2887           6 :       CALL dbcsr_init_p(mat_mo_coeff_Gamma_all)
    2888             :       CALL dbcsr_create(matrix=mat_mo_coeff_Gamma_all, &
    2889             :                         template=matrix_s(1)%matrix, &
    2890           6 :                         matrix_type=dbcsr_type_no_symmetry)
    2891             : 
    2892           6 :       CALL copy_fm_to_dbcsr(fm_mo_coeff, mat_mo_coeff_Gamma_all, keep_sparsity=.FALSE.)
    2893             : 
    2894           6 :       NULLIFY (mat_mo_coeff_Gamma_occ_and_GW)
    2895           6 :       CALL dbcsr_init_p(mat_mo_coeff_Gamma_occ_and_GW)
    2896             :       CALL dbcsr_create(matrix=mat_mo_coeff_Gamma_occ_and_GW, &
    2897             :                         template=matrix_s(1)%matrix, &
    2898           6 :                         matrix_type=dbcsr_type_no_symmetry)
    2899             : 
    2900           6 :       CALL copy_fm_to_dbcsr(fm_mo_coeff, mat_mo_coeff_Gamma_occ_and_GW, keep_sparsity=.FALSE.)
    2901             : 
    2902           6 :       IF (.NOT. do_aux_bas) THEN
    2903             : 
    2904             :          ! allocate intermediate matrices
    2905           4 :          CALL dbcsr_init_p(cosmat)
    2906           4 :          CALL dbcsr_init_p(sinmat)
    2907           4 :          CALL dbcsr_init_p(tmp)
    2908           4 :          CALL dbcsr_init_p(cosmat_desymm)
    2909           4 :          CALL dbcsr_init_p(sinmat_desymm)
    2910           4 :          CALL dbcsr_create(matrix=cosmat, template=matrix_s(1)%matrix)
    2911           4 :          CALL dbcsr_create(matrix=sinmat, template=matrix_s(1)%matrix)
    2912             :          CALL dbcsr_create(matrix=tmp, &
    2913             :                            template=matrix_s(1)%matrix, &
    2914           4 :                            matrix_type=dbcsr_type_no_symmetry)
    2915             :          CALL dbcsr_create(matrix=cosmat_desymm, &
    2916             :                            template=matrix_s(1)%matrix, &
    2917           4 :                            matrix_type=dbcsr_type_no_symmetry)
    2918             :          CALL dbcsr_create(matrix=sinmat_desymm, &
    2919             :                            template=matrix_s(1)%matrix, &
    2920           4 :                            matrix_type=dbcsr_type_no_symmetry)
    2921           4 :          CALL dbcsr_copy(cosmat, matrix_s(1)%matrix)
    2922           4 :          CALL dbcsr_copy(sinmat, matrix_s(1)%matrix)
    2923           4 :          CALL dbcsr_set(cosmat, 0.0_dp)
    2924           4 :          CALL dbcsr_set(sinmat, 0.0_dp)
    2925             : 
    2926           4 :          CALL dbcsr_allocate_matrix_set(matrix_berry_re_mo_mo, nkp)
    2927           4 :          CALL dbcsr_allocate_matrix_set(matrix_berry_im_mo_mo, nkp)
    2928             : 
    2929             :       ELSE
    2930             : 
    2931           2 :          NULLIFY (gw_aux_basis_set_list)
    2932          10 :          ALLOCATE (gw_aux_basis_set_list(nkind))
    2933             : 
    2934           6 :          DO ikind = 1, nkind
    2935             : 
    2936           4 :             NULLIFY (gw_aux_basis_set_list(ikind)%gto_basis_set)
    2937             : 
    2938           4 :             NULLIFY (basis_set_gw_aux)
    2939             : 
    2940           4 :             qs_kind => qs_kind_set(ikind)
    2941           4 :             CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_gw_aux, basis_type="AUX_GW")
    2942           4 :             CPASSERT(ASSOCIATED(basis_set_gw_aux))
    2943             : 
    2944           4 :             basis_set_gw_aux%kind_radius = orb_basis_set_list(ikind)%gto_basis_set%kind_radius
    2945             : 
    2946           6 :             gw_aux_basis_set_list(ikind)%gto_basis_set => basis_set_gw_aux
    2947             : 
    2948             :          END DO
    2949             : 
    2950             :          ! neighbor lists
    2951           2 :          NULLIFY (sgwgw_list, sgworb_list)
    2952           2 :          CALL setup_neighbor_list(sgwgw_list, gw_aux_basis_set_list, qs_env=qs_env)
    2953           2 :          CALL setup_neighbor_list(sgworb_list, gw_aux_basis_set_list, orb_basis_set_list, qs_env=qs_env)
    2954             : 
    2955           2 :          NULLIFY (matrix_s_aux_aux, matrix_s_aux_orb)
    2956             : 
    2957             :          ! build overlap matrix in gw aux basis and the mixed gw aux basis-orb basis
    2958             :          CALL build_overlap_matrix_simple(ks_env, matrix_s_aux_aux, &
    2959           2 :                                           gw_aux_basis_set_list, gw_aux_basis_set_list, sgwgw_list)
    2960             : 
    2961             :          CALL build_overlap_matrix_simple(ks_env, matrix_s_aux_orb, &
    2962           2 :                                           gw_aux_basis_set_list, orb_basis_set_list, sgworb_list)
    2963             : 
    2964           2 :          CALL dbcsr_get_info(matrix_s_aux_aux(1)%matrix, nfullrows_total=nao_aux)
    2965             : 
    2966           2 :          nmo_for_aux_bas = FLOOR(frac_aux_mos*REAL(nao_aux, KIND=dp))
    2967             : 
    2968             :          CALL cp_fm_struct_create(fm_struct_aux_aux, &
    2969             :                                   context=fm_mo_coeff%matrix_struct%context, &
    2970             :                                   nrow_global=nao_aux, &
    2971             :                                   ncol_global=nao_aux, &
    2972           2 :                                   para_env=para_env)
    2973             : 
    2974           2 :          NULLIFY (mat_work_aux_orb)
    2975           2 :          CALL dbcsr_init_p(mat_work_aux_orb)
    2976             :          CALL dbcsr_create(matrix=mat_work_aux_orb, &
    2977             :                            template=matrix_s_aux_orb(1)%matrix, &
    2978           2 :                            matrix_type=dbcsr_type_no_symmetry)
    2979             : 
    2980           2 :          NULLIFY (mat_work_aux_orb_2)
    2981           2 :          CALL dbcsr_init_p(mat_work_aux_orb_2)
    2982             :          CALL dbcsr_create(matrix=mat_work_aux_orb_2, &
    2983             :                            template=matrix_s_aux_orb(1)%matrix, &
    2984           2 :                            matrix_type=dbcsr_type_no_symmetry)
    2985             : 
    2986           2 :          NULLIFY (mat_mo_coeff_aux)
    2987           2 :          CALL dbcsr_init_p(mat_mo_coeff_aux)
    2988             :          CALL dbcsr_create(matrix=mat_mo_coeff_aux, &
    2989             :                            template=matrix_s_aux_orb(1)%matrix, &
    2990           2 :                            matrix_type=dbcsr_type_no_symmetry)
    2991             : 
    2992           2 :          NULLIFY (mat_mo_coeff_aux_2)
    2993           2 :          CALL dbcsr_init_p(mat_mo_coeff_aux_2)
    2994             :          CALL dbcsr_create(matrix=mat_mo_coeff_aux_2, &
    2995             :                            template=matrix_s_aux_orb(1)%matrix, &
    2996           2 :                            matrix_type=dbcsr_type_no_symmetry)
    2997             : 
    2998           2 :          NULLIFY (matrix_s_inv_aux_aux)
    2999           2 :          CALL dbcsr_init_p(matrix_s_inv_aux_aux)
    3000             :          CALL dbcsr_create(matrix=matrix_s_inv_aux_aux, &
    3001             :                            template=matrix_s_aux_aux(1)%matrix, &
    3002           2 :                            matrix_type=dbcsr_type_no_symmetry)
    3003             : 
    3004           2 :          NULLIFY (matrix_P)
    3005           2 :          CALL dbcsr_init_p(matrix_P)
    3006             :          CALL dbcsr_create(matrix=matrix_P, &
    3007             :                            template=matrix_s(1)%matrix, &
    3008           2 :                            matrix_type=dbcsr_type_no_symmetry)
    3009             : 
    3010           2 :          NULLIFY (matrix_P_sqrt)
    3011           2 :          CALL dbcsr_init_p(matrix_P_sqrt)
    3012             :          CALL dbcsr_create(matrix=matrix_P_sqrt, &
    3013             :                            template=matrix_s(1)%matrix, &
    3014           2 :                            matrix_type=dbcsr_type_no_symmetry)
    3015             : 
    3016           2 :          NULLIFY (matrix_P_sqrt_inv)
    3017           2 :          CALL dbcsr_init_p(matrix_P_sqrt_inv)
    3018             :          CALL dbcsr_create(matrix=matrix_P_sqrt_inv, &
    3019             :                            template=matrix_s(1)%matrix, &
    3020           2 :                            matrix_type=dbcsr_type_no_symmetry)
    3021             : 
    3022           2 :          CALL cp_fm_create(fm_mat_s_aux_aux_inv, fm_struct_aux_aux, name="inverse overlap mat")
    3023           2 :          CALL cp_fm_create(fm_mat_work_aux_aux, fm_struct_aux_aux, name="work mat")
    3024           2 :          CALL cp_fm_create(fm_mat_P, fm_mo_coeff%matrix_struct)
    3025           2 :          CALL cp_fm_create(fm_mat_eigv_P, fm_mo_coeff%matrix_struct)
    3026           2 :          CALL cp_fm_create(fm_mat_scaled_eigv_P, fm_mo_coeff%matrix_struct)
    3027           2 :          CALL cp_fm_create(fm_mat_P_sqrt_inv, fm_mo_coeff%matrix_struct)
    3028             : 
    3029             :          NULLIFY (evals_P)
    3030           6 :          ALLOCATE (evals_P(nmo))
    3031             : 
    3032           2 :          NULLIFY (evals_P_sqrt_inv)
    3033           4 :          ALLOCATE (evals_P_sqrt_inv(nmo))
    3034             : 
    3035           2 :          CALL copy_dbcsr_to_fm(matrix_s_aux_aux(1)%matrix, fm_mat_s_aux_aux_inv)
    3036             :          ! Calculate S_inverse
    3037           2 :          CALL cp_fm_cholesky_decompose(fm_mat_s_aux_aux_inv)
    3038           2 :          CALL cp_fm_cholesky_invert(fm_mat_s_aux_aux_inv)
    3039             :          ! Symmetrize the guy
    3040           2 :          CALL cp_fm_uplo_to_full(fm_mat_s_aux_aux_inv, fm_mat_work_aux_aux)
    3041             : 
    3042           2 :          CALL copy_fm_to_dbcsr(fm_mat_s_aux_aux_inv, matrix_s_inv_aux_aux, keep_sparsity=.FALSE.)
    3043             : 
    3044             :          CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s_inv_aux_aux, matrix_s_aux_orb(1)%matrix, 0.0_dp, mat_work_aux_orb, &
    3045           2 :                              filter_eps=1.0E-15_dp)
    3046             : 
    3047             :          CALL dbcsr_multiply('N', 'N', 1.0_dp, mat_work_aux_orb, mat_mo_coeff_Gamma_all, 0.0_dp, mat_mo_coeff_aux_2, &
    3048           2 :                              last_column=nmo_for_aux_bas, filter_eps=1.0E-15_dp)
    3049             : 
    3050             :          CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s_aux_aux(1)%matrix, mat_mo_coeff_aux_2, 0.0_dp, mat_work_aux_orb, &
    3051           2 :                              filter_eps=1.0E-15_dp)
    3052             : 
    3053             :          CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_aux_2, mat_work_aux_orb, 0.0_dp, matrix_P, &
    3054           2 :                              filter_eps=1.0E-15_dp)
    3055             : 
    3056           2 :          CALL copy_dbcsr_to_fm(matrix_P, fm_mat_P)
    3057             : 
    3058           2 :          CALL cp_fm_syevd(fm_mat_P, fm_mat_eigv_P, evals_P)
    3059             : 
    3060             :          ! only invert the eigenvalues which correspond to the MOs used in the aux. basis
    3061          62 :          evals_P_sqrt_inv(1:nmo - nmo_for_aux_bas) = 0.0_dp
    3062          46 :          evals_P_sqrt_inv(nmo - nmo_for_aux_bas + 1:nmo) = 1.0_dp/SQRT(evals_P(nmo - nmo_for_aux_bas + 1:nmo))
    3063             : 
    3064           2 :          CALL cp_fm_to_fm(fm_mat_eigv_P, fm_mat_scaled_eigv_P)
    3065             : 
    3066             :          CALL cp_fm_get_info(matrix=fm_mat_scaled_eigv_P, &
    3067             :                              ncol_local=ncol_local, &
    3068           2 :                              col_indices=col_indices)
    3069             : 
    3070           2 :          CALL para_env%sync()
    3071             : 
    3072             :          ! multiply eigenvectors with inverse sqrt of eigenvalues
    3073          84 :          DO i_col_local = 1, ncol_local
    3074             : 
    3075          82 :             col_index = col_indices(i_col_local)
    3076             : 
    3077             :             fm_mat_scaled_eigv_P%local_data(:, i_col_local) = &
    3078        1765 :                fm_mat_scaled_eigv_P%local_data(:, i_col_local)*evals_P_sqrt_inv(col_index)
    3079             : 
    3080             :          END DO
    3081             : 
    3082           2 :          CALL para_env%sync()
    3083             : 
    3084             :          CALL parallel_gemm(transa="N", transb="T", m=nmo, n=nmo, k=nmo, alpha=1.0_dp, &
    3085             :                             matrix_a=fm_mat_eigv_P, matrix_b=fm_mat_scaled_eigv_P, beta=0.0_dp, &
    3086           2 :                             matrix_c=fm_mat_P_sqrt_inv)
    3087             : 
    3088           2 :          CALL copy_fm_to_dbcsr(fm_mat_P_sqrt_inv, matrix_P_sqrt_inv, keep_sparsity=.FALSE.)
    3089             : 
    3090             :          CALL dbcsr_multiply('N', 'N', 1.0_dp, mat_mo_coeff_aux_2, matrix_P_sqrt_inv, 0.0_dp, mat_mo_coeff_aux, &
    3091           2 :                              filter_eps=1.0E-15_dp)
    3092             : 
    3093             :          ! allocate intermediate matrices
    3094           2 :          CALL dbcsr_init_p(cosmat)
    3095           2 :          CALL dbcsr_init_p(sinmat)
    3096           2 :          CALL dbcsr_init_p(tmp)
    3097           2 :          CALL dbcsr_init_p(cosmat_desymm)
    3098           2 :          CALL dbcsr_init_p(sinmat_desymm)
    3099           2 :          CALL dbcsr_create(matrix=cosmat, template=matrix_s_aux_aux(1)%matrix)
    3100           2 :          CALL dbcsr_create(matrix=sinmat, template=matrix_s_aux_aux(1)%matrix)
    3101             :          CALL dbcsr_create(matrix=tmp, &
    3102             :                            template=matrix_s_aux_orb(1)%matrix, &
    3103           2 :                            matrix_type=dbcsr_type_no_symmetry)
    3104             :          CALL dbcsr_create(matrix=cosmat_desymm, &
    3105             :                            template=matrix_s_aux_aux(1)%matrix, &
    3106           2 :                            matrix_type=dbcsr_type_no_symmetry)
    3107             :          CALL dbcsr_create(matrix=sinmat_desymm, &
    3108             :                            template=matrix_s_aux_aux(1)%matrix, &
    3109           2 :                            matrix_type=dbcsr_type_no_symmetry)
    3110           2 :          CALL dbcsr_copy(cosmat, matrix_s_aux_aux(1)%matrix)
    3111           2 :          CALL dbcsr_copy(sinmat, matrix_s_aux_aux(1)%matrix)
    3112           2 :          CALL dbcsr_set(cosmat, 0.0_dp)
    3113           2 :          CALL dbcsr_set(sinmat, 0.0_dp)
    3114             : 
    3115           2 :          CALL dbcsr_allocate_matrix_set(matrix_berry_re_mo_mo, nkp)
    3116           2 :          CALL dbcsr_allocate_matrix_set(matrix_berry_im_mo_mo, nkp)
    3117             : 
    3118             :          ! allocate the new MO coefficients in the aux basis
    3119           2 :          CALL dbcsr_release_p(mat_mo_coeff_Gamma_all)
    3120           2 :          CALL dbcsr_release_p(mat_mo_coeff_Gamma_occ_and_GW)
    3121             : 
    3122           2 :          NULLIFY (mat_mo_coeff_Gamma_all)
    3123           2 :          CALL dbcsr_init_p(mat_mo_coeff_Gamma_all)
    3124             :          CALL dbcsr_create(matrix=mat_mo_coeff_Gamma_all, &
    3125             :                            template=matrix_s_aux_orb(1)%matrix, &
    3126           2 :                            matrix_type=dbcsr_type_no_symmetry)
    3127             : 
    3128           2 :          CALL dbcsr_copy(mat_mo_coeff_Gamma_all, mat_mo_coeff_aux)
    3129             : 
    3130           2 :          NULLIFY (mat_mo_coeff_Gamma_occ_and_GW)
    3131           2 :          CALL dbcsr_init_p(mat_mo_coeff_Gamma_occ_and_GW)
    3132             :          CALL dbcsr_create(matrix=mat_mo_coeff_Gamma_occ_and_GW, &
    3133             :                            template=matrix_s_aux_orb(1)%matrix, &
    3134           2 :                            matrix_type=dbcsr_type_no_symmetry)
    3135             : 
    3136           2 :          CALL dbcsr_copy(mat_mo_coeff_Gamma_occ_and_GW, mat_mo_coeff_aux)
    3137             : 
    3138           8 :          DEALLOCATE (evals_P, evals_P_sqrt_inv)
    3139             : 
    3140             :       END IF
    3141             : 
    3142           6 :       CALL remove_unnecessary_blocks(mat_mo_coeff_Gamma_occ_and_GW, homo, gw_corr_lev_virt)
    3143             : 
    3144       11166 :       DO ikp = 1, nkp
    3145             : 
    3146       11160 :          ALLOCATE (matrix_berry_re_mo_mo(ikp)%matrix)
    3147       11160 :          CALL dbcsr_init_p(matrix_berry_re_mo_mo(ikp)%matrix)
    3148             :          CALL dbcsr_create(matrix_berry_re_mo_mo(ikp)%matrix, &
    3149             :                            template=matrix_s(1)%matrix, &
    3150       11160 :                            matrix_type=dbcsr_type_no_symmetry)
    3151       11160 :          CALL dbcsr_desymmetrize(matrix_s(1)%matrix, matrix_berry_re_mo_mo(ikp)%matrix)
    3152       11160 :          CALL dbcsr_set(matrix_berry_re_mo_mo(ikp)%matrix, 0.0_dp)
    3153             : 
    3154       11160 :          ALLOCATE (matrix_berry_im_mo_mo(ikp)%matrix)
    3155       11160 :          CALL dbcsr_init_p(matrix_berry_im_mo_mo(ikp)%matrix)
    3156             :          CALL dbcsr_create(matrix_berry_im_mo_mo(ikp)%matrix, &
    3157             :                            template=matrix_s(1)%matrix, &
    3158       11160 :                            matrix_type=dbcsr_type_no_symmetry)
    3159       11160 :          CALL dbcsr_desymmetrize(matrix_s(1)%matrix, matrix_berry_im_mo_mo(ikp)%matrix)
    3160       11160 :          CALL dbcsr_set(matrix_berry_im_mo_mo(ikp)%matrix, 0.0_dp)
    3161             : 
    3162       44640 :          correct_kpoint(1:3) = -twopi*kpoints%xkp(1:3, ikp)
    3163             : 
    3164       11160 :          abs_kpoint = SQRT(correct_kpoint(1)**2 + correct_kpoint(2)**2 + correct_kpoint(3)**2)
    3165             : 
    3166       11160 :          IF (abs_kpoint < eps_kpoint) THEN
    3167             : 
    3168           0 :             scale_kpoint = eps_kpoint/abs_kpoint
    3169           0 :             correct_kpoint(:) = correct_kpoint(:)*scale_kpoint
    3170             : 
    3171             :          END IF
    3172             : 
    3173             :          ! get the Berry phase
    3174       11160 :          IF (do_aux_bas) THEN
    3175             :             CALL build_berry_moment_matrix(qs_env, cosmat, sinmat, correct_kpoint, sab_orb_external=sab_orb_mic, &
    3176        1944 :                                            basis_type="AUX_GW")
    3177             :          ELSE
    3178             :             CALL build_berry_moment_matrix(qs_env, cosmat, sinmat, correct_kpoint, sab_orb_external=sab_orb_mic, &
    3179        9216 :                                            basis_type="ORB")
    3180             :          END IF
    3181             : 
    3182       11160 :          IF (do_mo_coeff_Gamma_only) THEN
    3183             : 
    3184       11160 :             CALL dbcsr_desymmetrize(cosmat, cosmat_desymm)
    3185             : 
    3186             :             CALL dbcsr_multiply('N', 'N', 1.0_dp, cosmat_desymm, mat_mo_coeff_Gamma_occ_and_GW, 0.0_dp, tmp, &
    3187       11160 :                                 filter_eps=1.0E-15_dp)
    3188             : 
    3189             :             CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_Gamma_all, tmp, 0.0_dp, &
    3190       11160 :                                 matrix_berry_re_mo_mo(ikp)%matrix, filter_eps=1.0E-15_dp)
    3191             : 
    3192       11160 :             CALL dbcsr_desymmetrize(sinmat, sinmat_desymm)
    3193             : 
    3194             :             CALL dbcsr_multiply('N', 'N', 1.0_dp, sinmat_desymm, mat_mo_coeff_Gamma_occ_and_GW, 0.0_dp, tmp, &
    3195       11160 :                                 filter_eps=1.0E-15_dp)
    3196             : 
    3197             :             CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_Gamma_all, tmp, 0.0_dp, &
    3198       11160 :                                 matrix_berry_im_mo_mo(ikp)%matrix, filter_eps=1.0E-15_dp)
    3199             : 
    3200             :          ELSE
    3201             : 
    3202             :             ! get mo coeff at the ikp
    3203             :             CALL copy_fm_to_dbcsr(kpoints%kp_env(ikp)%kpoint_env%mos(1, 1)%mo_coeff, &
    3204           0 :                                   mat_mo_coeff_re, keep_sparsity=.FALSE.)
    3205             : 
    3206             :             CALL copy_fm_to_dbcsr(kpoints%kp_env(ikp)%kpoint_env%mos(2, 1)%mo_coeff, &
    3207           0 :                                   mat_mo_coeff_im, keep_sparsity=.FALSE.)
    3208             : 
    3209           0 :             CALL dbcsr_desymmetrize(cosmat, cosmat_desymm)
    3210             : 
    3211           0 :             CALL dbcsr_desymmetrize(sinmat, sinmat_desymm)
    3212             : 
    3213             :             ! I.
    3214           0 :             CALL dbcsr_multiply('N', 'N', 1.0_dp, cosmat_desymm, mat_mo_coeff_re, 0.0_dp, tmp)
    3215             : 
    3216             :             ! I.1
    3217             :             CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_Gamma_all, tmp, 0.0_dp, &
    3218           0 :                                 matrix_berry_re_mo_mo(ikp)%matrix)
    3219             : 
    3220             :             ! II.
    3221           0 :             CALL dbcsr_multiply('N', 'N', 1.0_dp, sinmat_desymm, mat_mo_coeff_re, 0.0_dp, tmp)
    3222             : 
    3223             :             ! II.5
    3224             :             CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_Gamma_all, tmp, 0.0_dp, &
    3225           0 :                                 matrix_berry_im_mo_mo(ikp)%matrix)
    3226             : 
    3227             :             ! III.
    3228           0 :             CALL dbcsr_multiply('N', 'N', 1.0_dp, cosmat_desymm, mat_mo_coeff_im, 0.0_dp, tmp)
    3229             : 
    3230             :             ! III.7
    3231             :             CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_Gamma_all, tmp, 1.0_dp, &
    3232           0 :                                 matrix_berry_im_mo_mo(ikp)%matrix)
    3233             : 
    3234             :             ! IV.
    3235           0 :             CALL dbcsr_multiply('N', 'N', 1.0_dp, sinmat_desymm, mat_mo_coeff_im, 0.0_dp, tmp)
    3236             : 
    3237             :             ! IV.3
    3238             :             CALL dbcsr_multiply('T', 'N', -1.0_dp, mat_mo_coeff_Gamma_all, tmp, 1.0_dp, &
    3239           0 :                                 matrix_berry_re_mo_mo(ikp)%matrix)
    3240             : 
    3241             :          END IF
    3242             : 
    3243       11166 :          IF (abs_kpoint < eps_kpoint) THEN
    3244             : 
    3245           0 :             CALL dbcsr_scale(matrix_berry_im_mo_mo(ikp)%matrix, 1.0_dp/scale_kpoint)
    3246           0 :             CALL dbcsr_set(matrix_berry_re_mo_mo(ikp)%matrix, 0.0_dp)
    3247           0 :             CALL dbcsr_add_on_diag(matrix_berry_re_mo_mo(ikp)%matrix, 1.0_dp)
    3248             : 
    3249             :          END IF
    3250             : 
    3251             :       END DO
    3252             : 
    3253           6 :       CALL dbcsr_release_p(cosmat)
    3254           6 :       CALL dbcsr_release_p(sinmat)
    3255           6 :       CALL dbcsr_release_p(mat_mo_coeff_re)
    3256           6 :       CALL dbcsr_release_p(mat_mo_coeff_im)
    3257           6 :       CALL dbcsr_release_p(mat_mo_coeff_Gamma_all)
    3258           6 :       CALL dbcsr_release_p(mat_mo_coeff_Gamma_occ_and_GW)
    3259           6 :       CALL dbcsr_release_p(tmp)
    3260           6 :       CALL dbcsr_release_p(cosmat_desymm)
    3261           6 :       CALL dbcsr_release_p(sinmat_desymm)
    3262           6 :       DEALLOCATE (orb_basis_set_list)
    3263             : 
    3264           6 :       CALL release_neighbor_list_sets(sab_orb_mic)
    3265             : 
    3266           6 :       IF (do_aux_bas) THEN
    3267             : 
    3268           2 :          DEALLOCATE (gw_aux_basis_set_list)
    3269           2 :          CALL dbcsr_deallocate_matrix_set(matrix_s_aux_aux)
    3270           2 :          CALL dbcsr_deallocate_matrix_set(matrix_s_aux_orb)
    3271           2 :          CALL dbcsr_release_p(mat_work_aux_orb)
    3272           2 :          CALL dbcsr_release_p(mat_work_aux_orb_2)
    3273           2 :          CALL dbcsr_release_p(mat_mo_coeff_aux)
    3274           2 :          CALL dbcsr_release_p(mat_mo_coeff_aux_2)
    3275           2 :          CALL dbcsr_release_p(matrix_s_inv_aux_aux)
    3276           2 :          CALL dbcsr_release_p(matrix_P)
    3277           2 :          CALL dbcsr_release_p(matrix_P_sqrt)
    3278           2 :          CALL dbcsr_release_p(matrix_P_sqrt_inv)
    3279             : 
    3280           2 :          CALL cp_fm_struct_release(fm_struct_aux_aux)
    3281             : 
    3282           2 :          CALL cp_fm_release(fm_mat_s_aux_aux_inv)
    3283           2 :          CALL cp_fm_release(fm_mat_work_aux_aux)
    3284           2 :          CALL cp_fm_release(fm_mat_P)
    3285           2 :          CALL cp_fm_release(fm_mat_eigv_P)
    3286           2 :          CALL cp_fm_release(fm_mat_scaled_eigv_P)
    3287           2 :          CALL cp_fm_release(fm_mat_P_sqrt_inv)
    3288             : 
    3289             :          ! Deallocate the neighbor list structure
    3290           2 :          CALL release_neighbor_list_sets(sgwgw_list)
    3291           2 :          CALL release_neighbor_list_sets(sgworb_list)
    3292             : 
    3293             :       END IF
    3294             : 
    3295           6 :       CALL timestop(handle)
    3296             : 
    3297           6 :    END SUBROUTINE get_berry_phase
    3298             : 
    3299             : ! **************************************************************************************************
    3300             : !> \brief ...
    3301             : !> \param mat_mo_coeff_Gamma_occ_and_GW ...
    3302             : !> \param homo ...
    3303             : !> \param gw_corr_lev_virt ...
    3304             : ! **************************************************************************************************
    3305           6 :    SUBROUTINE remove_unnecessary_blocks(mat_mo_coeff_Gamma_occ_and_GW, homo, gw_corr_lev_virt)
    3306             : 
    3307             :       TYPE(dbcsr_type), POINTER                          :: mat_mo_coeff_Gamma_occ_and_GW
    3308             :       INTEGER, INTENT(IN)                                :: homo, gw_corr_lev_virt
    3309             : 
    3310             :       INTEGER                                            :: col, col_offset, row
    3311           6 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: data_block
    3312             :       TYPE(dbcsr_iterator_type)                          :: iter
    3313             : 
    3314           6 :       CALL dbcsr_iterator_start(iter, mat_mo_coeff_Gamma_occ_and_GW)
    3315             : 
    3316          27 :       DO WHILE (dbcsr_iterator_blocks_left(iter))
    3317             : 
    3318             :          CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
    3319          21 :                                         col_offset=col_offset)
    3320             : 
    3321          27 :          IF (col_offset > homo + gw_corr_lev_virt) THEN
    3322             : 
    3323         532 :             data_block = 0.0_dp
    3324             : 
    3325             :          END IF
    3326             : 
    3327             :       END DO
    3328             : 
    3329           6 :       CALL dbcsr_iterator_stop(iter)
    3330             : 
    3331           6 :       CALL dbcsr_filter(mat_mo_coeff_Gamma_occ_and_GW, 1.0E-15_dp)
    3332             : 
    3333           6 :    END SUBROUTINE remove_unnecessary_blocks
    3334             : 
    3335             : ! **************************************************************************************************
    3336             : !> \brief ...
    3337             : !> \param delta_corr ...
    3338             : !> \param eps_inv_head ...
    3339             : !> \param kpoints ...
    3340             : !> \param qs_env ...
    3341             : !> \param matrix_berry_re_mo_mo ...
    3342             : !> \param matrix_berry_im_mo_mo ...
    3343             : !> \param homo ...
    3344             : !> \param gw_corr_lev_occ ...
    3345             : !> \param gw_corr_lev_virt ...
    3346             : !> \param para_env_RPA ...
    3347             : !> \param do_extra_kpoints ...
    3348             : ! **************************************************************************************************
    3349         260 :    SUBROUTINE kpoint_sum_for_eps_inv_head_Berry(delta_corr, eps_inv_head, kpoints, qs_env, matrix_berry_re_mo_mo, &
    3350         260 :                                                 matrix_berry_im_mo_mo, homo, gw_corr_lev_occ, gw_corr_lev_virt, &
    3351             :                                                 para_env_RPA, do_extra_kpoints)
    3352             : 
    3353             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
    3354             :          INTENT(INOUT)                                   :: delta_corr
    3355             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: eps_inv_head
    3356             :       TYPE(kpoint_type), POINTER                         :: kpoints
    3357             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3358             :       TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN)       :: matrix_berry_re_mo_mo, &
    3359             :                                                             matrix_berry_im_mo_mo
    3360             :       INTEGER, INTENT(IN)                                :: homo, gw_corr_lev_occ, gw_corr_lev_virt
    3361             :       TYPE(mp_para_env_type), INTENT(IN), OPTIONAL       :: para_env_RPA
    3362             :       LOGICAL, INTENT(IN)                                :: do_extra_kpoints
    3363             : 
    3364             :       INTEGER                                            :: col, col_offset, col_size, i_col, i_row, &
    3365             :                                                             ikp, m_level, n_level_gw, nkp, row, &
    3366             :                                                             row_offset, row_size
    3367             :       REAL(KIND=dp)                                      :: abs_k_square, cell_volume, &
    3368             :                                                             check_int_one_over_ksq, contribution, &
    3369             :                                                             weight
    3370             :       REAL(KIND=dp), DIMENSION(3)                        :: correct_kpoint
    3371         260 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: delta_corr_extra
    3372         260 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: data_block
    3373             :       TYPE(cell_type), POINTER                           :: cell
    3374             :       TYPE(dbcsr_iterator_type)                          :: iter, iter_new
    3375             : 
    3376         260 :       CALL get_qs_env(qs_env=qs_env, cell=cell)
    3377             : 
    3378         260 :       CALL get_cell(cell=cell, deth=cell_volume)
    3379             : 
    3380         260 :       nkp = kpoints%nkp
    3381             : 
    3382        3800 :       delta_corr = 0.0_dp
    3383             : 
    3384         260 :       IF (do_extra_kpoints) THEN
    3385         260 :          NULLIFY (delta_corr_extra)
    3386         780 :          ALLOCATE (delta_corr_extra(1 + homo - gw_corr_lev_occ:homo + gw_corr_lev_virt))
    3387        3800 :          delta_corr_extra = 0.0_dp
    3388             :       END IF
    3389             : 
    3390         260 :       check_int_one_over_ksq = 0.0_dp
    3391             : 
    3392      279620 :       DO ikp = 1, nkp
    3393             : 
    3394      279360 :          weight = kpoints%wkp(ikp)
    3395             : 
    3396     1117440 :          correct_kpoint(1:3) = twopi*kpoints%xkp(1:3, ikp)
    3397             : 
    3398      279360 :          abs_k_square = (correct_kpoint(1))**2 + (correct_kpoint(2))**2 + (correct_kpoint(3))**2
    3399             : 
    3400             :          ! cos part of the Berry phase
    3401      279360 :          CALL dbcsr_iterator_start(iter, matrix_berry_re_mo_mo(ikp)%matrix)
    3402      465120 :          DO WHILE (dbcsr_iterator_blocks_left(iter))
    3403             : 
    3404             :             CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
    3405             :                                            row_size=row_size, col_size=col_size, &
    3406      185760 :                                            row_offset=row_offset, col_offset=col_offset)
    3407             : 
    3408     2880000 :             DO i_col = 1, col_size
    3409             : 
    3410    31916160 :                DO n_level_gw = 1 + homo - gw_corr_lev_occ, homo + gw_corr_lev_virt
    3411             : 
    3412    31730400 :                   IF (n_level_gw == i_col + col_offset - 1) THEN
    3413             : 
    3414    26619840 :                      DO i_row = 1, row_size
    3415             : 
    3416    24481440 :                         contribution = weight*(eps_inv_head(ikp) - 1.0_dp)/abs_k_square*(data_block(i_row, i_col))**2
    3417             : 
    3418    24481440 :                         m_level = i_row + row_offset - 1
    3419             : 
    3420             :                         ! we only compute the correction for n=m
    3421    24481440 :                         IF (m_level .NE. n_level_gw) CYCLE
    3422             : 
    3423     3862080 :                         IF (.NOT. do_extra_kpoints) THEN
    3424             : 
    3425           0 :                            delta_corr(n_level_gw) = delta_corr(n_level_gw) + contribution
    3426             : 
    3427             :                         ELSE
    3428             : 
    3429     1723680 :                            IF (ikp <= nkp*8/9) THEN
    3430             : 
    3431     1532160 :                               delta_corr(n_level_gw) = delta_corr(n_level_gw) + contribution
    3432             : 
    3433             :                            ELSE
    3434             : 
    3435      191520 :                               delta_corr_extra(n_level_gw) = delta_corr_extra(n_level_gw) + contribution
    3436             : 
    3437             :                            END IF
    3438             : 
    3439             :                         END IF
    3440             : 
    3441             :                      END DO
    3442             : 
    3443             :                   END IF
    3444             : 
    3445             :                END DO
    3446             : 
    3447             :             END DO
    3448             : 
    3449             :          END DO
    3450             : 
    3451      279360 :          CALL dbcsr_iterator_stop(iter)
    3452             : 
    3453             :          ! the same for the im. part of the Berry phase
    3454      279360 :          CALL dbcsr_iterator_start(iter_new, matrix_berry_im_mo_mo(ikp)%matrix)
    3455      465120 :          DO WHILE (dbcsr_iterator_blocks_left(iter_new))
    3456             : 
    3457             :             CALL dbcsr_iterator_next_block(iter_new, row, col, data_block, &
    3458             :                                            row_size=row_size, col_size=col_size, &
    3459      185760 :                                            row_offset=row_offset, col_offset=col_offset)
    3460             : 
    3461     2880000 :             DO i_col = 1, col_size
    3462             : 
    3463    31916160 :                DO n_level_gw = 1 + homo - gw_corr_lev_occ, homo + gw_corr_lev_virt
    3464             : 
    3465    31730400 :                   IF (n_level_gw == i_col + col_offset - 1) THEN
    3466             : 
    3467    26619840 :                      DO i_row = 1, row_size
    3468             : 
    3469    24481440 :                         m_level = i_row + row_offset - 1
    3470             : 
    3471    24481440 :                         contribution = weight*(eps_inv_head(ikp) - 1.0_dp)/abs_k_square*(data_block(i_row, i_col))**2
    3472             : 
    3473             :                         ! we only compute the correction for n=m
    3474    24481440 :                         IF (m_level .NE. n_level_gw) CYCLE
    3475             : 
    3476     3862080 :                         IF (.NOT. do_extra_kpoints) THEN
    3477             : 
    3478           0 :                            delta_corr(n_level_gw) = delta_corr(n_level_gw) + contribution
    3479             : 
    3480             :                         ELSE
    3481             : 
    3482     1723680 :                            IF (ikp <= nkp*8/9) THEN
    3483             : 
    3484     1532160 :                               delta_corr(n_level_gw) = delta_corr(n_level_gw) + contribution
    3485             : 
    3486             :                            ELSE
    3487             : 
    3488      191520 :                               delta_corr_extra(n_level_gw) = delta_corr_extra(n_level_gw) + contribution
    3489             : 
    3490             :                            END IF
    3491             : 
    3492             :                         END IF
    3493             : 
    3494             :                      END DO
    3495             : 
    3496             :                   END IF
    3497             : 
    3498             :                END DO
    3499             : 
    3500             :             END DO
    3501             : 
    3502             :          END DO
    3503             : 
    3504      279360 :          CALL dbcsr_iterator_stop(iter_new)
    3505             : 
    3506      838340 :          check_int_one_over_ksq = check_int_one_over_ksq + weight/abs_k_square
    3507             : 
    3508             :       END DO
    3509             : 
    3510             :       ! normalize by the cell volume
    3511        3800 :       delta_corr = delta_corr/cell_volume*fourpi
    3512             : 
    3513         260 :       check_int_one_over_ksq = check_int_one_over_ksq/cell_volume
    3514             : 
    3515         260 :       CALL para_env_RPA%sum(delta_corr)
    3516             : 
    3517         260 :       IF (do_extra_kpoints) THEN
    3518             : 
    3519        3800 :          delta_corr_extra = delta_corr_extra/cell_volume*fourpi
    3520             : 
    3521        7340 :          CALL para_env_RPA%sum(delta_corr_extra)
    3522             : 
    3523        3800 :          delta_corr(:) = delta_corr(:) + (delta_corr(:) - delta_corr_extra(:))
    3524             : 
    3525         260 :          DEALLOCATE (delta_corr_extra)
    3526             : 
    3527             :       END IF
    3528             : 
    3529         260 :    END SUBROUTINE kpoint_sum_for_eps_inv_head_Berry
    3530             : 
    3531             : ! **************************************************************************************************
    3532             : !> \brief ...
    3533             : !> \param eps_inv_head ...
    3534             : !> \param eps_head ...
    3535             : !> \param kpoints ...
    3536             : ! **************************************************************************************************
    3537         260 :    SUBROUTINE compute_eps_inv_head(eps_inv_head, eps_head, kpoints)
    3538             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
    3539             :          INTENT(OUT)                                     :: eps_inv_head
    3540             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: eps_head
    3541             :       TYPE(kpoint_type), POINTER                         :: kpoints
    3542             : 
    3543             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_eps_inv_head'
    3544             : 
    3545             :       INTEGER                                            :: handle, ikp, nkp
    3546             : 
    3547         260 :       CALL timeset(routineN, handle)
    3548             : 
    3549         260 :       nkp = kpoints%nkp
    3550             : 
    3551         780 :       ALLOCATE (eps_inv_head(nkp))
    3552             : 
    3553      279620 :       DO ikp = 1, nkp
    3554             : 
    3555      279620 :          eps_inv_head(ikp) = 1.0_dp/eps_head(ikp)
    3556             : 
    3557             :       END DO
    3558             : 
    3559         260 :       CALL timestop(handle)
    3560             : 
    3561         260 :    END SUBROUTINE compute_eps_inv_head
    3562             : 
    3563             : ! **************************************************************************************************
    3564             : !> \brief ...
    3565             : !> \param qs_env ...
    3566             : !> \param kpoints ...
    3567             : !> \param kp_grid ...
    3568             : !> \param num_kp_grids ...
    3569             : !> \param para_env ...
    3570             : !> \param h_inv ...
    3571             : !> \param nmo ...
    3572             : !> \param do_mo_coeff_Gamma_only ...
    3573             : !> \param do_extra_kpoints ...
    3574             : ! **************************************************************************************************
    3575           6 :    SUBROUTINE get_kpoints(qs_env, kpoints, kp_grid, num_kp_grids, para_env, h_inv, nmo, &
    3576             :                           do_mo_coeff_Gamma_only, do_extra_kpoints)
    3577             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3578             :       TYPE(kpoint_type), POINTER                         :: kpoints
    3579             :       INTEGER, DIMENSION(:), POINTER                     :: kp_grid
    3580             :       INTEGER, INTENT(IN)                                :: num_kp_grids
    3581             :       TYPE(mp_para_env_type), INTENT(IN)                 :: para_env
    3582             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT)      :: h_inv
    3583             :       INTEGER, INTENT(IN)                                :: nmo
    3584             :       LOGICAL, INTENT(IN)                                :: do_mo_coeff_Gamma_only, do_extra_kpoints
    3585             : 
    3586             :       INTEGER                                            :: end_kp, i, i_grid_level, ix, iy, iz, &
    3587             :                                                             nkp_inner_grid, nkp_outer_grid, &
    3588             :                                                             npoints, start_kp
    3589             :       INTEGER, DIMENSION(3)                              :: outer_kp_grid
    3590             :       REAL(KIND=dp)                                      :: kpoint_weight_left, single_weight
    3591             :       REAL(KIND=dp), DIMENSION(3)                        :: kpt_latt, reducing_factor
    3592             :       TYPE(cell_type), POINTER                           :: cell
    3593           6 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    3594             : 
    3595           6 :       NULLIFY (kpoints, cell, particle_set)
    3596             : 
    3597             :       ! check whether kp_grid includes the Gamma point. If so, abort.
    3598           6 :       CPASSERT(MOD(kp_grid(1)*kp_grid(2)*kp_grid(3), 2) == 0)
    3599           6 :       IF (do_extra_kpoints) THEN
    3600           6 :          CPASSERT(do_mo_coeff_Gamma_only)
    3601             :       END IF
    3602             : 
    3603           6 :       IF (do_mo_coeff_Gamma_only) THEN
    3604             : 
    3605           6 :          outer_kp_grid(1) = kp_grid(1) - 1
    3606           6 :          outer_kp_grid(2) = kp_grid(2) - 1
    3607           6 :          outer_kp_grid(3) = kp_grid(3) - 1
    3608             : 
    3609           6 :          CALL get_qs_env(qs_env=qs_env, cell=cell, particle_set=particle_set)
    3610             : 
    3611           6 :          CALL get_cell(cell, h_inv=h_inv)
    3612             : 
    3613           6 :          CALL kpoint_create(kpoints)
    3614             : 
    3615           6 :          kpoints%kp_scheme = "GENERAL"
    3616           6 :          kpoints%symmetry = .FALSE.
    3617           6 :          kpoints%verbose = .FALSE.
    3618           6 :          kpoints%full_grid = .FALSE.
    3619           6 :          kpoints%use_real_wfn = .FALSE.
    3620           6 :          kpoints%eps_geo = 1.e-6_dp
    3621             :          npoints = kp_grid(1)*kp_grid(2)*kp_grid(3)/2 + &
    3622           6 :                    (num_kp_grids - 1)*((outer_kp_grid(1) + 1)/2*outer_kp_grid(2)*outer_kp_grid(3) - 1)
    3623             : 
    3624           6 :          IF (do_extra_kpoints) THEN
    3625             : 
    3626           6 :             CPASSERT(num_kp_grids == 1)
    3627           6 :             CPASSERT(MOD(kp_grid(1), 4) == 0)
    3628           6 :             CPASSERT(MOD(kp_grid(2), 4) == 0)
    3629           6 :             CPASSERT(MOD(kp_grid(3), 4) == 0)
    3630             : 
    3631             :          END IF
    3632             : 
    3633           6 :          IF (do_extra_kpoints) THEN
    3634             : 
    3635           6 :             npoints = kp_grid(1)*kp_grid(2)*kp_grid(3)/2 + kp_grid(1)*kp_grid(2)*kp_grid(3)/2/8
    3636             : 
    3637             :          END IF
    3638             : 
    3639           6 :          kpoints%full_grid = .TRUE.
    3640           6 :          kpoints%nkp = npoints
    3641          30 :          ALLOCATE (kpoints%xkp(3, npoints), kpoints%wkp(npoints))
    3642       44646 :          kpoints%xkp = 0.0_dp
    3643       11166 :          kpoints%wkp = 0.0_dp
    3644             : 
    3645           6 :          nkp_outer_grid = outer_kp_grid(1)*outer_kp_grid(2)*outer_kp_grid(3)
    3646           6 :          nkp_inner_grid = kp_grid(1)*kp_grid(2)*kp_grid(3)
    3647             : 
    3648           6 :          i = 0
    3649          24 :          reducing_factor(:) = 1.0_dp
    3650             :          kpoint_weight_left = 1.0_dp
    3651             : 
    3652             :          ! the outer grids
    3653           6 :          DO i_grid_level = 1, num_kp_grids - 1
    3654             : 
    3655           0 :             single_weight = kpoint_weight_left/REAL(nkp_outer_grid, KIND=dp)
    3656             : 
    3657           0 :             start_kp = i + 1
    3658             : 
    3659           0 :             DO ix = 1, outer_kp_grid(1)
    3660           0 :                DO iy = 1, outer_kp_grid(2)
    3661           0 :                   DO iz = 1, outer_kp_grid(3)
    3662             : 
    3663             :                      ! exclude Gamma
    3664           0 :                      IF (2*ix - outer_kp_grid(1) - 1 == 0 .AND. 2*iy - outer_kp_grid(2) - 1 == 0 .AND. &
    3665             :                          2*iz - outer_kp_grid(3) - 1 == 0) CYCLE
    3666             : 
    3667             :                      ! use time reversal symmetry k<->-k
    3668           0 :                      IF (2*ix - outer_kp_grid(1) - 1 < 0) CYCLE
    3669             : 
    3670           0 :                      i = i + 1
    3671             :                      kpt_latt(1) = REAL(2*ix - outer_kp_grid(1) - 1, KIND=dp)/(2._dp*REAL(outer_kp_grid(1), KIND=dp)) &
    3672           0 :                                    *reducing_factor(1)
    3673             :                      kpt_latt(2) = REAL(2*iy - outer_kp_grid(2) - 1, KIND=dp)/(2._dp*REAL(outer_kp_grid(2), KIND=dp)) &
    3674           0 :                                    *reducing_factor(2)
    3675             :                      kpt_latt(3) = REAL(2*iz - outer_kp_grid(3) - 1, KIND=dp)/(2._dp*REAL(outer_kp_grid(3), KIND=dp)) &
    3676           0 :                                    *reducing_factor(3)
    3677           0 :                      kpoints%xkp(1:3, i) = MATMUL(TRANSPOSE(h_inv), kpt_latt(:))
    3678             : 
    3679           0 :                      IF (2*ix - outer_kp_grid(1) - 1 == 0) THEN
    3680           0 :                         kpoints%wkp(i) = single_weight
    3681             :                      ELSE
    3682           0 :                         kpoints%wkp(i) = 2._dp*single_weight
    3683             :                      END IF
    3684             : 
    3685             :                   END DO
    3686             :                END DO
    3687             :             END DO
    3688             : 
    3689           0 :             end_kp = i
    3690             : 
    3691           0 :             kpoint_weight_left = kpoint_weight_left - SUM(kpoints%wkp(start_kp:end_kp))
    3692             : 
    3693           0 :             reducing_factor(1) = reducing_factor(1)/REAL(outer_kp_grid(1), KIND=dp)
    3694           0 :             reducing_factor(2) = reducing_factor(2)/REAL(outer_kp_grid(2), KIND=dp)
    3695           6 :             reducing_factor(3) = reducing_factor(3)/REAL(outer_kp_grid(3), KIND=dp)
    3696             : 
    3697             :          END DO
    3698             : 
    3699           6 :          single_weight = kpoint_weight_left/REAL(nkp_inner_grid, KIND=dp)
    3700             : 
    3701             :          ! the inner grid
    3702          94 :          DO ix = 1, kp_grid(1)
    3703        1406 :             DO iy = 1, kp_grid(2)
    3704       21240 :                DO iz = 1, kp_grid(3)
    3705             : 
    3706             :                   ! use time reversal symmetry k<->-k
    3707       19840 :                   IF (2*ix - kp_grid(1) - 1 < 0) CYCLE
    3708             : 
    3709        9920 :                   i = i + 1
    3710        9920 :                   kpt_latt(1) = REAL(2*ix - kp_grid(1) - 1, KIND=dp)/(2._dp*REAL(kp_grid(1), KIND=dp))*reducing_factor(1)
    3711        9920 :                   kpt_latt(2) = REAL(2*iy - kp_grid(2) - 1, KIND=dp)/(2._dp*REAL(kp_grid(2), KIND=dp))*reducing_factor(2)
    3712        9920 :                   kpt_latt(3) = REAL(2*iz - kp_grid(3) - 1, KIND=dp)/(2._dp*REAL(kp_grid(3), KIND=dp))*reducing_factor(3)
    3713             : 
    3714       39680 :                   kpoints%xkp(1:3, i) = MATMUL(TRANSPOSE(h_inv), kpt_latt(:))
    3715             : 
    3716       21152 :                   kpoints%wkp(i) = 2._dp*single_weight
    3717             : 
    3718             :                END DO
    3719             :             END DO
    3720             :          END DO
    3721             : 
    3722           6 :          IF (do_extra_kpoints) THEN
    3723             : 
    3724           6 :             single_weight = kpoint_weight_left/REAL(kp_grid(1)*kp_grid(2)*kp_grid(3)/8, KIND=dp)
    3725             : 
    3726          50 :             DO ix = 1, kp_grid(1)/2
    3727         378 :                DO iy = 1, kp_grid(2)/2
    3728        2852 :                   DO iz = 1, kp_grid(3)/2
    3729             : 
    3730             :                      ! use time reversal symmetry k<->-k
    3731        2480 :                      IF (2*ix - kp_grid(1)/2 - 1 < 0) CYCLE
    3732             : 
    3733        1240 :                      i = i + 1
    3734        1240 :                      kpt_latt(1) = REAL(2*ix - kp_grid(1)/2 - 1, KIND=dp)/(REAL(kp_grid(1), KIND=dp))
    3735        1240 :                      kpt_latt(2) = REAL(2*iy - kp_grid(2)/2 - 1, KIND=dp)/(REAL(kp_grid(2), KIND=dp))
    3736        1240 :                      kpt_latt(3) = REAL(2*iz - kp_grid(3)/2 - 1, KIND=dp)/(REAL(kp_grid(3), KIND=dp))
    3737             : 
    3738        4960 :                      kpoints%xkp(1:3, i) = MATMUL(TRANSPOSE(h_inv), kpt_latt(:))
    3739             : 
    3740        2808 :                      kpoints%wkp(i) = 2._dp*single_weight
    3741             : 
    3742             :                   END DO
    3743             :                END DO
    3744             :             END DO
    3745             : 
    3746             :          END IF
    3747             : 
    3748             :          ! default: no symmetry settings
    3749       11178 :          ALLOCATE (kpoints%kp_sym(kpoints%nkp))
    3750       11166 :          DO i = 1, kpoints%nkp
    3751       11160 :             NULLIFY (kpoints%kp_sym(i)%kpoint_sym)
    3752       11166 :             CALL kpoint_sym_create(kpoints%kp_sym(i)%kpoint_sym)
    3753             :          END DO
    3754             : 
    3755             :       ELSE
    3756             : 
    3757             :          BLOCK
    3758             :             TYPE(qs_environment_type), POINTER :: qs_env_kp_Gamma_only
    3759           0 :             CALL create_kp_from_gamma(qs_env, qs_env_kp_Gamma_only)
    3760             : 
    3761           0 :             CALL get_qs_env(qs_env=qs_env, cell=cell, particle_set=particle_set)
    3762             : 
    3763             :             CALL calculate_kp_orbitals(qs_env_kp_Gamma_only, kpoints, "MONKHORST-PACK", nadd=nmo, mp_grid=kp_grid(1:3), &
    3764           0 :                                        group_size_ext=para_env%num_pe)
    3765             : 
    3766           0 :             CALL qs_env_release(qs_env_kp_Gamma_only)
    3767           0 :             DEALLOCATE (qs_env_kp_Gamma_only)
    3768             :          END BLOCK
    3769             : 
    3770             :       END IF
    3771             : 
    3772           6 :    END SUBROUTINE get_kpoints
    3773             : 
    3774             : ! **************************************************************************************************
    3775             : !> \brief ...
    3776             : !> \param vec_Sigma_c_gw ...
    3777             : !> \param Eigenval_DFT ...
    3778             : !> \param eps_eigenval ...
    3779             : ! **************************************************************************************************
    3780          10 :    PURE SUBROUTINE average_degenerate_levels(vec_Sigma_c_gw, Eigenval_DFT, eps_eigenval)
    3781             :       COMPLEX(KIND=dp), DIMENSION(:, :, :), &
    3782             :          INTENT(INOUT)                                   :: vec_Sigma_c_gw
    3783             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: Eigenval_DFT
    3784             :       REAL(KIND=dp), INTENT(IN)                          :: eps_eigenval
    3785             : 
    3786          10 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:)        :: avg_self_energy
    3787             :       INTEGER :: degeneracy, first_degenerate_level, i_deg_level, i_level_gw, j_deg_level, jquad, &
    3788             :          num_deg_levels, num_integ_points, num_levels_gw
    3789          10 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: list_degenerate_levels
    3790             : 
    3791          10 :       num_levels_gw = SIZE(vec_Sigma_c_gw, 1)
    3792             : 
    3793          30 :       ALLOCATE (list_degenerate_levels(num_levels_gw))
    3794         130 :       list_degenerate_levels = 1
    3795             : 
    3796          10 :       num_integ_points = SIZE(vec_Sigma_c_gw, 2)
    3797             : 
    3798          30 :       ALLOCATE (avg_self_energy(num_integ_points))
    3799             : 
    3800         120 :       DO i_level_gw = 2, num_levels_gw
    3801             : 
    3802         120 :          IF (ABS(Eigenval_DFT(i_level_gw) - Eigenval_DFT(i_level_gw - 1)) < eps_eigenval) THEN
    3803             : 
    3804           0 :             list_degenerate_levels(i_level_gw) = list_degenerate_levels(i_level_gw - 1)
    3805             : 
    3806             :          ELSE
    3807             : 
    3808         110 :             list_degenerate_levels(i_level_gw) = list_degenerate_levels(i_level_gw - 1) + 1
    3809             : 
    3810             :          END IF
    3811             : 
    3812             :       END DO
    3813             : 
    3814          10 :       num_deg_levels = list_degenerate_levels(num_levels_gw)
    3815             : 
    3816         130 :       DO i_deg_level = 1, num_deg_levels
    3817             : 
    3818             :          degeneracy = 0
    3819             : 
    3820        1624 :          DO i_level_gw = 1, num_levels_gw
    3821             : 
    3822        1504 :             IF (degeneracy == 0 .AND. i_deg_level == list_degenerate_levels(i_level_gw)) THEN
    3823             : 
    3824         120 :                first_degenerate_level = i_level_gw
    3825             : 
    3826             :             END IF
    3827             : 
    3828        1624 :             IF (i_deg_level == list_degenerate_levels(i_level_gw)) THEN
    3829             : 
    3830         120 :                degeneracy = degeneracy + 1
    3831             : 
    3832             :             END IF
    3833             : 
    3834             :          END DO
    3835             : 
    3836        3120 :          DO jquad = 1, num_integ_points
    3837             : 
    3838             :             avg_self_energy(jquad) = SUM(vec_Sigma_c_gw(first_degenerate_level:first_degenerate_level + degeneracy - 1, jquad, 1)) &
    3839        6120 :                                      /REAL(degeneracy, KIND=dp)
    3840             : 
    3841             :          END DO
    3842             : 
    3843         250 :          DO j_deg_level = 0, degeneracy - 1
    3844             : 
    3845        3240 :             vec_Sigma_c_gw(first_degenerate_level + j_deg_level, :, 1) = avg_self_energy(:)
    3846             : 
    3847             :          END DO
    3848             : 
    3849             :       END DO
    3850             : 
    3851          10 :    END SUBROUTINE average_degenerate_levels
    3852             : 
    3853             : ! **************************************************************************************************
    3854             : !> \brief ...
    3855             : !> \param vec_gw_energ ...
    3856             : !> \param vec_omega_fit_gw ...
    3857             : !> \param z_value ...
    3858             : !> \param m_value ...
    3859             : !> \param vec_Sigma_c_gw ...
    3860             : !> \param vec_Sigma_x_minus_vxc_gw ...
    3861             : !> \param Eigenval ...
    3862             : !> \param Eigenval_scf ...
    3863             : !> \param n_level_gw ...
    3864             : !> \param gw_corr_lev_occ ...
    3865             : !> \param gw_corr_lev_vir ...
    3866             : !> \param num_poles ...
    3867             : !> \param num_fit_points ...
    3868             : !> \param crossing_search ...
    3869             : !> \param homo ...
    3870             : !> \param stop_crit ...
    3871             : !> \param fermi_level_offset ...
    3872             : !> \param do_gw_im_time ...
    3873             : ! **************************************************************************************************
    3874         568 :    SUBROUTINE fit_and_continuation_2pole(vec_gw_energ, vec_omega_fit_gw, &
    3875        1136 :                                          z_value, m_value, vec_Sigma_c_gw, vec_Sigma_x_minus_vxc_gw, &
    3876        1136 :                                          Eigenval, Eigenval_scf, n_level_gw, &
    3877             :                                          gw_corr_lev_occ, gw_corr_lev_vir, num_poles, &
    3878             :                                          num_fit_points, crossing_search, homo, stop_crit, &
    3879             :                                          fermi_level_offset, do_gw_im_time)
    3880             : 
    3881             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: vec_gw_energ, vec_omega_fit_gw, z_value, &
    3882             :                                                             m_value
    3883             :       COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(IN)      :: vec_Sigma_c_gw
    3884             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: vec_Sigma_x_minus_vxc_gw, Eigenval, &
    3885             :                                                             Eigenval_scf
    3886             :       INTEGER, INTENT(IN)                                :: n_level_gw, gw_corr_lev_occ, &
    3887             :                                                             gw_corr_lev_vir, num_poles, &
    3888             :                                                             num_fit_points, crossing_search, homo
    3889             :       REAL(KIND=dp), INTENT(IN)                          :: stop_crit, fermi_level_offset
    3890             :       LOGICAL, INTENT(IN)                                :: do_gw_im_time
    3891             : 
    3892             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'fit_and_continuation_2pole'
    3893             : 
    3894             :       COMPLEX(KIND=dp)                                   :: func_val, rho1
    3895         568 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:)        :: dLambda, dLambda_2, Lambda, &
    3896         568 :                                                             Lambda_without_offset, vec_b_gw, &
    3897         568 :                                                             vec_b_gw_copy
    3898         568 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :)     :: mat_A_gw, mat_B_gw
    3899             :       INTEGER                                            :: handle4, ierr, iii, iiter, info, &
    3900             :                                                             integ_range, jjj, jquad, kkk, &
    3901             :                                                             max_iter_fit, n_level_gw_ref, num_var, &
    3902             :                                                             xpos
    3903         568 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: ipiv
    3904             :       LOGICAL                                            :: could_exit
    3905             :       REAL(KIND=dp) :: chi2, chi2_old, delta, deriv_val_real, e_fermi, gw_energ, Ldown, &
    3906             :          level_energ_GW, Lup, range_step, ScalParam, sign_occ_virt, stat_error
    3907         568 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: Lambda_Im, Lambda_Re, stat_errors, &
    3908         568 :                                                             vec_N_gw, vec_omega_fit_gw_sign
    3909         568 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: mat_N_gw
    3910             : 
    3911         568 :       max_iter_fit = 10000
    3912             : 
    3913         568 :       num_var = 2*num_poles + 1
    3914        1704 :       ALLOCATE (Lambda(num_var))
    3915        3408 :       Lambda = z_zero
    3916        1136 :       ALLOCATE (Lambda_without_offset(num_var))
    3917        3408 :       Lambda_without_offset = z_zero
    3918        1704 :       ALLOCATE (Lambda_Re(num_var))
    3919        3408 :       Lambda_Re = 0.0_dp
    3920        1136 :       ALLOCATE (Lambda_Im(num_var))
    3921        3408 :       Lambda_Im = 0.0_dp
    3922             : 
    3923        1704 :       ALLOCATE (vec_omega_fit_gw_sign(num_fit_points))
    3924             : 
    3925         568 :       IF (n_level_gw <= gw_corr_lev_occ) THEN
    3926             :          sign_occ_virt = -1.0_dp
    3927             :       ELSE
    3928         405 :          sign_occ_virt = 1.0_dp
    3929             :       END IF
    3930             : 
    3931         568 :       n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
    3932             : 
    3933        6630 :       DO jquad = 1, num_fit_points
    3934        6630 :          vec_omega_fit_gw_sign(jquad) = ABS(vec_omega_fit_gw(jquad))*sign_occ_virt
    3935             :       END DO
    3936             : 
    3937             :       ! initial guess
    3938         568 :       range_step = (vec_omega_fit_gw_sign(num_fit_points) - vec_omega_fit_gw_sign(1))/(num_poles - 1)
    3939        1704 :       DO iii = 1, num_poles
    3940        1704 :          Lambda_Im(2*iii + 1) = vec_omega_fit_gw_sign(1) + (iii - 1)*range_step
    3941             :       END DO
    3942         568 :       range_step = (vec_omega_fit_gw_sign(num_fit_points) - vec_omega_fit_gw_sign(1))/num_poles
    3943        1704 :       DO iii = 1, num_poles
    3944        1704 :          Lambda_Re(2*iii + 1) = ABS(vec_omega_fit_gw_sign(1) + (iii - 0.5_dp)*range_step)
    3945             :       END DO
    3946             : 
    3947        3408 :       DO iii = 1, num_var
    3948        3408 :          Lambda(iii) = Lambda_Re(iii) + gaussi*Lambda_Im(iii)
    3949             :       END DO
    3950             : 
    3951             :       CALL calc_chi2(chi2_old, Lambda, vec_Sigma_c_gw, vec_omega_fit_gw_sign, num_poles, &
    3952         568 :                      num_fit_points, n_level_gw)
    3953             : 
    3954        2272 :       ALLOCATE (mat_A_gw(num_poles + 1, num_poles + 1))
    3955        1704 :       ALLOCATE (vec_b_gw(num_poles + 1))
    3956        1704 :       ALLOCATE (ipiv(num_poles + 1))
    3957        7384 :       mat_A_gw = z_zero
    3958        2272 :       vec_b_gw = 0.0_dp
    3959             : 
    3960        2272 :       mat_A_gw(1:num_poles + 1, 1) = z_one
    3961         568 :       integ_range = num_fit_points/num_poles
    3962        2272 :       DO kkk = 1, num_poles + 1
    3963        1704 :          xpos = (kkk - 1)*integ_range + 1
    3964        1704 :          xpos = MIN(xpos, num_fit_points)
    3965             :          ! calculate coefficient at this point
    3966        5112 :          DO iii = 1, num_poles
    3967        3408 :             jjj = iii*2
    3968             :             func_val = z_one/(gaussi*vec_omega_fit_gw_sign(xpos) - &
    3969        3408 :                               CMPLX(Lambda_Re(jjj + 1), Lambda_Im(jjj + 1), KIND=dp))
    3970        5112 :             mat_A_gw(kkk, iii + 1) = func_val
    3971             :          END DO
    3972        2272 :          vec_b_gw(kkk) = vec_Sigma_c_gw(n_level_gw, xpos)
    3973             :       END DO
    3974             : 
    3975             :       ! Solve system of linear equations
    3976         568 :       CALL ZGETRF(num_poles + 1, num_poles + 1, mat_A_gw, num_poles + 1, ipiv, info)
    3977             : 
    3978         568 :       CALL ZGETRS('N', num_poles + 1, 1, mat_A_gw, num_poles + 1, ipiv, vec_b_gw, num_poles + 1, info)
    3979             : 
    3980         568 :       Lambda_Re(1) = REAL(vec_b_gw(1))
    3981         568 :       Lambda_Im(1) = AIMAG(vec_b_gw(1))
    3982        1704 :       DO iii = 1, num_poles
    3983        1136 :          jjj = iii*2
    3984        1136 :          Lambda_Re(jjj) = REAL(vec_b_gw(iii + 1))
    3985        1704 :          Lambda_Im(jjj) = AIMAG(vec_b_gw(iii + 1))
    3986             :       END DO
    3987             : 
    3988         568 :       DEALLOCATE (mat_A_gw)
    3989         568 :       DEALLOCATE (vec_b_gw)
    3990         568 :       DEALLOCATE (ipiv)
    3991             : 
    3992        2272 :       ALLOCATE (mat_A_gw(num_var*2, num_var*2))
    3993        2272 :       ALLOCATE (mat_B_gw(num_fit_points, num_var*2))
    3994        1704 :       ALLOCATE (dLambda(num_fit_points))
    3995        1136 :       ALLOCATE (dLambda_2(num_fit_points))
    3996        1704 :       ALLOCATE (vec_b_gw(num_var*2))
    3997        1136 :       ALLOCATE (vec_b_gw_copy(num_var*2))
    3998        1704 :       ALLOCATE (ipiv(num_var*2))
    3999             : 
    4000             :       ScalParam = 0.01_dp
    4001             :       Ldown = 1.5_dp
    4002             :       Lup = 10.0_dp
    4003             :       could_exit = .FALSE.
    4004             : 
    4005             :       ! iteration loop for fitting
    4006     1083686 :       DO iiter = 1, max_iter_fit
    4007             : 
    4008     1083659 :          CALL timeset(routineN//"_fit_loop_1", handle4)
    4009             : 
    4010             :          ! calc delta lambda
    4011     6501954 :          DO iii = 1, num_var
    4012     6501954 :             Lambda(iii) = Lambda_Re(iii) + gaussi*Lambda_Im(iii)
    4013             :          END DO
    4014    12309521 :          dLambda = z_zero
    4015             : 
    4016    12309521 :          DO kkk = 1, num_fit_points
    4017    11225862 :             func_val = Lambda(1)
    4018    33677586 :             DO iii = 1, num_poles
    4019    22451724 :                jjj = iii*2
    4020    33677586 :                func_val = func_val + Lambda(jjj)/(vec_omega_fit_gw_sign(kkk)*gaussi - Lambda(jjj + 1))
    4021             :             END DO
    4022    12309521 :             dLambda(kkk) = vec_Sigma_c_gw(n_level_gw, kkk) - func_val
    4023             :          END DO
    4024    12309521 :          rho1 = SUM(dLambda*dLambda)
    4025             : 
    4026             :          ! fill matrix
    4027   124178869 :          mat_B_gw = z_zero
    4028    12309521 :          DO iii = 1, num_fit_points
    4029    11225862 :             mat_B_gw(iii, 1) = 1.0_dp
    4030    12309521 :             mat_B_gw(iii, num_var + 1) = gaussi
    4031             :          END DO
    4032     3250977 :          DO iii = 1, num_poles
    4033     2167318 :             jjj = iii*2
    4034    25702701 :             DO kkk = 1, num_fit_points
    4035    22451724 :                mat_B_gw(kkk, jjj) = 1.0_dp/(gaussi*vec_omega_fit_gw_sign(kkk) - Lambda(jjj + 1))
    4036    22451724 :                mat_B_gw(kkk, jjj + num_var) = gaussi/(gaussi*vec_omega_fit_gw_sign(kkk) - Lambda(jjj + 1))
    4037    22451724 :                mat_B_gw(kkk, jjj + 1) = Lambda(jjj)/(gaussi*vec_omega_fit_gw_sign(kkk) - Lambda(jjj + 1))**2
    4038             :                mat_B_gw(kkk, jjj + 1 + num_var) = (-Lambda_Im(jjj) + gaussi*Lambda_Re(jjj))/ &
    4039    24619042 :                                                   (gaussi*vec_omega_fit_gw_sign(kkk) - Lambda(jjj + 1))**2
    4040             :             END DO
    4041             :          END DO
    4042             : 
    4043     1083659 :          CALL timestop(handle4)
    4044             : 
    4045     1083659 :          CALL timeset(routineN//"_fit_matmul_1", handle4)
    4046             : 
    4047             :          CALL zgemm('C', 'N', num_var*2, num_var*2, num_fit_points, z_one, mat_B_gw, num_fit_points, mat_B_gw, num_fit_points, &
    4048     1083659 :                     z_zero, mat_A_gw, num_var*2)
    4049     1083659 :          CALL timestop(handle4)
    4050             : 
    4051     1083659 :          CALL timeset(routineN//"_fit_zgemv_1", handle4)
    4052             :          CALL zgemv('C', num_fit_points, num_var*2, z_one, mat_B_gw, num_fit_points, dLambda, 1, &
    4053     1083659 :                     z_zero, vec_b_gw, 1)
    4054             : 
    4055     1083659 :          CALL timestop(handle4)
    4056             : 
    4057             :          ! scale diagonal elements of a_mat
    4058    11920249 :          DO iii = 1, num_var*2
    4059    11920249 :             mat_A_gw(iii, iii) = mat_A_gw(iii, iii) + ScalParam*mat_A_gw(iii, iii)
    4060             :          END DO
    4061             : 
    4062             :          ! solve linear system
    4063             :          ierr = 0
    4064    11920249 :          ipiv = 0
    4065             : 
    4066     1083659 :          CALL timeset(routineN//"_fit_lin_eq_2", handle4)
    4067             : 
    4068     1083659 :          CALL ZGETRF(2*num_var, 2*num_var, mat_A_gw, 2*num_var, ipiv, info)
    4069             : 
    4070     1083659 :          CALL ZGETRS('N', 2*num_var, 1, mat_A_gw, 2*num_var, ipiv, vec_b_gw, 2*num_var, info)
    4071             : 
    4072     1083659 :          CALL timestop(handle4)
    4073             : 
    4074     6501954 :          DO iii = 1, num_var
    4075     6501954 :             Lambda(iii) = Lambda_Re(iii) + gaussi*Lambda_Im(iii) + vec_b_gw(iii) + vec_b_gw(iii + num_var)
    4076             :          END DO
    4077             : 
    4078             :          ! calculate chi2
    4079             :          CALL calc_chi2(chi2, Lambda, vec_Sigma_c_gw, vec_omega_fit_gw_sign, num_poles, &
    4080     1083659 :                         num_fit_points, n_level_gw)
    4081             : 
    4082             :          ! if the fit is already super accurate, exit. otherwise maybe issues when dividing by 0
    4083     1083659 :          IF (chi2 < 1.0E-30_dp) EXIT
    4084             : 
    4085     1083595 :          IF (chi2 < chi2_old) THEN
    4086      920165 :             ScalParam = MAX(ScalParam/Ldown, 1E-12_dp)
    4087     5520990 :             DO iii = 1, num_var
    4088     4600825 :                Lambda_Re(iii) = Lambda_Re(iii) + REAL(vec_b_gw(iii) + vec_b_gw(iii + num_var))
    4089     5520990 :                Lambda_Im(iii) = Lambda_Im(iii) + AIMAG(vec_b_gw(iii) + vec_b_gw(iii + num_var))
    4090             :             END DO
    4091      920165 :             IF (chi2_old/chi2 - 1.0_dp < stop_crit) could_exit = .TRUE.
    4092      920165 :             chi2_old = chi2
    4093             :          ELSE
    4094      163430 :             ScalParam = ScalParam*Lup
    4095             :          END IF
    4096     1083595 :          IF (ScalParam > 100.0_dp .AND. could_exit) EXIT
    4097             : 
    4098     4335204 :          IF (ScalParam > 1E+10_dp) ScalParam = 1E-4_dp
    4099             : 
    4100             :       END DO
    4101             : 
    4102         568 :       IF (.NOT. do_gw_im_time) THEN
    4103             : 
    4104             :          ! change a_0 [Lambda(1)], so that Sigma(i0) = Fit(i0)
    4105             :          ! do not do this for imaginary time since we do not have many fit points and the fit should be perfect
    4106         420 :          func_val = Lambda(1)
    4107        1260 :          DO iii = 1, num_poles
    4108         840 :             jjj = iii*2
    4109             :             ! calculate value of the fit function
    4110        1260 :             func_val = func_val + Lambda(jjj)/(-Lambda(jjj + 1))
    4111             :          END DO
    4112             : 
    4113         420 :          Lambda_Re(1) = Lambda_Re(1) - REAL(func_val) + REAL(vec_Sigma_c_gw(n_level_gw, num_fit_points))
    4114         420 :          Lambda_Im(1) = Lambda_Im(1) - AIMAG(func_val) + AIMAG(vec_Sigma_c_gw(n_level_gw, num_fit_points))
    4115             : 
    4116             :       END IF
    4117             : 
    4118        3408 :       Lambda_without_offset(:) = Lambda(:)
    4119             : 
    4120        3408 :       DO iii = 1, num_var
    4121        3408 :          Lambda(iii) = CMPLX(Lambda_Re(iii), Lambda_Im(iii), KIND=dp)
    4122             :       END DO
    4123             : 
    4124         568 :       IF (do_gw_im_time) THEN
    4125             :          ! for cubic-scaling GW, we have one Green's function for occ and virt states with the Fermi level
    4126             :          ! in the middle of homo and lumo
    4127         148 :          e_fermi = 0.5_dp*(Eigenval(homo) + Eigenval(homo + 1))
    4128             :       ELSE
    4129             :          ! in case of O(N^4) GW, we have the Fermi level differently for occ and virt states, see
    4130             :          ! Fig. 1 in JCTC 12, 3623-3635 (2016)
    4131         420 :          IF (n_level_gw <= gw_corr_lev_occ) THEN
    4132         666 :             e_fermi = MAXVAL(Eigenval(homo - gw_corr_lev_occ + 1:homo)) + fermi_level_offset
    4133             :          ELSE
    4134        3738 :             e_fermi = MINVAL(Eigenval(homo + 1:homo + gw_corr_lev_vir)) - fermi_level_offset
    4135             :          END IF
    4136             :       END IF
    4137             : 
    4138             :       ! either Z-shot or Newton/bisection crossing search for evaluating Sigma_c
    4139         568 :       IF (crossing_search == ri_rpa_g0w0_crossing_z_shot .OR. &
    4140             :           crossing_search == ri_rpa_g0w0_crossing_newton) THEN
    4141             : 
    4142             :          ! calculate Sigma_c_fit(e_n) and Z
    4143         568 :          func_val = Lambda(1)
    4144         568 :          z_value(n_level_gw) = 1.0_dp
    4145        1704 :          DO iii = 1, num_poles
    4146        1136 :             jjj = iii*2
    4147             :             z_value(n_level_gw) = z_value(n_level_gw) + REAL(Lambda(jjj)/ &
    4148        1136 :                                                              (Eigenval(n_level_gw_ref) - e_fermi - Lambda(jjj + 1))**2)
    4149        1704 :             func_val = func_val + Lambda(jjj)/(Eigenval(n_level_gw_ref) - e_fermi - Lambda(jjj + 1))
    4150             :          END DO
    4151             :          ! m is the slope of the correl self-energy
    4152         568 :          m_value(n_level_gw) = 1.0_dp - z_value(n_level_gw)
    4153         568 :          z_value(n_level_gw) = 1.0_dp/z_value(n_level_gw)
    4154         568 :          gw_energ = REAL(func_val)
    4155         568 :          vec_gw_energ(n_level_gw) = gw_energ
    4156             : 
    4157             :          ! in case one wants to do Newton-Raphson on top of the Z-shot
    4158         568 :          IF (crossing_search == ri_rpa_g0w0_crossing_newton) THEN
    4159             : 
    4160             :             level_energ_GW = (Eigenval_scf(n_level_gw_ref) - &
    4161             :                               m_value(n_level_gw)*Eigenval(n_level_gw_ref) + &
    4162             :                               vec_gw_energ(n_level_gw) + &
    4163             :                               vec_Sigma_x_minus_vxc_gw(n_level_gw_ref))* &
    4164          32 :                              z_value(n_level_gw)
    4165             : 
    4166             :             ! Newton-Raphson iteration
    4167         240 :             DO kkk = 1, 1000
    4168             : 
    4169             :                ! calculate the value of the fit function for level_energ_GW
    4170         240 :                func_val = Lambda(1)
    4171         240 :                z_value(n_level_gw) = 1.0_dp
    4172         720 :                DO iii = 1, num_poles
    4173         480 :                   jjj = iii*2
    4174         720 :                   func_val = func_val + Lambda(jjj)/(level_energ_GW - e_fermi - Lambda(jjj + 1))
    4175             :                END DO
    4176             : 
    4177             :                ! calculate the derivative of the fit function for level_energ_GW
    4178         240 :                deriv_val_real = -1.0_dp
    4179         720 :                DO iii = 1, num_poles
    4180         480 :                   jjj = iii*2
    4181             :                   deriv_val_real = deriv_val_real + REAL(Lambda(jjj))/((ABS(level_energ_GW - e_fermi - Lambda(jjj + 1)))**2) &
    4182             :                                    - (REAL(Lambda(jjj))*(level_energ_GW - e_fermi) - REAL(Lambda(jjj)*CONJG(Lambda(jjj + 1))))* &
    4183             :                                    2.0_dp*(level_energ_GW - e_fermi - REAL(Lambda(jjj + 1)))/ &
    4184         720 :                                    ((ABS(level_energ_GW - e_fermi - Lambda(jjj + 1)))**2)
    4185             : 
    4186             :                END DO
    4187             : 
    4188             :               delta = (Eigenval_scf(n_level_gw_ref) + vec_Sigma_x_minus_vxc_gw(n_level_gw_ref) + REAL(func_val) - level_energ_GW)/ &
    4189         240 :                        deriv_val_real
    4190             : 
    4191         240 :                level_energ_GW = level_energ_GW - delta
    4192             : 
    4193         240 :                IF (ABS(delta) < 1.0E-08) EXIT
    4194             : 
    4195             :             END DO
    4196             : 
    4197             :             ! update the GW-energy by Newton-Raphson and set the Z-value to 1
    4198             : 
    4199          32 :             vec_gw_energ(n_level_gw) = REAL(func_val)
    4200          32 :             z_value(n_level_gw) = 1.0_dp
    4201          32 :             m_value(n_level_gw) = 0.0_dp
    4202             : 
    4203             :          END IF ! Newton-Raphson on top of Z-shot
    4204             : 
    4205             :       ELSE
    4206           0 :          CPABORT("Only NONE, ZSHOT and NEWTON implemented for 2-pole model")
    4207             :       END IF ! decision crossing search none, Z-shot
    4208             : 
    4209             :       !   --------------------------------------------
    4210             :       !  | calculate statistical error due to fitting |
    4211             :       !   --------------------------------------------
    4212             : 
    4213             :       ! estimate the statistical error of the calculated Sigma_c(i*omega)
    4214             :       ! by sqrt(chi2/n), where n is the number of fit points
    4215             : 
    4216             :       CALL calc_chi2(chi2, Lambda_without_offset, vec_Sigma_c_gw, vec_omega_fit_gw_sign, num_poles, &
    4217         568 :                      num_fit_points, n_level_gw)
    4218             : 
    4219             :       ! Estimate the statistical error of every fit point
    4220         568 :       stat_error = SQRT(chi2/num_fit_points)
    4221             : 
    4222             :       ! allocate N array containing the second derivatives of chi^2
    4223        1704 :       ALLOCATE (vec_N_gw(num_var*2))
    4224        6248 :       vec_N_gw = 0.0_dp
    4225             : 
    4226        2272 :       ALLOCATE (mat_N_gw(num_var*2, num_var*2))
    4227       63048 :       mat_N_gw = 0.0_dp
    4228             : 
    4229        6248 :       DO iii = 1, num_var*2
    4230             :          CALL calc_mat_N(vec_N_gw(iii), Lambda_without_offset, vec_Sigma_c_gw, vec_omega_fit_gw_sign, &
    4231        6248 :                          iii, iii, num_poles, num_fit_points, n_level_gw, 0.001_dp)
    4232             :       END DO
    4233             : 
    4234        6248 :       DO iii = 1, num_var*2
    4235       63048 :          DO jjj = 1, num_var*2
    4236             :             CALL calc_mat_N(mat_N_gw(iii, jjj), Lambda_without_offset, vec_Sigma_c_gw, vec_omega_fit_gw_sign, &
    4237       62480 :                             iii, jjj, num_poles, num_fit_points, n_level_gw, 0.001_dp)
    4238             :          END DO
    4239             :       END DO
    4240             : 
    4241         568 :       CALL DGETRF(2*num_var, 2*num_var, mat_N_gw, 2*num_var, ipiv, info)
    4242             : 
    4243             :       ! vec_b_gw is only working array
    4244         568 :       CALL DGETRI(2*num_var, mat_N_gw, 2*num_var, ipiv, vec_b_gw, 2*num_var, info)
    4245             : 
    4246        1136 :       ALLOCATE (stat_errors(2*num_var))
    4247        6248 :       stat_errors = 0.0_dp
    4248             : 
    4249        6248 :       DO iii = 1, 2*num_var
    4250        6248 :          stat_errors(iii) = SQRT(ABS(mat_N_gw(iii, iii)))*stat_error
    4251             :       END DO
    4252             : 
    4253         568 :       DEALLOCATE (mat_N_gw)
    4254         568 :       DEALLOCATE (vec_N_gw)
    4255         568 :       DEALLOCATE (mat_A_gw)
    4256         568 :       DEALLOCATE (mat_B_gw)
    4257         568 :       DEALLOCATE (stat_errors)
    4258         568 :       DEALLOCATE (dLambda)
    4259         568 :       DEALLOCATE (dLambda_2)
    4260         568 :       DEALLOCATE (vec_b_gw)
    4261         568 :       DEALLOCATE (vec_b_gw_copy)
    4262         568 :       DEALLOCATE (ipiv)
    4263         568 :       DEALLOCATE (vec_omega_fit_gw_sign)
    4264         568 :       DEALLOCATE (Lambda)
    4265         568 :       DEALLOCATE (Lambda_without_offset)
    4266         568 :       DEALLOCATE (Lambda_Re)
    4267         568 :       DEALLOCATE (Lambda_Im)
    4268             : 
    4269         568 :    END SUBROUTINE fit_and_continuation_2pole
    4270             : 
    4271             : ! **************************************************************************************************
    4272             : !> \brief perform analytic continuation with pade approximation
    4273             : !> \param vec_gw_energ real Sigma_c
    4274             : !> \param vec_omega_fit_gw frequency points for Sigma_c(iomega)
    4275             : !> \param z_value 1/(1-dev)
    4276             : !> \param m_value derivative of real Sigma_c
    4277             : !> \param vec_Sigma_c_gw complex Sigma_c(iomega)
    4278             : !> \param vec_Sigma_x_minus_vxc_gw ...
    4279             : !> \param Eigenval quasiparticle energy during ev self-consistent GW
    4280             : !> \param Eigenval_scf KS/HF eigenvalue
    4281             : !> \param do_hedin_shift ...
    4282             : !> \param n_level_gw ...
    4283             : !> \param gw_corr_lev_occ ...
    4284             : !> \param gw_corr_lev_vir ...
    4285             : !> \param nparam_pade number of pade parameters
    4286             : !> \param num_fit_points number of fit points for Sigma_c(iomega)
    4287             : !> \param crossing_search type ofr cross search to find quasiparticle energies
    4288             : !> \param homo ...
    4289             : !> \param fermi_level_offset ...
    4290             : !> \param do_gw_im_time ...
    4291             : !> \param print_self_energy ...
    4292             : !> \param count_ev_sc_GW ...
    4293             : !> \param vec_gw_dos ...
    4294             : !> \param dos_lower_bound ...
    4295             : !> \param dos_precision ...
    4296             : !> \param ndos ...
    4297             : !> \param min_level_self_energy ...
    4298             : !> \param max_level_self_energy ...
    4299             : !> \param dos_eta ...
    4300             : !> \param dos_min ...
    4301             : !> \param dos_max ...
    4302             : !> \param e_fermi_ext ...
    4303             : ! **************************************************************************************************
    4304        3228 :    SUBROUTINE continuation_pade(vec_gw_energ, vec_omega_fit_gw, &
    4305        6456 :                                 z_value, m_value, vec_Sigma_c_gw, vec_Sigma_x_minus_vxc_gw, &
    4306        6456 :                                 Eigenval, Eigenval_scf, do_hedin_shift, n_level_gw, &
    4307             :                                 gw_corr_lev_occ, gw_corr_lev_vir, &
    4308             :                                 nparam_pade, num_fit_points, crossing_search, homo, &
    4309             :                                 fermi_level_offset, do_gw_im_time, print_self_energy, count_ev_sc_GW, &
    4310             :                                 vec_gw_dos, dos_lower_bound, dos_precision, ndos, &
    4311             :                                 min_level_self_energy, max_level_self_energy, &
    4312             :                                 dos_eta, dos_min, dos_max, e_fermi_ext)
    4313             : 
    4314             :       ! Optional arguments for spectral function
    4315             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: vec_gw_energ
    4316             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: vec_omega_fit_gw
    4317             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: z_value, m_value
    4318             :       COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(IN)      :: vec_Sigma_c_gw
    4319             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: vec_Sigma_x_minus_vxc_gw, Eigenval, &
    4320             :                                                             Eigenval_scf
    4321             :       LOGICAL, INTENT(IN)                                :: do_hedin_shift
    4322             :       INTEGER, INTENT(IN)                                :: n_level_gw, gw_corr_lev_occ, &
    4323             :                                                             gw_corr_lev_vir, nparam_pade, &
    4324             :                                                             num_fit_points, crossing_search, homo
    4325             :       REAL(KIND=dp), INTENT(IN)                          :: fermi_level_offset
    4326             :       LOGICAL, INTENT(IN)                                :: do_gw_im_time, print_self_energy
    4327             :       INTEGER, INTENT(IN)                                :: count_ev_sc_GW
    4328             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), OPTIONAL :: vec_gw_dos
    4329             :       REAL(KIND=dp), OPTIONAL                            :: dos_lower_bound, dos_precision
    4330             :       INTEGER, INTENT(IN), OPTIONAL                      :: ndos, min_level_self_energy, &
    4331             :                                                             max_level_self_energy
    4332             :       REAL(KIND=dp), OPTIONAL                            :: dos_eta
    4333             :       INTEGER, INTENT(IN), OPTIONAL                      :: dos_min, dos_max
    4334             :       REAL(KIND=dp), OPTIONAL                            :: e_fermi_ext
    4335             : 
    4336             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'continuation_pade'
    4337             : 
    4338             :       CHARACTER(LEN=5)                                   :: string_level
    4339             :       CHARACTER(len=default_path_length)                 :: filename
    4340             :       COMPLEX(KIND=dp)                                   :: sigma_c_pade, sigma_c_pade_im_freq
    4341        3228 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:)        :: coeff_pade, omega_points_pade, &
    4342        3228 :                                                             Sigma_c_gw_reorder
    4343             :       INTEGER                                            :: handle, i_omega, idos, iunit, jquad, &
    4344             :                                                             n_level_gw_ref, num_omega
    4345             :       REAL(KIND=dp)                                      :: e_fermi, energy_val, hedin_shift, &
    4346             :                                                             level_energ_GW_start, omega, &
    4347             :                                                             omega_dos, omega_dos_pade_eval, &
    4348             :                                                             sign_occ_virt
    4349        3228 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: vec_omega_fit_gw_sign, &
    4350        3228 :                                                             vec_omega_fit_gw_sign_reorder, &
    4351        3228 :                                                             vec_sigma_imag, vec_sigma_real
    4352             :       TYPE(cp_logger_type), POINTER                      :: logger
    4353             : 
    4354        3228 :       CALL timeset(routineN, handle)
    4355             : 
    4356        9684 :       ALLOCATE (vec_omega_fit_gw_sign(num_fit_points))
    4357             : 
    4358        3228 :       IF (n_level_gw <= gw_corr_lev_occ) THEN
    4359             :          sign_occ_virt = -1.0_dp
    4360             :       ELSE
    4361        2168 :          sign_occ_virt = 1.0_dp
    4362             :       END IF
    4363             : 
    4364      111160 :       DO jquad = 1, num_fit_points
    4365      111160 :          vec_omega_fit_gw_sign(jquad) = ABS(vec_omega_fit_gw(jquad))*sign_occ_virt
    4366             :       END DO
    4367             : 
    4368        3228 :       IF (do_gw_im_time) THEN
    4369             :          ! for cubic-scaling GW, we have one Green's function for occ and virt states
    4370             :          ! with the Fermi level in the middle of homo and lumo
    4371        1836 :          e_fermi = 0.5_dp*(Eigenval(homo) + Eigenval(homo + 1))
    4372             :       ELSE
    4373             :          ! in case of O(N^4) GW, we have the Fermi level differently for occ and virt states, see
    4374             :          ! Fig. 1 in JCTC 12, 3623-3635 (2016)
    4375        1392 :          IF (n_level_gw <= gw_corr_lev_occ) THEN
    4376        2136 :             e_fermi = MAXVAL(Eigenval(homo - gw_corr_lev_occ + 1:homo)) + fermi_level_offset
    4377             :          ELSE
    4378       14184 :             e_fermi = MINVAL(Eigenval(homo + 1:homo + gw_corr_lev_vir)) - fermi_level_offset
    4379             :          END IF
    4380             :       END IF
    4381             : 
    4382        3228 :       IF (PRESENT(e_fermi_ext)) e_fermi = e_fermi_ext
    4383             : 
    4384        3228 :       n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
    4385             : 
    4386             :       !*** reorder, such that omega=i*0 is first entry
    4387        9684 :       ALLOCATE (Sigma_c_gw_reorder(num_fit_points))
    4388        6456 :       ALLOCATE (vec_omega_fit_gw_sign_reorder(num_fit_points))
    4389             :       ! for cubic scaling GW fit points are ordered differently than in N^4 GW
    4390        3228 :       IF (do_gw_im_time) THEN
    4391        9640 :          DO jquad = 1, num_fit_points
    4392        7804 :             Sigma_c_gw_reorder(jquad) = vec_Sigma_c_gw(n_level_gw, jquad)
    4393        9640 :             vec_omega_fit_gw_sign_reorder(jquad) = vec_omega_fit_gw_sign(jquad)
    4394             :          END DO
    4395             :       ELSE
    4396      101520 :          DO jquad = 1, num_fit_points
    4397      100128 :             Sigma_c_gw_reorder(jquad) = vec_Sigma_c_gw(n_level_gw, num_fit_points - jquad + 1)
    4398      101520 :             vec_omega_fit_gw_sign_reorder(jquad) = vec_omega_fit_gw_sign(num_fit_points - jquad + 1)
    4399             :          END DO
    4400             :       END IF
    4401             : 
    4402             :       !*** evaluate parameters for pade approximation
    4403        9684 :       ALLOCATE (coeff_pade(nparam_pade))
    4404        6456 :       ALLOCATE (omega_points_pade(nparam_pade))
    4405       31680 :       coeff_pade = 0.0_dp
    4406             :       CALL get_pade_parameters(Sigma_c_gw_reorder, vec_omega_fit_gw_sign_reorder, &
    4407        3228 :                                num_fit_points, nparam_pade, omega_points_pade, coeff_pade)
    4408             : 
    4409             :       !*** calculate start_value for iterative cross-searching methods
    4410        3228 :       IF ((crossing_search == ri_rpa_g0w0_crossing_bisection) .OR. &
    4411             :           (crossing_search == ri_rpa_g0w0_crossing_newton)) THEN
    4412        3228 :          energy_val = Eigenval(n_level_gw_ref) - e_fermi
    4413             :          CALL evaluate_pade_function(energy_val, nparam_pade, omega_points_pade, &
    4414        3228 :                                      coeff_pade, sigma_c_pade)
    4415             :          CALL get_z_and_m_value_pade(energy_val, nparam_pade, omega_points_pade, &
    4416        3228 :                                      coeff_pade, z_value(n_level_gw), m_value(n_level_gw))
    4417             :          level_energ_GW_start = (Eigenval_scf(n_level_gw_ref) - &
    4418             :                                  m_value(n_level_gw)*Eigenval(n_level_gw_ref) + &
    4419             :                                  REAL(sigma_c_pade) + &
    4420             :                                  vec_Sigma_x_minus_vxc_gw(n_level_gw_ref))* &
    4421        3228 :                                 z_value(n_level_gw)
    4422             : 
    4423             :          ! calculate Hedin shift; the last line is for evGW0 and evGW
    4424        3228 :          hedin_shift = 0.0_dp
    4425        3228 :          IF (do_hedin_shift) hedin_shift = REAL(sigma_c_pade) + &
    4426             :                                            vec_Sigma_x_minus_vxc_gw(n_level_gw_ref) &
    4427          60 :                                            - Eigenval(n_level_gw_ref) + Eigenval_scf(n_level_gw_ref)
    4428             :       END IF
    4429             : 
    4430        3228 :       IF (PRESENT(min_level_self_energy) .AND. PRESENT(max_level_self_energy)) THEN
    4431        1668 :          IF (n_level_gw_ref >= min_level_self_energy .AND. &
    4432             :              n_level_gw_ref <= max_level_self_energy) THEN
    4433           0 :             ALLOCATE (vec_sigma_real(ndos))
    4434           0 :             ALLOCATE (vec_sigma_imag(ndos))
    4435           0 :             WRITE (string_level, "(I4)") n_level_gw_ref
    4436           0 :             string_level = ADJUSTL(string_level)
    4437             :          END IF
    4438             :       END IF
    4439             : 
    4440             :       !*** Calculate spectral function
    4441             :       !***         1   \‾‾                    |Im 𝚺ₘ(ω)|+η
    4442             :       !*** A(ω) = ---   |    ---------------------------------------------------
    4443             :       !***         π   /__   [ω - eₘ^DFT - (Re 𝚺ₘ(ω) - vₘ^xc)]² + (|Im 𝚺ₘ(ω)|+η)²
    4444             : 
    4445        3228 :       IF (PRESENT(ndos)) THEN
    4446        1668 :       IF (ndos /= 0) THEN
    4447             :          ! Hedin shift not implemented
    4448           0 :          CPASSERT(.NOT. do_hedin_shift)
    4449           0 :          logger => cp_get_default_logger()
    4450           0 :          IF (logger%para_env%is_source()) THEN
    4451           0 :             iunit = cp_logger_get_default_unit_nr()
    4452             :          ELSE
    4453           0 :             iunit = -1
    4454             :          END IF
    4455           0 :          DO idos = 1, ndos
    4456           0 :             omega_dos = dos_lower_bound + REAL(idos - 1, KIND=dp)*dos_precision
    4457           0 :             omega_dos_pade_eval = omega_dos - e_fermi
    4458             :             CALL evaluate_pade_function(omega_dos_pade_eval, nparam_pade, omega_points_pade, &
    4459           0 :                                         coeff_pade, sigma_c_pade)
    4460             : 
    4461             :             IF (n_level_gw_ref >= min_level_self_energy .AND. &
    4462           0 :                 n_level_gw_ref <= max_level_self_energy .AND. iunit > 0) THEN
    4463             : 
    4464           0 :                vec_sigma_real(idos) = (REAL(sigma_c_pade))
    4465           0 :                vec_sigma_imag(idos) = (AIMAG(sigma_c_pade))
    4466             : 
    4467             :             END IF
    4468             : 
    4469           0 :             IF (n_level_gw_ref >= dos_min .AND. &
    4470           0 :                 (n_level_gw_ref <= dos_max .OR. dos_max == 0)) THEN
    4471             :                vec_gw_dos(idos) = vec_gw_dos(idos) + &
    4472             :                                   (ABS(AIMAG(sigma_c_pade)) + dos_eta) &
    4473             :                                   /( &
    4474             :                                   (omega_dos - Eigenval_scf(n_level_gw_ref) - &
    4475             :                                    (REAL(sigma_c_pade) + vec_Sigma_x_minus_vxc_gw(n_level_gw_ref)) &
    4476             :                                    )**2 &
    4477             :                                   + (ABS(AIMAG(sigma_c_pade)) + dos_eta)**2 &
    4478           0 :                                   )
    4479             :             END IF
    4480             : 
    4481             :          END DO
    4482             :       END IF
    4483             :       END IF
    4484             : 
    4485        3228 :       IF (PRESENT(min_level_self_energy) .AND. PRESENT(max_level_self_energy)) THEN
    4486        1668 :          logger => cp_get_default_logger()
    4487        1668 :          IF (logger%para_env%is_source()) THEN
    4488        1644 :             iunit = cp_logger_get_default_unit_nr()
    4489             :          ELSE
    4490          24 :             iunit = -1
    4491             :          END IF
    4492             :          IF (n_level_gw_ref >= min_level_self_energy .AND. &
    4493        1668 :              n_level_gw_ref <= max_level_self_energy .AND. iunit > 0) THEN
    4494             : 
    4495             :             CALL open_file('self_energy_re_'//TRIM(string_level)//'.dat', unit_number=iunit, &
    4496           0 :                            file_status="UNKNOWN", file_action="WRITE")
    4497           0 :             DO idos = 1, ndos
    4498           0 :                omega_dos = dos_lower_bound + REAL(idos - 1, KIND=dp)*dos_precision
    4499           0 :                WRITE (iunit, '(F17.10, F17.10)') omega_dos*evolt, vec_sigma_real(idos)*evolt
    4500             :             END DO
    4501             : 
    4502           0 :             CALL close_file(iunit)
    4503             : 
    4504             :             CALL open_file('self_energy_im_'//TRIM(string_level)//'.dat', unit_number=iunit, &
    4505           0 :                            file_status="UNKNOWN", file_action="WRITE")
    4506           0 :             DO idos = 1, ndos
    4507           0 :                omega_dos = dos_lower_bound + REAL(idos - 1, KIND=dp)*dos_precision
    4508           0 :                WRITE (iunit, '(F17.10, F17.10)') omega_dos*evolt, vec_sigma_imag(idos)*evolt
    4509             :             END DO
    4510             : 
    4511           0 :             CALL close_file(iunit)
    4512             : 
    4513           0 :             DEALLOCATE (vec_sigma_real)
    4514           0 :             DEALLOCATE (vec_sigma_imag)
    4515             :          END IF
    4516             :       END IF
    4517             : 
    4518             :       !*** perform crossing search
    4519           0 :       SELECT CASE (crossing_search)
    4520             :       CASE (ri_rpa_g0w0_crossing_z_shot)
    4521             :          ! Hedin shift not implemented
    4522           0 :          CPASSERT(.NOT. do_hedin_shift)
    4523           0 :          energy_val = Eigenval(n_level_gw_ref) - e_fermi
    4524             :          CALL evaluate_pade_function(energy_val, nparam_pade, omega_points_pade, &
    4525           0 :                                      coeff_pade, sigma_c_pade)
    4526           0 :          vec_gw_energ(n_level_gw) = REAL(sigma_c_pade)
    4527             : 
    4528             :          CALL get_z_and_m_value_pade(energy_val, nparam_pade, omega_points_pade, &
    4529           0 :                                      coeff_pade, z_value(n_level_gw), m_value(n_level_gw))
    4530             : 
    4531             :       CASE (ri_rpa_g0w0_crossing_bisection)
    4532             :          CALL get_sigma_c_bisection_pade(vec_gw_energ(n_level_gw), Eigenval_scf(n_level_gw_ref), &
    4533             :                                          vec_Sigma_x_minus_vxc_gw(n_level_gw_ref), e_fermi, &
    4534             :                                          nparam_pade, omega_points_pade, coeff_pade, &
    4535           8 :                                          level_energ_GW_start, hedin_shift)
    4536           8 :          z_value(n_level_gw) = 1.0_dp
    4537           8 :          m_value(n_level_gw) = 0.0_dp
    4538             : 
    4539             :       CASE (ri_rpa_g0w0_crossing_newton)
    4540             :          CALL get_sigma_c_newton_pade(vec_gw_energ(n_level_gw), Eigenval_scf(n_level_gw_ref), &
    4541             :                                       vec_Sigma_x_minus_vxc_gw(n_level_gw_ref), e_fermi, &
    4542             :                                       nparam_pade, omega_points_pade, coeff_pade, &
    4543        3220 :                                       level_energ_GW_start, hedin_shift)
    4544        3220 :          z_value(n_level_gw) = 1.0_dp
    4545        3220 :          m_value(n_level_gw) = 0.0_dp
    4546             : 
    4547             :       CASE DEFAULT
    4548        3228 :          CPABORT("Only Z_SHOT, NEWTON, and BISECTION crossing search implemented.")
    4549             :       END SELECT
    4550             : 
    4551        3228 :       IF (print_self_energy) THEN
    4552             : 
    4553           0 :          IF (count_ev_sc_GW == 1) THEN
    4554             : 
    4555           0 :             IF (n_level_gw_ref < 10) THEN
    4556           0 :                WRITE (filename, "(A26,I1)") "G0W0_self_energy_level_000", n_level_gw_ref
    4557           0 :             ELSE IF (n_level_gw_ref < 100) THEN
    4558           0 :                WRITE (filename, "(A25,I2)") "G0W0_self_energy_level_00", n_level_gw_ref
    4559           0 :             ELSE IF (n_level_gw_ref < 1000) THEN
    4560           0 :                WRITE (filename, "(A24,I3)") "G0W0_self_energy_level_0", n_level_gw_ref
    4561             :             ELSE
    4562           0 :                WRITE (filename, "(A23,I4)") "G0W0_self_energy_level_", n_level_gw_ref
    4563             :             END IF
    4564             : 
    4565             :          ELSE
    4566             : 
    4567           0 :             IF (n_level_gw_ref < 10) THEN
    4568           0 :                WRITE (filename, "(A11,I1,A22,I1)") "evGW_cycle_", count_ev_sc_GW, &
    4569           0 :                   "_self_energy_level_000", n_level_gw_ref
    4570           0 :             ELSE IF (n_level_gw_ref < 100) THEN
    4571           0 :                WRITE (filename, "(A11,I1,A21,I2)") "evGW_cycle_", count_ev_sc_GW, &
    4572           0 :                   "_self_energy_level_00", n_level_gw_ref
    4573           0 :             ELSE IF (n_level_gw_ref < 1000) THEN
    4574           0 :                WRITE (filename, "(A11,I1,A20,I3)") "evGW_cycle_", count_ev_sc_GW, &
    4575           0 :                   "_self_energy_level_0", n_level_gw_ref
    4576             :             ELSE
    4577           0 :                WRITE (filename, "(A11,I1,A19,I4)") "evGW_cycle_", count_ev_sc_GW, &
    4578           0 :                   "_self_energy_level_", n_level_gw_ref
    4579             :             END IF
    4580             : 
    4581             :          END IF
    4582             : 
    4583           0 :          logger => cp_get_default_logger()
    4584           0 :          IF (logger%para_env%is_source()) THEN
    4585           0 :             iunit = cp_logger_get_default_unit_nr()
    4586             :          ELSE
    4587           0 :             iunit = -1
    4588             :          END IF
    4589           0 :          CALL open_file(TRIM(filename), unit_number=iunit, file_status="UNKNOWN", file_action="WRITE")
    4590             : 
    4591           0 :          num_omega = 10000
    4592             : 
    4593           0 :          WRITE (iunit, "(2A42)") " omega (eV)     Sigma(omega) (eV)  ", &
    4594           0 :             "  omega - e_n^DFT - Sigma_n^x - v_n^xc (eV)"
    4595             : 
    4596           0 :          DO i_omega = 0, num_omega
    4597             : 
    4598           0 :             omega = -50.0_dp/evolt + REAL(i_omega, KIND=dp)/REAL(num_omega, KIND=dp)*100.0_dp/evolt
    4599             : 
    4600             :             CALL evaluate_pade_function(omega - e_fermi, nparam_pade, omega_points_pade, &
    4601           0 :                                         coeff_pade, sigma_c_pade)
    4602             : 
    4603           0 :             WRITE (iunit, "(F12.2,2F17.5)") omega*evolt, REAL(sigma_c_pade)*evolt, &
    4604           0 :                (omega - Eigenval_scf(n_level_gw_ref) - vec_Sigma_x_minus_vxc_gw(n_level_gw_ref))*evolt
    4605             : 
    4606             :          END DO
    4607             : 
    4608           0 :          WRITE (iunit, "(A51,A39)") " w (eV)  Re(Sigma(i*w)) (eV)   Im(Sigma(i*w)) (eV) ", &
    4609           0 :             "  Re(Fit(i*w)) (eV)    Im(Fit(iw)) (eV)"
    4610             : 
    4611           0 :          DO jquad = 1, num_fit_points
    4612             : 
    4613             :             CALL evaluate_pade_function(vec_omega_fit_gw_sign_reorder(jquad), &
    4614             :                                         nparam_pade, omega_points_pade, &
    4615           0 :                                         coeff_pade, sigma_c_pade_im_freq, do_imag_freq=.TRUE.)
    4616             : 
    4617           0 :             WRITE (iunit, "(F12.2,4F17.5)") vec_omega_fit_gw_sign_reorder(jquad)*evolt, &
    4618           0 :                REAL(Sigma_c_gw_reorder(jquad)*evolt), &
    4619           0 :                AIMAG(Sigma_c_gw_reorder(jquad)*evolt), &
    4620           0 :                REAL(sigma_c_pade_im_freq*evolt), &
    4621           0 :                AIMAG(sigma_c_pade_im_freq*evolt)
    4622             : 
    4623             :          END DO
    4624             : 
    4625           0 :          CALL close_file(iunit)
    4626             : 
    4627             :       END IF
    4628             : 
    4629        3228 :       DEALLOCATE (vec_omega_fit_gw_sign)
    4630        3228 :       DEALLOCATE (Sigma_c_gw_reorder)
    4631        3228 :       DEALLOCATE (vec_omega_fit_gw_sign_reorder)
    4632        3228 :       DEALLOCATE (coeff_pade, omega_points_pade)
    4633             : 
    4634        3228 :       CALL timestop(handle)
    4635             : 
    4636        6456 :    END SUBROUTINE continuation_pade
    4637             : 
    4638             : ! **************************************************************************************************
    4639             : !> \brief calculate pade parameter recursively as in  Eq. (A2) in J. Low Temp. Phys., Vol. 29,
    4640             : !>          1977, pp. 179
    4641             : !> \param y f(x), here: Sigma_c(iomega)
    4642             : !> \param x the frequency points omega
    4643             : !> \param num_fit_points ...
    4644             : !> \param nparam number of pade parameters
    4645             : !> \param xpoints set of points used in pade approximation, selection of x
    4646             : !> \param coeff pade coefficients
    4647             : ! **************************************************************************************************
    4648        3228 :    PURE SUBROUTINE get_pade_parameters(y, x, num_fit_points, nparam, xpoints, coeff)
    4649             : 
    4650             :       COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN)         :: y
    4651             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: x
    4652             :       INTEGER, INTENT(IN)                                :: num_fit_points, nparam
    4653             :       COMPLEX(KIND=dp), DIMENSION(:), INTENT(INOUT)      :: xpoints, coeff
    4654             : 
    4655        3228 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:)        :: ypoints
    4656        3228 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :)     :: g_mat
    4657             :       INTEGER                                            :: idat, iparam, nstep
    4658             : 
    4659        3228 :       nstep = INT(num_fit_points/(nparam - 1))
    4660             : 
    4661        9684 :       ALLOCATE (ypoints(nparam))
    4662             :       !omega=i0 is in element x(1)
    4663        3228 :       idat = 1
    4664       28452 :       DO iparam = 1, nparam - 1
    4665       25224 :          xpoints(iparam) = gaussi*x(idat)
    4666       25224 :          ypoints(iparam) = y(idat)
    4667       28452 :          idat = idat + nstep
    4668             :       END DO
    4669        3228 :       xpoints(nparam) = gaussi*x(num_fit_points)
    4670        3228 :       ypoints(nparam) = y(num_fit_points)
    4671             : 
    4672             :       !*** generate parameters recursively
    4673             : 
    4674       12912 :       ALLOCATE (g_mat(nparam, nparam))
    4675       31680 :       g_mat(:, 1) = ypoints(:)
    4676       28452 :       DO iparam = 2, nparam
    4677      193534 :          DO idat = iparam, nparam
    4678             :             g_mat(idat, iparam) = (g_mat(iparam - 1, iparam - 1) - g_mat(idat, iparam - 1))/ &
    4679      190306 :                                   ((xpoints(idat) - xpoints(iparam - 1))*g_mat(idat, iparam - 1))
    4680             :          END DO
    4681             :       END DO
    4682             : 
    4683       31680 :       DO iparam = 1, nparam
    4684       31680 :          coeff(iparam) = g_mat(iparam, iparam)
    4685             :       END DO
    4686             : 
    4687        3228 :       DEALLOCATE (ypoints)
    4688        3228 :       DEALLOCATE (g_mat)
    4689             : 
    4690        3228 :    END SUBROUTINE get_pade_parameters
    4691             : 
    4692             : ! **************************************************************************************************
    4693             : !> \brief evaluate pade function for a real value x_val
    4694             : !> \param x_val real value
    4695             : !> \param nparam number of pade parameters
    4696             : !> \param xpoints selection of points of the original complex function, i.e. here of Sigma_c(iomega)
    4697             : !> \param coeff pade coefficients
    4698             : !> \param func_val function value
    4699             : !> \param do_imag_freq ...
    4700             : ! **************************************************************************************************
    4701       12689 :    PURE SUBROUTINE evaluate_pade_function(x_val, nparam, xpoints, coeff, func_val, do_imag_freq)
    4702             : 
    4703             :       REAL(KIND=dp), INTENT(IN)                          :: x_val
    4704             :       INTEGER, INTENT(IN)                                :: nparam
    4705             :       COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN)         :: xpoints, coeff
    4706             :       COMPLEX(KIND=dp), INTENT(OUT)                      :: func_val
    4707             :       LOGICAL, INTENT(IN), OPTIONAL                      :: do_imag_freq
    4708             : 
    4709             :       INTEGER                                            :: iparam
    4710             :       LOGICAL                                            :: my_do_imag_freq
    4711             : 
    4712       12689 :       my_do_imag_freq = .FALSE.
    4713       12689 :       IF (PRESENT(do_imag_freq)) my_do_imag_freq = do_imag_freq
    4714             : 
    4715       12689 :       func_val = z_one
    4716       95285 :       DO iparam = nparam, 2, -1
    4717       95285 :          IF (my_do_imag_freq) THEN
    4718           0 :             func_val = z_one + coeff(iparam)*(gaussi*x_val - xpoints(iparam - 1))/func_val
    4719             :          ELSE
    4720       82596 :             func_val = z_one + coeff(iparam)*(x_val*z_one - xpoints(iparam - 1))/func_val
    4721             :          END IF
    4722             :       END DO
    4723             : 
    4724       12689 :       func_val = coeff(1)/func_val
    4725             : 
    4726       12689 :    END SUBROUTINE evaluate_pade_function
    4727             : 
    4728             : ! **************************************************************************************************
    4729             : !> \brief get the z-value and the m-value (derivative) of the pade function
    4730             : !> \param x_val real value
    4731             : !> \param nparam number of pade parameters
    4732             : !> \param xpoints selection of points of the original complex function, i.e. here of Sigma_c(iomega)
    4733             : !> \param coeff pade coefficients
    4734             : !> \param z_value 1/(1-dev)
    4735             : !> \param m_value derivative
    4736             : ! **************************************************************************************************
    4737       12581 :    PURE SUBROUTINE get_z_and_m_value_pade(x_val, nparam, xpoints, coeff, z_value, m_value)
    4738             : 
    4739             :       REAL(KIND=dp), INTENT(IN)                          :: x_val
    4740             :       INTEGER, INTENT(IN)                                :: nparam
    4741             :       COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN)         :: xpoints, coeff
    4742             :       REAL(KIND=dp), INTENT(OUT), OPTIONAL               :: z_value, m_value
    4743             : 
    4744             :       COMPLEX(KIND=dp)                                   :: denominator, dev_denominator, &
    4745             :                                                             dev_numerator, dev_val, func_val, &
    4746             :                                                             numerator
    4747             :       INTEGER                                            :: iparam
    4748             : 
    4749       12581 :       func_val = z_one
    4750       12581 :       dev_val = z_zero
    4751       95069 :       DO iparam = nparam, 2, -1
    4752       82488 :          numerator = coeff(iparam)*(x_val*z_one - xpoints(iparam - 1))
    4753       82488 :          dev_numerator = coeff(iparam)*z_one
    4754       82488 :          denominator = func_val
    4755       82488 :          dev_denominator = dev_val
    4756       82488 :          dev_val = dev_numerator/denominator - (numerator*dev_denominator)/(denominator**2)
    4757       95069 :          func_val = z_one + coeff(iparam)*(x_val*z_one - xpoints(iparam - 1))/func_val
    4758             :       END DO
    4759             : 
    4760       12581 :       dev_val = -1.0_dp*coeff(1)/(func_val**2)*dev_val
    4761       12581 :       func_val = coeff(1)/func_val
    4762             : 
    4763       12581 :       IF (PRESENT(z_value)) THEN
    4764        3228 :          z_value = 1.0_dp - REAL(dev_val)
    4765        3228 :          z_value = 1.0_dp/z_value
    4766             :       END IF
    4767       12581 :       IF (PRESENT(m_value)) m_value = REAL(dev_val)
    4768             : 
    4769       12581 :    END SUBROUTINE get_z_and_m_value_pade
    4770             : 
    4771             : ! **************************************************************************************************
    4772             : !> \brief crossing search using the bisection method to find the quasiparticle energy
    4773             : !> \param gw_energ real Sigma_c
    4774             : !> \param Eigenval_scf Eigenvalue from the SCF
    4775             : !> \param Sigma_x_minus_vxc_gw ...
    4776             : !> \param e_fermi fermi level
    4777             : !> \param nparam_pade number of pade parameters
    4778             : !> \param omega_points_pade selection of frequency points of Sigma_c(iomega)
    4779             : !> \param coeff_pade pade coefficients
    4780             : !> \param start_val start value for the quasiparticle iteration
    4781             : !> \param hedin_shift ...
    4782             : ! **************************************************************************************************
    4783          16 :    SUBROUTINE get_sigma_c_bisection_pade(gw_energ, Eigenval_scf, Sigma_x_minus_vxc_gw, e_fermi, &
    4784           8 :                                          nparam_pade, omega_points_pade, coeff_pade, start_val, &
    4785             :                                          hedin_shift)
    4786             : 
    4787             :       REAL(KIND=dp), INTENT(OUT)                         :: gw_energ
    4788             :       REAL(KIND=dp), INTENT(IN)                          :: Eigenval_scf, Sigma_x_minus_vxc_gw, &
    4789             :                                                             e_fermi
    4790             :       INTEGER, INTENT(IN)                                :: nparam_pade
    4791             :       COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN)         :: omega_points_pade, coeff_pade
    4792             :       REAL(KIND=dp), INTENT(IN)                          :: start_val, hedin_shift
    4793             : 
    4794             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'get_sigma_c_bisection_pade'
    4795             : 
    4796             :       COMPLEX(KIND=dp)                                   :: sigma_c
    4797             :       INTEGER                                            :: handle, icount
    4798             :       REAL(KIND=dp)                                      :: delta, energy_val, qp_energy, &
    4799             :                                                             qp_energy_old, threshold
    4800             : 
    4801           8 :       CALL timeset(routineN, handle)
    4802             : 
    4803           8 :       threshold = 1.0E-7_dp
    4804             : 
    4805           8 :       qp_energy = start_val
    4806           8 :       qp_energy_old = start_val
    4807           8 :       delta = 1.0E-3_dp
    4808             : 
    4809           8 :       icount = 0
    4810         116 :       DO WHILE (ABS(delta) > threshold)
    4811         108 :          icount = icount + 1
    4812         108 :          qp_energy = qp_energy_old + 0.5_dp*delta
    4813         108 :          qp_energy_old = qp_energy
    4814         108 :          energy_val = qp_energy - e_fermi - hedin_shift
    4815             :          CALL evaluate_pade_function(energy_val, nparam_pade, omega_points_pade, &
    4816         108 :                                      coeff_pade, sigma_c)
    4817         108 :          qp_energy = Eigenval_scf + REAL(sigma_c) + Sigma_x_minus_vxc_gw
    4818         108 :          delta = qp_energy - qp_energy_old
    4819             :          ! Self-consistent quasi-particle solution has not been found
    4820         116 :          IF (icount > 500) EXIT
    4821             :       END DO
    4822             : 
    4823           8 :       gw_energ = REAL(sigma_c)
    4824             : 
    4825           8 :       CALL timestop(handle)
    4826             : 
    4827           8 :    END SUBROUTINE get_sigma_c_bisection_pade
    4828             : 
    4829             : ! **************************************************************************************************
    4830             : !> \brief crossing search using the Newton method to find the quasiparticle energy
    4831             : !> \param gw_energ real Sigma_c
    4832             : !> \param Eigenval_scf Eigenvalue from the SCF
    4833             : !> \param Sigma_x_minus_vxc_gw ...
    4834             : !> \param e_fermi fermi level
    4835             : !> \param nparam_pade number of pade parameters
    4836             : !> \param omega_points_pade selection of frequency points of Sigma_c(iomega)
    4837             : !> \param coeff_pade pade coefficients
    4838             : !> \param start_val start value for the quasiparticle iteration
    4839             : !> \param hedin_shift ...
    4840             : ! **************************************************************************************************
    4841        6440 :    SUBROUTINE get_sigma_c_newton_pade(gw_energ, Eigenval_scf, Sigma_x_minus_vxc_gw, e_fermi, &
    4842        3220 :                                       nparam_pade, omega_points_pade, coeff_pade, start_val, &
    4843             :                                       hedin_shift)
    4844             : 
    4845             :       REAL(KIND=dp), INTENT(OUT)                         :: gw_energ
    4846             :       REAL(KIND=dp), INTENT(IN)                          :: Eigenval_scf, Sigma_x_minus_vxc_gw, &
    4847             :                                                             e_fermi
    4848             :       INTEGER, INTENT(IN)                                :: nparam_pade
    4849             :       COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN)         :: omega_points_pade, coeff_pade
    4850             :       REAL(KIND=dp), INTENT(IN)                          :: start_val, hedin_shift
    4851             : 
    4852             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'get_sigma_c_newton_pade'
    4853             : 
    4854             :       COMPLEX(KIND=dp)                                   :: sigma_c
    4855             :       INTEGER                                            :: handle, icount
    4856             :       REAL(KIND=dp)                                      :: delta, energy_val, m_value, qp_energy, &
    4857             :                                                             qp_energy_old, threshold
    4858             : 
    4859        3220 :       CALL timeset(routineN, handle)
    4860             : 
    4861        3220 :       threshold = 1.0E-7_dp
    4862             : 
    4863        3220 :       qp_energy = start_val
    4864        3220 :       qp_energy_old = start_val
    4865        3220 :       delta = 1.0E-3_dp
    4866             : 
    4867        3220 :       icount = 0
    4868       12573 :       DO WHILE (ABS(delta) > threshold)
    4869        9353 :          icount = icount + 1
    4870        9353 :          energy_val = qp_energy - e_fermi - hedin_shift
    4871             :          CALL evaluate_pade_function(energy_val, nparam_pade, omega_points_pade, &
    4872        9353 :                                      coeff_pade, sigma_c)
    4873             :          !get m_value --> derivative of function
    4874             :          CALL get_z_and_m_value_pade(energy_val, nparam_pade, omega_points_pade, &
    4875        9353 :                                      coeff_pade, m_value=m_value)
    4876        9353 :          qp_energy_old = qp_energy
    4877             :          qp_energy = qp_energy - (Eigenval_scf + Sigma_x_minus_vxc_gw + REAL(sigma_c) - qp_energy)/ &
    4878        9353 :                      (m_value - 1.0_dp)
    4879        9353 :          delta = qp_energy - qp_energy_old
    4880             :          ! Self-consistent quasi-particle solution has not been found
    4881       12573 :          IF (icount > 500) EXIT
    4882             :       END DO
    4883             : 
    4884        3220 :       gw_energ = REAL(sigma_c)
    4885             : 
    4886        3220 :       CALL timestop(handle)
    4887             : 
    4888        3220 :    END SUBROUTINE get_sigma_c_newton_pade
    4889             : 
    4890             : ! **************************************************************************************************
    4891             : !> \brief Prints the GW stuff to the output and optinally to an external file.
    4892             : !>        Also updates the eigenvalues for eigenvalue-self-consistent GW
    4893             : !> \param vec_gw_energ ...
    4894             : !> \param z_value ...
    4895             : !> \param m_value ...
    4896             : !> \param vec_Sigma_x_minus_vxc_gw ...
    4897             : !> \param Eigenval ...
    4898             : !> \param Eigenval_last ...
    4899             : !> \param Eigenval_scf ...
    4900             : !> \param gw_corr_lev_occ ...
    4901             : !> \param gw_corr_lev_virt ...
    4902             : !> \param gw_corr_lev_tot ...
    4903             : !> \param crossing_search ...
    4904             : !> \param homo ...
    4905             : !> \param unit_nr ...
    4906             : !> \param count_ev_sc_GW ...
    4907             : !> \param count_sc_GW0 ...
    4908             : !> \param ikp ...
    4909             : !> \param nkp_self_energy ...
    4910             : !> \param kpoints ...
    4911             : !> \param ispin requested spin-state (1 for alpha, 2 for beta, else closed-shell)
    4912             : !> \param E_VBM_GW ...
    4913             : !> \param E_CBM_GW ...
    4914             : !> \param E_VBM_SCF ...
    4915             : !> \param E_CBM_SCF ...
    4916             : ! **************************************************************************************************
    4917        1872 :    SUBROUTINE print_and_update_for_ev_sc(vec_gw_energ, &
    4918         468 :                                          z_value, m_value, vec_Sigma_x_minus_vxc_gw, Eigenval, &
    4919         468 :                                          Eigenval_last, Eigenval_scf, &
    4920             :                                          gw_corr_lev_occ, gw_corr_lev_virt, gw_corr_lev_tot, &
    4921             :                                          crossing_search, homo, unit_nr, count_ev_sc_GW, count_sc_GW0, &
    4922             :                                          ikp, nkp_self_energy, kpoints, ispin, E_VBM_GW, E_CBM_GW, &
    4923             :                                          E_VBM_SCF, E_CBM_SCF)
    4924             : 
    4925             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: vec_gw_energ, z_value, m_value
    4926             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: vec_Sigma_x_minus_vxc_gw, Eigenval, &
    4927             :                                                             Eigenval_last, Eigenval_scf
    4928             :       INTEGER, INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, gw_corr_lev_tot, crossing_search, &
    4929             :          homo, unit_nr, count_ev_sc_GW, count_sc_GW0, ikp, nkp_self_energy
    4930             :       TYPE(kpoint_type), INTENT(IN), POINTER             :: kpoints
    4931             :       INTEGER, INTENT(IN)                                :: ispin
    4932             :       REAL(KIND=dp), INTENT(INOUT), OPTIONAL             :: E_VBM_GW, E_CBM_GW, E_VBM_SCF, E_CBM_SCF
    4933             : 
    4934             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'print_and_update_for_ev_sc'
    4935             : 
    4936             :       CHARACTER(4)                                       :: occ_virt
    4937             :       INTEGER                                            :: handle, n_level_gw, n_level_gw_ref
    4938             :       LOGICAL                                            :: do_alpha, do_beta, do_closed_shell, &
    4939             :                                                             do_kpoints, is_energy_okay
    4940             :       REAL(KIND=dp)                                      :: E_GAP_GW, E_HOMO_GW, E_HOMO_SCF, &
    4941             :                                                             E_LUMO_GW, E_LUMO_SCF, new_energy
    4942             : 
    4943         468 :       CALL timeset(routineN, handle)
    4944             : 
    4945         468 :       do_alpha = (ispin == 1)
    4946         468 :       do_beta = (ispin == 2)
    4947         468 :       do_closed_shell = .NOT. (do_alpha .OR. do_beta)
    4948         468 :       do_kpoints = (nkp_self_energy > 1)
    4949             : 
    4950       10658 :       Eigenval_last(:) = Eigenval(:)
    4951             : 
    4952         468 :       IF (unit_nr > 0) THEN
    4953             : 
    4954         234 :          IF (count_ev_sc_GW == 1 .AND. count_sc_GW0 == 1 .AND. ikp == 1) THEN
    4955             : 
    4956          65 :             WRITE (unit_nr, *) ' '
    4957             : 
    4958          65 :             IF (do_alpha .OR. do_closed_shell) THEN
    4959          58 :                WRITE (unit_nr, *) ' '
    4960          58 :                WRITE (unit_nr, '(T3,A)') '******************************************************************************'
    4961          58 :                WRITE (unit_nr, '(T3,A)') '**                                                                          **'
    4962          58 :                WRITE (unit_nr, '(T3,A)') '**                        GW QUASIPARTICLE ENERGIES                         **'
    4963          58 :                WRITE (unit_nr, '(T3,A)') '**                                                                          **'
    4964          58 :                WRITE (unit_nr, '(T3,A)') '******************************************************************************'
    4965          58 :                WRITE (unit_nr, '(T3,A)') ' '
    4966          58 :                WRITE (unit_nr, '(T3,A)') ' '
    4967          58 :                WRITE (unit_nr, '(T3,A)') 'The GW quasiparticle energies are calculated according to: '
    4968             : 
    4969          58 :                IF (crossing_search == ri_rpa_g0w0_crossing_z_shot) THEN
    4970          16 :                   WRITE (unit_nr, '(T3,A)') 'E_GW = E_SCF + Z * ( Sigc(E_SCF) + Sigx - vxc )'
    4971             :                ELSE
    4972          42 :                   WRITE (unit_nr, '(T3,A)') ' '
    4973          42 :                   WRITE (unit_nr, '(T3,A)') '                    E_GW = E_SCF + Sigc(E_GW) + Sigx - vxc '
    4974          42 :                   WRITE (unit_nr, '(T3,A)') ' '
    4975          42 :                   WRITE (unit_nr, '(T3,A)') 'Upper equation is solved self-consistently for E_GW, see Eq. (12) in J. Phys.'
    4976          42 :                   WRITE (unit_nr, '(T3,A)') 'Chem. Lett. 9, 306 (2018), doi: 10.1021/acs.jpclett.7b02740'
    4977             :                END IF
    4978          58 :                WRITE (unit_nr, *) ' '
    4979          58 :                WRITE (unit_nr, *) ' '
    4980          58 :                WRITE (unit_nr, '(T3,A)') '------------'
    4981          58 :                WRITE (unit_nr, '(T3,A)') 'G0W0 results'
    4982          58 :                WRITE (unit_nr, '(T3,A)') '------------'
    4983             : 
    4984             :             END IF
    4985             : 
    4986          65 :             IF (.NOT. do_kpoints) THEN
    4987          54 :                IF (do_alpha) THEN
    4988           5 :                   WRITE (unit_nr, *) ' '
    4989           5 :                   WRITE (unit_nr, '(T3,A)') '---------------------------------------'
    4990           5 :                   WRITE (unit_nr, '(T3,A)') 'GW quasiparticle energies of alpha spins'
    4991           5 :                   WRITE (unit_nr, '(T3,A)') '----------------------------------------'
    4992          49 :                ELSE IF (do_beta) THEN
    4993           5 :                   WRITE (unit_nr, *) ' '
    4994           5 :                   WRITE (unit_nr, '(T3,A)') '---------------------------------------'
    4995           5 :                   WRITE (unit_nr, '(T3,A)') 'GW quasiparticle energies of beta spins'
    4996           5 :                   WRITE (unit_nr, '(T3,A)') '---------------------------------------'
    4997             :                END IF
    4998             :             END IF
    4999             : 
    5000             :          END IF
    5001             : 
    5002         234 :          IF (count_ev_sc_GW > 1) THEN
    5003          49 :             WRITE (unit_nr, *) ' '
    5004          49 :             WRITE (unit_nr, '(T3,A)') '---------------------------------------'
    5005          49 :             WRITE (unit_nr, '(T3,A,I4)') 'Eigenvalue-selfconsistency cycle: ', count_ev_sc_GW
    5006          49 :             WRITE (unit_nr, '(T3,A)') '---------------------------------------'
    5007             :          END IF
    5008             : 
    5009         234 :          IF (count_sc_GW0 > 1) THEN
    5010          48 :             WRITE (unit_nr, '(T3,A)') '----------------------------------'
    5011          48 :             WRITE (unit_nr, '(T3,A,I4)') 'scGW0 selfconsistency cycle: ', count_sc_GW0
    5012          48 :             WRITE (unit_nr, '(T3,A)') '----------------------------------'
    5013             :          END IF
    5014             : 
    5015         234 :          IF (do_kpoints) THEN
    5016          84 :             WRITE (unit_nr, *) ' '
    5017          84 :             WRITE (unit_nr, '(T3,A7,I3,A3,I3,A8,3F7.3,A12,3F7.3)') 'Kpoint ', ikp, '  /', nkp_self_energy, &
    5018          84 :                '   xkp =', kpoints%xkp(1, ikp), kpoints%xkp(2, ikp), kpoints%xkp(3, ikp), &
    5019         168 :                '  and  xkp =', -kpoints%xkp(1, ikp), -kpoints%xkp(2, ikp), -kpoints%xkp(3, ikp)
    5020          84 :             WRITE (unit_nr, '(T3,A72)') '(Relative Brillouin zone size: [-0.5, 0.5] x [-0.5, 0.5] x [-0.5, 0.5])'
    5021          84 :             WRITE (unit_nr, *) ' '
    5022          84 :             IF (do_alpha) THEN
    5023          16 :                WRITE (unit_nr, '(T3,A)') 'GW quasiparticle energies of alpha spins:'
    5024          68 :             ELSE IF (do_beta) THEN
    5025          16 :                WRITE (unit_nr, '(T3,A)') 'GW quasiparticle energies of beta spins:'
    5026             :             END IF
    5027             :          END IF
    5028             : 
    5029             :       END IF
    5030             : 
    5031        4940 :       DO n_level_gw = 1, gw_corr_lev_tot
    5032             : 
    5033        4472 :          n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
    5034             : 
    5035             :          new_energy = (Eigenval_scf(n_level_gw_ref) - &
    5036             :                        m_value(n_level_gw)*Eigenval(n_level_gw_ref) + &
    5037             :                        vec_gw_energ(n_level_gw) + &
    5038             :                        vec_Sigma_x_minus_vxc_gw(n_level_gw_ref))* &
    5039        4472 :                       z_value(n_level_gw)
    5040             : 
    5041        4472 :          is_energy_okay = .TRUE.
    5042             : 
    5043        4472 :          IF (n_level_gw_ref > homo .AND. new_energy < Eigenval(homo)) THEN
    5044             :             is_energy_okay = .FALSE.
    5045             :          END IF
    5046             : 
    5047         468 :          IF (is_energy_okay) THEN
    5048        4472 :             Eigenval(n_level_gw_ref) = new_energy
    5049             :          END IF
    5050             : 
    5051             :       END DO
    5052             : 
    5053         468 :       IF (unit_nr > 0) THEN
    5054         234 :          WRITE (unit_nr, '(T3,A)') ' '
    5055         234 :          IF (crossing_search == ri_rpa_g0w0_crossing_z_shot) THEN
    5056          39 :             WRITE (unit_nr, '(T13,2A)') 'MO    E_SCF (eV)    Sigc (eV)   Sigx-vxc (eV)    Z         E_GW (eV)'
    5057             :          ELSE
    5058         195 :             WRITE (unit_nr, '(T3,2A)') 'Molecular orbital   E_SCF (eV)       Sigc (eV)   Sigx-vxc (eV)       E_GW (eV)'
    5059             :          END IF
    5060             :       END IF
    5061             : 
    5062        4940 :       DO n_level_gw = 1, gw_corr_lev_tot
    5063        4472 :          n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
    5064        4472 :          IF (n_level_gw <= gw_corr_lev_occ) THEN
    5065        1266 :             occ_virt = 'occ'
    5066             :          ELSE
    5067        3206 :             occ_virt = 'vir'
    5068             :          END IF
    5069             : 
    5070        4940 :          IF (unit_nr > 0) THEN
    5071        2236 :             IF (crossing_search == ri_rpa_g0w0_crossing_z_shot) THEN
    5072             :                WRITE (unit_nr, '(T3,I4,3A,5F13.4)') &
    5073         536 :                   n_level_gw_ref, ' ( ', occ_virt, ') ', &
    5074         536 :                   Eigenval_last(n_level_gw_ref)*evolt, &
    5075         536 :                   vec_gw_energ(n_level_gw)*evolt, &
    5076         536 :                   vec_Sigma_x_minus_vxc_gw(n_level_gw_ref)*evolt, &
    5077         536 :                   z_value(n_level_gw), &
    5078        1072 :                   Eigenval(n_level_gw_ref)*evolt
    5079             :             ELSE
    5080             :                WRITE (unit_nr, '(T3,I4,3A,4F16.4)') &
    5081        1700 :                   n_level_gw_ref, ' ( ', occ_virt, ')  ', &
    5082        1700 :                   Eigenval_last(n_level_gw_ref)*evolt, &
    5083        1700 :                   vec_gw_energ(n_level_gw)*evolt, &
    5084        1700 :                   vec_Sigma_x_minus_vxc_gw(n_level_gw_ref)*evolt, &
    5085        3400 :                   Eigenval(n_level_gw_ref)*evolt
    5086             :             END IF
    5087             :          END IF
    5088             :       END DO
    5089             : 
    5090        2202 :       E_HOMO_SCF = MAXVAL(Eigenval_last(homo - gw_corr_lev_occ + 1:homo))
    5091        4142 :       E_LUMO_SCF = MINVAL(Eigenval_last(homo + 1:homo + gw_corr_lev_virt))
    5092             : 
    5093        2202 :       E_HOMO_GW = MAXVAL(Eigenval(homo - gw_corr_lev_occ + 1:homo))
    5094        4142 :       E_LUMO_GW = MINVAL(Eigenval(homo + 1:homo + gw_corr_lev_virt))
    5095         468 :       E_GAP_GW = E_LUMO_GW - E_HOMO_GW
    5096             : 
    5097             :       IF (PRESENT(E_VBM_SCF) .AND. PRESENT(E_CBM_SCF) .AND. &
    5098         468 :           PRESENT(E_VBM_GW) .AND. PRESENT(E_CBM_GW)) THEN
    5099         468 :          IF (E_HOMO_SCF > E_VBM_SCF) E_VBM_SCF = E_HOMO_SCF
    5100         468 :          IF (E_LUMO_SCF < E_CBM_SCF) E_CBM_SCF = E_LUMO_SCF
    5101         468 :          IF (E_HOMO_GW > E_VBM_GW) E_VBM_GW = E_HOMO_GW
    5102         468 :          IF (E_LUMO_GW < E_CBM_GW) E_CBM_GW = E_LUMO_GW
    5103             :       END IF
    5104             : 
    5105         468 :       IF (unit_nr > 0) THEN
    5106             : 
    5107         234 :          IF (do_kpoints) THEN
    5108          84 :             IF (do_closed_shell) THEN
    5109          52 :                WRITE (unit_nr, '(T3,A)') ' '
    5110          52 :                WRITE (unit_nr, '(T3,A,F42.4)') 'GW direct gap at current kpoint (eV)', E_GAP_GW*evolt
    5111          32 :             ELSE IF (do_alpha) THEN
    5112          16 :                WRITE (unit_nr, '(T3,A)') ' '
    5113          16 :                WRITE (unit_nr, '(T3,A,F36.4)') 'Alpha GW direct gap at current kpoint (eV)', &
    5114          32 :                   E_GAP_GW*evolt
    5115          16 :             ELSE IF (do_beta) THEN
    5116          16 :                WRITE (unit_nr, '(T3,A)') ' '
    5117          16 :                WRITE (unit_nr, '(T3,A,F37.4)') 'Beta GW direct gap at current kpoint (eV)', &
    5118          32 :                   E_GAP_GW*evolt
    5119             :             END IF
    5120             :          ELSE
    5121         150 :             IF (do_closed_shell) THEN
    5122         132 :                WRITE (unit_nr, '(T3,A)') ' '
    5123         132 :                IF (count_ev_sc_GW > 1) THEN
    5124          41 :                   WRITE (unit_nr, '(T3,A,I3,A,F39.4)') 'HOMO-LUMO gap in evGW iteration', &
    5125          82 :                      count_ev_sc_GW, ' (eV)', E_GAP_GW*evolt
    5126          91 :                ELSE IF (count_sc_GW0 > 1) THEN
    5127          47 :                   WRITE (unit_nr, '(T3,A,I3,A,F38.4)') 'HOMO-LUMO gap in evGW0 iteration', &
    5128          94 :                      count_sc_GW0, ' (eV)', E_GAP_GW*evolt
    5129             :                ELSE
    5130          44 :                   WRITE (unit_nr, '(T3,A,F55.4)') 'G0W0 HOMO-LUMO gap (eV)', E_GAP_GW*evolt
    5131             :                END IF
    5132          18 :             ELSE IF (do_alpha) THEN
    5133           9 :                WRITE (unit_nr, '(T3,A)') ' '
    5134           9 :                WRITE (unit_nr, '(T3,A,F51.4)') 'Alpha GW HOMO-LUMO gap (eV)', E_GAP_GW*evolt
    5135           9 :             ELSE IF (do_beta) THEN
    5136           9 :                WRITE (unit_nr, '(T3,A)') ' '
    5137           9 :                WRITE (unit_nr, '(T3,A,F52.4)') 'Beta GW HOMO-LUMO gap (eV)', E_GAP_GW*evolt
    5138             :             END IF
    5139             :          END IF
    5140             :       END IF
    5141             : 
    5142         468 :       IF (unit_nr > 0) THEN
    5143         234 :          WRITE (unit_nr, *) ' '
    5144         234 :          WRITE (unit_nr, '(T3,A)') '------------------------------------------------------------------------------'
    5145             :       END IF
    5146             : 
    5147         468 :       CALL timestop(handle)
    5148             : 
    5149         468 :    END SUBROUTINE print_and_update_for_ev_sc
    5150             : 
    5151             : ! **************************************************************************************************
    5152             : !> \brief ...
    5153             : !> \param Eigenval ...
    5154             : !> \param Eigenval_last ...
    5155             : !> \param gw_corr_lev_occ ...
    5156             : !> \param gw_corr_lev_virt ...
    5157             : !> \param homo ...
    5158             : !> \param nmo ...
    5159             : ! **************************************************************************************************
    5160         290 :    PURE SUBROUTINE shift_unshifted_levels(Eigenval, Eigenval_last, gw_corr_lev_occ, gw_corr_lev_virt, &
    5161             :                                           homo, nmo)
    5162             : 
    5163             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: Eigenval, Eigenval_last
    5164             :       INTEGER, INTENT(IN)                                :: gw_corr_lev_occ, gw_corr_lev_virt, homo, &
    5165             :                                                             nmo
    5166             : 
    5167             :       INTEGER                                            :: n_level_gw, n_level_gw_ref
    5168             :       REAL(KIND=dp)                                      :: eigen_diff
    5169             : 
    5170             :       ! for eigenvalue self-consistent GW, all eigenvalues have to be corrected
    5171             :       ! 1) the occupied; check if there are occupied MOs not being corrected by GW
    5172         290 :       IF (gw_corr_lev_occ < homo .AND. gw_corr_lev_occ > 0) THEN
    5173             : 
    5174             :          ! calculate average GW correction for occupied orbitals
    5175             :          eigen_diff = 0.0_dp
    5176             : 
    5177          88 :          DO n_level_gw = 1, gw_corr_lev_occ
    5178          44 :             n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
    5179          88 :             eigen_diff = eigen_diff + Eigenval(n_level_gw_ref) - Eigenval_last(n_level_gw_ref)
    5180             :          END DO
    5181          44 :          eigen_diff = eigen_diff/gw_corr_lev_occ
    5182             : 
    5183             :          ! correct the eigenvalues of the occupied orbitals which have not been corrected by GW
    5184         168 :          DO n_level_gw = 1, homo - gw_corr_lev_occ
    5185         168 :             Eigenval(n_level_gw) = Eigenval(n_level_gw) + eigen_diff
    5186             :          END DO
    5187             : 
    5188             :       END IF
    5189             : 
    5190             :       ! 2) the virtual: check if there are virtual orbitals not being corrected by GW
    5191         290 :       IF (gw_corr_lev_virt < nmo - homo .AND. gw_corr_lev_virt > 0) THEN
    5192             : 
    5193             :          ! calculate average GW correction for virtual orbitals
    5194             :          eigen_diff = 0.0_dp
    5195        2996 :          DO n_level_gw = 1, gw_corr_lev_virt
    5196        2706 :             n_level_gw_ref = n_level_gw + homo
    5197        2996 :             eigen_diff = eigen_diff + Eigenval(n_level_gw_ref) - Eigenval_last(n_level_gw_ref)
    5198             :          END DO
    5199         290 :          eigen_diff = eigen_diff/gw_corr_lev_virt
    5200             : 
    5201             :          ! correct the eigenvalues of the virtual orbitals which have not been corrected by GW
    5202        3090 :          DO n_level_gw = homo + gw_corr_lev_virt + 1, nmo
    5203        3090 :             Eigenval(n_level_gw) = Eigenval(n_level_gw) + eigen_diff
    5204             :          END DO
    5205             : 
    5206             :       END IF
    5207             : 
    5208         290 :    END SUBROUTINE shift_unshifted_levels
    5209             : 
    5210             : ! **************************************************************************************************
    5211             : !> \brief Calculate the matrix mat_N_gw containing the second derivatives
    5212             : !>        with respect to the fitting parameters. The second derivatives are
    5213             : !>        calculated numerically by finite differences.
    5214             : !> \param N_ij matrix element
    5215             : !> \param Lambda fitting parameters
    5216             : !> \param Sigma_c ...
    5217             : !> \param vec_omega_fit_gw ...
    5218             : !> \param i ...
    5219             : !> \param j ...
    5220             : !> \param num_poles ...
    5221             : !> \param num_fit_points ...
    5222             : !> \param n_level_gw ...
    5223             : !> \param h  ...
    5224             : ! **************************************************************************************************
    5225       62480 :    SUBROUTINE calc_mat_N(N_ij, Lambda, Sigma_c, vec_omega_fit_gw, i, j, &
    5226             :                          num_poles, num_fit_points, n_level_gw, h)
    5227             :       REAL(KIND=dp), INTENT(OUT)                         :: N_ij
    5228             :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:), &
    5229             :          INTENT(IN)                                      :: Lambda
    5230             :       COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(IN)      :: Sigma_c
    5231             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
    5232             :          INTENT(IN)                                      :: vec_omega_fit_gw
    5233             :       INTEGER, INTENT(IN)                                :: i, j, num_poles, num_fit_points, &
    5234             :                                                             n_level_gw
    5235             :       REAL(KIND=dp), INTENT(IN)                          :: h
    5236             : 
    5237             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'calc_mat_N'
    5238             : 
    5239             :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:)        :: Lambda_tmp
    5240             :       INTEGER                                            :: handle, num_var
    5241             :       REAL(KIND=dp)                                      :: chi2, chi2_sum
    5242             : 
    5243       62480 :       CALL timeset(routineN, handle)
    5244             : 
    5245       62480 :       num_var = 2*num_poles + 1
    5246      187440 :       ALLOCATE (Lambda_tmp(num_var))
    5247      374880 :       Lambda_tmp = z_zero
    5248       62480 :       chi2_sum = 0.0_dp
    5249             : 
    5250             :       !test
    5251      374880 :       Lambda_tmp(:) = Lambda(:)
    5252             :       CALL calc_chi2(chi2, Lambda_tmp, Sigma_c, vec_omega_fit_gw, num_poles, &
    5253       62480 :                      num_fit_points, n_level_gw)
    5254             : 
    5255             :       ! Fitting parameters with offset h
    5256      374880 :       Lambda_tmp(:) = Lambda(:)
    5257       62480 :       IF (MODULO(i, 2) == 0) THEN
    5258       31240 :          Lambda_tmp(i/2) = Lambda_tmp(i/2) + h*z_one
    5259             :       ELSE
    5260       31240 :          Lambda_tmp((i + 1)/2) = Lambda_tmp((i + 1)/2) + h*gaussi
    5261             :       END IF
    5262       62480 :       IF (MODULO(j, 2) == 0) THEN
    5263       31240 :          Lambda_tmp(j/2) = Lambda_tmp(j/2) + h*z_one
    5264             :       ELSE
    5265       31240 :          Lambda_tmp((j + 1)/2) = Lambda_tmp((j + 1)/2) + h*gaussi
    5266             :       END IF
    5267             :       CALL calc_chi2(chi2, Lambda_tmp, Sigma_c, vec_omega_fit_gw, num_poles, &
    5268       62480 :                      num_fit_points, n_level_gw)
    5269       62480 :       chi2_sum = chi2_sum + chi2
    5270             : 
    5271       62480 :       IF (MODULO(i, 2) == 0) THEN
    5272       31240 :          Lambda_tmp(i/2) = Lambda_tmp(i/2) - 2.0_dp*h*z_one
    5273             :       ELSE
    5274       31240 :          Lambda_tmp((i + 1)/2) = Lambda_tmp((i + 1)/2) - 2.0_dp*h*gaussi
    5275             :       END IF
    5276             :       CALL calc_chi2(chi2, Lambda_tmp, Sigma_c, vec_omega_fit_gw, num_poles, &
    5277       62480 :                      num_fit_points, n_level_gw)
    5278       62480 :       chi2_sum = chi2_sum - chi2
    5279             : 
    5280       62480 :       IF (MODULO(j, 2) == 0) THEN
    5281       31240 :          Lambda_tmp(j/2) = Lambda_tmp(j/2) - 2.0_dp*h*z_one
    5282             :       ELSE
    5283       31240 :          Lambda_tmp((j + 1)/2) = Lambda_tmp((j + 1)/2) - 2.0_dp*h*gaussi
    5284             :       END IF
    5285             :       CALL calc_chi2(chi2, Lambda_tmp, Sigma_c, vec_omega_fit_gw, num_poles, &
    5286       62480 :                      num_fit_points, n_level_gw)
    5287       62480 :       chi2_sum = chi2_sum + chi2
    5288             : 
    5289       62480 :       IF (MODULO(i, 2) == 0) THEN
    5290       31240 :          Lambda_tmp(i/2) = Lambda_tmp(i/2) + 2.0_dp*h*z_one
    5291             :       ELSE
    5292       31240 :          Lambda_tmp((i + 1)/2) = Lambda_tmp((i + 1)/2) + 2.0_dp*h*gaussi
    5293             :       END IF
    5294             :       CALL calc_chi2(chi2, Lambda_tmp, Sigma_c, vec_omega_fit_gw, num_poles, &
    5295       62480 :                      num_fit_points, n_level_gw)
    5296       62480 :       chi2_sum = chi2_sum - chi2
    5297             : 
    5298             :       ! Second derivative with symmetric difference quotient
    5299       62480 :       N_ij = 1.0_dp/2.0_dp*chi2_sum/(4.0_dp*h*h)
    5300             : 
    5301       62480 :       DEALLOCATE (Lambda_tmp)
    5302             : 
    5303       62480 :       CALL timestop(handle)
    5304             : 
    5305       62480 :    END SUBROUTINE calc_mat_N
    5306             : 
    5307             : ! **************************************************************************************************
    5308             : !> \brief Calculate chi2
    5309             : !> \param chi2 ...
    5310             : !> \param Lambda fitting parameters
    5311             : !> \param Sigma_c ...
    5312             : !> \param vec_omega_fit_gw ...
    5313             : !> \param num_poles ...
    5314             : !> \param num_fit_points ...
    5315             : !> \param n_level_gw ...
    5316             : ! **************************************************************************************************
    5317     1397195 :    PURE SUBROUTINE calc_chi2(chi2, Lambda, Sigma_c, vec_omega_fit_gw, num_poles, &
    5318             :                              num_fit_points, n_level_gw)
    5319             :       REAL(KIND=dp), INTENT(OUT)                         :: chi2
    5320             :       COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN)         :: Lambda
    5321             :       COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(IN)      :: Sigma_c
    5322             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: vec_omega_fit_gw
    5323             :       INTEGER, INTENT(IN)                                :: num_poles, num_fit_points, n_level_gw
    5324             : 
    5325             :       COMPLEX(KIND=dp)                                   :: func_val
    5326             :       INTEGER                                            :: iii, jjj, kkk
    5327             : 
    5328     1397195 :       chi2 = 0.0_dp
    5329    15969281 :       DO kkk = 1, num_fit_points
    5330    14572086 :          func_val = Lambda(1)
    5331    43716258 :          DO iii = 1, num_poles
    5332    29144172 :             jjj = iii*2
    5333             :             ! calculate value of the fit function
    5334    43716258 :             func_val = func_val + Lambda(jjj)/(gaussi*vec_omega_fit_gw(kkk) - Lambda(jjj + 1))
    5335             :          END DO
    5336    15969281 :          chi2 = chi2 + (ABS(Sigma_c(n_level_gw, kkk) - func_val))**2
    5337             :       END DO
    5338             : 
    5339     1397195 :    END SUBROUTINE calc_chi2
    5340             : 
    5341             : ! **************************************************************************************************
    5342             : !> \brief ...
    5343             : !> \param num_integ_points ...
    5344             : !> \param nmo ...
    5345             : !> \param tau_tj ...
    5346             : !> \param tj ...
    5347             : !> \param matrix_s ...
    5348             : !> \param fm_mo_coeff_occ ...
    5349             : !> \param fm_mo_coeff_virt ...
    5350             : !> \param fm_mo_coeff_occ_scaled ...
    5351             : !> \param fm_mo_coeff_virt_scaled ...
    5352             : !> \param fm_scaled_dm_occ_tau ...
    5353             : !> \param fm_scaled_dm_virt_tau ...
    5354             : !> \param Eigenval ...
    5355             : !> \param eps_filter ...
    5356             : !> \param e_fermi ...
    5357             : !> \param fm_mat_W ...
    5358             : !> \param gw_corr_lev_tot ...
    5359             : !> \param gw_corr_lev_occ ...
    5360             : !> \param gw_corr_lev_virt ...
    5361             : !> \param homo ...
    5362             : !> \param count_ev_sc_GW ...
    5363             : !> \param count_sc_GW0 ...
    5364             : !> \param t_3c_overl_int_ao_mo ...
    5365             : !> \param t_3c_O_mo_compressed ...
    5366             : !> \param t_3c_O_mo_ind ...
    5367             : !> \param t_3c_overl_int_gw_RI ...
    5368             : !> \param t_3c_overl_int_gw_AO ...
    5369             : !> \param mat_W ...
    5370             : !> \param mat_MinvVMinv ...
    5371             : !> \param mat_dm ...
    5372             : !> \param weights_cos_tf_t_to_w ...
    5373             : !> \param weights_sin_tf_t_to_w ...
    5374             : !> \param vec_Sigma_c_gw ...
    5375             : !> \param do_periodic ...
    5376             : !> \param num_points_corr ...
    5377             : !> \param delta_corr ...
    5378             : !> \param qs_env ...
    5379             : !> \param para_env ...
    5380             : !> \param para_env_RPA ...
    5381             : !> \param mp2_env ...
    5382             : !> \param matrix_berry_re_mo_mo ...
    5383             : !> \param matrix_berry_im_mo_mo ...
    5384             : !> \param first_cycle_periodic_correction ...
    5385             : !> \param kpoints ...
    5386             : !> \param num_fit_points ...
    5387             : !> \param fm_mo_coeff ...
    5388             : !> \param do_ri_Sigma_x ...
    5389             : !> \param vec_Sigma_x_gw ...
    5390             : !> \param unit_nr ...
    5391             : !> \param ispin ...
    5392             : ! **************************************************************************************************
    5393          62 :    SUBROUTINE compute_self_energy_cubic_gw(num_integ_points, nmo, tau_tj, tj, &
    5394          62 :                                            matrix_s, fm_mo_coeff_occ, fm_mo_coeff_virt, fm_mo_coeff_occ_scaled, &
    5395             :                                            fm_mo_coeff_virt_scaled, fm_scaled_dm_occ_tau, &
    5396         124 :                                            fm_scaled_dm_virt_tau, Eigenval, eps_filter, &
    5397          62 :                                            e_fermi, fm_mat_W, &
    5398             :                                            gw_corr_lev_tot, gw_corr_lev_occ, gw_corr_lev_virt, homo, &
    5399             :                                            count_ev_sc_GW, count_sc_GW0, &
    5400          62 :                                            t_3c_overl_int_ao_mo, t_3c_O_mo_compressed, t_3c_O_mo_ind, &
    5401             :                                            t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
    5402             :                                            mat_W, mat_MinvVMinv, mat_dm, &
    5403         124 :                                            weights_cos_tf_t_to_w, weights_sin_tf_t_to_w, vec_Sigma_c_gw, &
    5404             :                                            do_periodic, num_points_corr, delta_corr, qs_env, para_env, para_env_RPA, &
    5405             :                                            mp2_env, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
    5406             :                                            first_cycle_periodic_correction, kpoints, num_fit_points, fm_mo_coeff, &
    5407          62 :                                            do_ri_Sigma_x, vec_Sigma_x_gw, unit_nr, ispin)
    5408             :       INTEGER, INTENT(IN)                                :: num_integ_points, nmo
    5409             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
    5410             :          INTENT(IN)                                      :: tau_tj, tj
    5411             :       TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN)       :: matrix_s
    5412             :       TYPE(cp_fm_type), INTENT(IN) :: fm_mo_coeff_occ, fm_mo_coeff_virt, fm_mo_coeff_occ_scaled, &
    5413             :          fm_mo_coeff_virt_scaled, fm_scaled_dm_occ_tau, fm_scaled_dm_virt_tau
    5414             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: Eigenval
    5415             :       REAL(KIND=dp), INTENT(IN)                          :: eps_filter
    5416             :       REAL(KIND=dp), INTENT(INOUT)                       :: e_fermi
    5417             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: fm_mat_W
    5418             :       INTEGER, INTENT(IN)                                :: gw_corr_lev_tot, gw_corr_lev_occ, &
    5419             :                                                             gw_corr_lev_virt, homo, &
    5420             :                                                             count_ev_sc_GW, count_sc_GW0
    5421             :       TYPE(dbt_type)                                     :: t_3c_overl_int_ao_mo
    5422             :       TYPE(hfx_compression_type)                         :: t_3c_O_mo_compressed
    5423             :       INTEGER, DIMENSION(:, :)                           :: t_3c_O_mo_ind
    5424             :       TYPE(dbt_type)                                     :: t_3c_overl_int_gw_RI, &
    5425             :                                                             t_3c_overl_int_gw_AO
    5426             :       TYPE(dbcsr_type), INTENT(INOUT), TARGET            :: mat_W
    5427             :       TYPE(dbcsr_p_type)                                 :: mat_MinvVMinv, mat_dm
    5428             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: weights_cos_tf_t_to_w, &
    5429             :                                                             weights_sin_tf_t_to_w
    5430             :       COMPLEX(KIND=dp), DIMENSION(:, :, :), INTENT(OUT)  :: vec_Sigma_c_gw
    5431             :       LOGICAL, INTENT(IN)                                :: do_periodic
    5432             :       INTEGER, INTENT(IN)                                :: num_points_corr
    5433             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
    5434             :          INTENT(INOUT)                                   :: delta_corr
    5435             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    5436             :       TYPE(mp_para_env_type), POINTER                    :: para_env, para_env_RPA
    5437             :       TYPE(mp2_type), INTENT(INOUT)                      :: mp2_env
    5438             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_berry_re_mo_mo, &
    5439             :                                                             matrix_berry_im_mo_mo
    5440             :       LOGICAL, INTENT(INOUT) :: first_cycle_periodic_correction
    5441             :       TYPE(kpoint_type), POINTER                         :: kpoints
    5442             :       INTEGER, INTENT(IN)                                :: num_fit_points
    5443             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mo_coeff
    5444             :       LOGICAL, INTENT(IN)                                :: do_ri_Sigma_x
    5445             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: vec_Sigma_x_gw
    5446             :       INTEGER, INTENT(IN)                                :: unit_nr, ispin
    5447             : 
    5448             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_self_energy_cubic_gw'
    5449             : 
    5450          62 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :)     :: delta_corr_omega
    5451             :       INTEGER :: gw_lev_end, gw_lev_start, handle, handle3, i, iblk_mo, iquad, jquad, mo_end, &
    5452             :          mo_start, n_level_gw, n_level_gw_ref, nblk_mo, unit_nr_prv
    5453          62 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: batch_range_mo, dist1, dist2, mo_bsizes, &
    5454         124 :                                                             mo_offsets, sizes_AO, sizes_RI
    5455             :       INTEGER, DIMENSION(2)                              :: mo_bounds, pdims_2d
    5456             :       LOGICAL                                            :: memory_info
    5457             :       REAL(KIND=dp)                                      :: ext_scaling, omega, omega_i, omega_sign, &
    5458             :                                                             sign_occ_virt, t_i_Clenshaw, tau, &
    5459             :                                                             weight_cos, weight_i, weight_sin
    5460          62 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: vec_Sigma_c_gw_cos_omega, &
    5461          62 :          vec_Sigma_c_gw_cos_tau, vec_Sigma_c_gw_neg_tau, vec_Sigma_c_gw_pos_tau, &
    5462          62 :          vec_Sigma_c_gw_sin_omega, vec_Sigma_c_gw_sin_tau
    5463             :       TYPE(dbcsr_type), TARGET                           :: mat_greens_fct_occ, mat_greens_fct_virt
    5464         186 :       TYPE(dbt_pgrid_type)                               :: pgrid_2d
    5465        1178 :       TYPE(dbt_type)                                     :: t_3c_ctr_AO, t_3c_ctr_RI, t_AO_tmp, &
    5466         806 :                                                             t_dm, t_greens_fct_occ, &
    5467         806 :                                                             t_greens_fct_virt, t_RI_tmp, &
    5468         806 :                                                             t_SinvVSinv, t_W
    5469             : 
    5470          62 :       CALL timeset(routineN, handle)
    5471             : 
    5472             :       CALL decompress_tensor(t_3c_overl_int_ao_mo, t_3c_O_mo_ind, t_3c_O_mo_compressed, &
    5473          62 :                              mp2_env%ri_rpa_im_time%eps_compress)
    5474             : 
    5475          62 :       CALL dbt_copy(t_3c_overl_int_ao_mo, t_3c_overl_int_gw_RI)
    5476          62 :       CALL dbt_copy(t_3c_overl_int_ao_mo, t_3c_overl_int_gw_AO, order=[2, 1, 3], move_data=.TRUE.)
    5477             : 
    5478          62 :       memory_info = mp2_env%ri_rpa_im_time%memory_info
    5479          62 :       IF (memory_info) THEN
    5480           0 :          unit_nr_prv = unit_nr
    5481             :       ELSE
    5482          62 :          unit_nr_prv = 0
    5483             :       END IF
    5484             : 
    5485          62 :       mo_start = homo - gw_corr_lev_occ + 1
    5486          62 :       mo_end = homo + gw_corr_lev_virt
    5487          62 :       CPASSERT(mo_end - mo_start + 1 == gw_corr_lev_tot)
    5488             : 
    5489        4502 :       vec_Sigma_c_gw = z_zero
    5490         248 :       ALLOCATE (vec_Sigma_c_gw_pos_tau(gw_corr_lev_tot, num_integ_points))
    5491        8382 :       vec_Sigma_c_gw_pos_tau = 0.0_dp
    5492         186 :       ALLOCATE (vec_Sigma_c_gw_neg_tau(gw_corr_lev_tot, num_integ_points))
    5493        8382 :       vec_Sigma_c_gw_neg_tau = 0.0_dp
    5494         186 :       ALLOCATE (vec_Sigma_c_gw_cos_tau(gw_corr_lev_tot, num_integ_points))
    5495        8382 :       vec_Sigma_c_gw_cos_tau = 0.0_dp
    5496         186 :       ALLOCATE (vec_Sigma_c_gw_sin_tau(gw_corr_lev_tot, num_integ_points))
    5497        8382 :       vec_Sigma_c_gw_sin_tau = 0.0_dp
    5498             : 
    5499         186 :       ALLOCATE (vec_Sigma_c_gw_cos_omega(gw_corr_lev_tot, num_integ_points))
    5500        8382 :       vec_Sigma_c_gw_cos_omega = 0.0_dp
    5501         186 :       ALLOCATE (vec_Sigma_c_gw_sin_omega(gw_corr_lev_tot, num_integ_points))
    5502        8382 :       vec_Sigma_c_gw_sin_omega = 0.0_dp
    5503             : 
    5504         248 :       ALLOCATE (delta_corr_omega(1 + homo - gw_corr_lev_occ:homo + gw_corr_lev_virt, num_integ_points))
    5505        8382 :       delta_corr_omega(:, :) = z_zero
    5506             : 
    5507             :       CALL dbcsr_create(matrix=mat_greens_fct_occ, &
    5508             :                         template=matrix_s(1)%matrix, &
    5509          62 :                         matrix_type=dbcsr_type_no_symmetry)
    5510             : 
    5511             :       CALL dbcsr_create(matrix=mat_greens_fct_virt, &
    5512             :                         template=matrix_s(1)%matrix, &
    5513          62 :                         matrix_type=dbcsr_type_no_symmetry)
    5514             : 
    5515          62 :       e_fermi = 0.5_dp*(Eigenval(homo) + Eigenval(homo + 1))
    5516             : 
    5517          62 :       nblk_mo = dbt_nblks_total(t_3c_overl_int_gw_AO, 3)
    5518         186 :       ALLOCATE (mo_offsets(nblk_mo))
    5519         124 :       ALLOCATE (mo_bsizes(nblk_mo))
    5520         186 :       ALLOCATE (batch_range_mo(nblk_mo - 1))
    5521          62 :       CALL dbt_get_info(t_3c_overl_int_gw_AO, blk_offset_3=mo_offsets, blk_size_3=mo_bsizes)
    5522             : 
    5523          62 :       pdims_2d = 0
    5524          62 :       CALL dbt_pgrid_create(para_env, pdims_2d, pgrid_2d)
    5525         186 :       ALLOCATE (sizes_RI(dbt_nblks_total(t_3c_overl_int_gw_RI, 1)))
    5526          62 :       CALL dbt_get_info(t_3c_overl_int_gw_RI, blk_size_1=sizes_RI)
    5527             : 
    5528             :       CALL create_2c_tensor(t_W, dist1, dist2, pgrid_2d, sizes_RI, sizes_RI, name="(RI|RI)")
    5529             : 
    5530          62 :       DEALLOCATE (dist1, dist2)
    5531             : 
    5532          62 :       CALL dbt_create(mat_W, t_RI_tmp, name="(RI|RI)")
    5533             : 
    5534          62 :       CALL dbt_create(t_3c_overl_int_gw_RI, t_3c_ctr_RI)
    5535          62 :       CALL dbt_create(t_3c_overl_int_gw_AO, t_3c_ctr_AO)
    5536             : 
    5537         186 :       ALLOCATE (sizes_AO(dbt_nblks_total(t_3c_overl_int_gw_AO, 1)))
    5538          62 :       CALL dbt_get_info(t_3c_overl_int_gw_AO, blk_size_1=sizes_AO)
    5539             :       CALL create_2c_tensor(t_greens_fct_occ, dist1, dist2, pgrid_2d, sizes_AO, sizes_AO, name="(AO|AO)")
    5540          62 :       DEALLOCATE (dist1, dist2)
    5541             :       CALL create_2c_tensor(t_greens_fct_virt, dist1, dist2, pgrid_2d, sizes_AO, sizes_AO, name="(AO|AO)")
    5542          62 :       DEALLOCATE (dist1, dist2)
    5543             : 
    5544         742 :       DO jquad = 1, num_integ_points
    5545             : 
    5546             :          CALL compute_Greens_function_time(mat_greens_fct_occ, mat_greens_fct_virt, &
    5547             :                                            fm_mo_coeff_occ, fm_mo_coeff_virt, &
    5548             :                                            fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
    5549             :                                            fm_scaled_dm_occ_tau, fm_scaled_dm_virt_tau, Eigenval, &
    5550         680 :                                            nmo, eps_filter, e_fermi, tau_tj(jquad), para_env)
    5551             : 
    5552         680 :          CALL dbcsr_set(mat_W, 0.0_dp)
    5553         680 :          CALL copy_fm_to_dbcsr(fm_mat_W(jquad), mat_W, keep_sparsity=.FALSE.)
    5554             : 
    5555         680 :          IF (jquad == 1) CALL dbt_create(mat_greens_fct_occ, t_AO_tmp, name="(AO|AO)")
    5556             : 
    5557         680 :          CALL dbt_copy_matrix_to_tensor(mat_W, t_RI_tmp)
    5558         680 :          CALL dbt_copy(t_RI_tmp, t_W)
    5559         680 :          CALL dbt_copy_matrix_to_tensor(mat_greens_fct_occ, t_AO_tmp)
    5560         680 :          CALL dbt_copy(t_AO_tmp, t_greens_fct_occ)
    5561         680 :          CALL dbt_copy_matrix_to_tensor(mat_greens_fct_virt, t_AO_tmp)
    5562         680 :          CALL dbt_copy(t_AO_tmp, t_greens_fct_virt)
    5563             : 
    5564        3400 :          batch_range_mo(:) = [(i, i=2, nblk_mo)]
    5565         680 :          CALL dbt_batched_contract_init(t_3c_overl_int_gw_AO, batch_range_3=batch_range_mo)
    5566         680 :          CALL dbt_batched_contract_init(t_3c_overl_int_gw_RI, batch_range_3=batch_range_mo)
    5567         680 :          CALL dbt_batched_contract_init(t_3c_ctr_AO, batch_range_3=batch_range_mo)
    5568         680 :          CALL dbt_batched_contract_init(t_3c_ctr_RI, batch_range_3=batch_range_mo)
    5569         680 :          CALL dbt_batched_contract_init(t_W)
    5570         680 :          CALL dbt_batched_contract_init(t_greens_fct_occ)
    5571         680 :          CALL dbt_batched_contract_init(t_greens_fct_virt)
    5572             : 
    5573             :          ! in iteration over MO blocks skip first and last block because they correspond to the MO s
    5574             :          ! outside of the GW range of required MOs
    5575        1360 :          DO iblk_mo = 2, nblk_mo - 1
    5576        2040 :             mo_bounds = [mo_offsets(iblk_mo), mo_offsets(iblk_mo) + mo_bsizes(iblk_mo) - 1]
    5577             :             CALL contract_cubic_gw(t_3c_overl_int_gw_AO, t_3c_overl_int_gw_RI, &
    5578             :                                    t_greens_fct_occ, t_W, [1.0_dp, -1.0_dp], &
    5579             :                                    mo_bounds, unit_nr_prv, &
    5580         680 :                                    t_3c_ctr_RI, t_3c_ctr_AO, calculate_ctr_ri=.TRUE.)
    5581         680 :             CALL trace_sigma_gw(t_3c_ctr_AO, t_3c_ctr_RI, vec_Sigma_c_gw_neg_tau(:, jquad), mo_start, mo_bounds, para_env)
    5582             : 
    5583             :             CALL contract_cubic_gw(t_3c_overl_int_gw_AO, t_3c_overl_int_gw_RI, &
    5584             :                                    t_greens_fct_virt, t_W, [1.0_dp, 1.0_dp], &
    5585             :                                    mo_bounds, unit_nr_prv, &
    5586         680 :                                    t_3c_ctr_RI, t_3c_ctr_AO, calculate_ctr_ri=.FALSE.)
    5587             : 
    5588        1360 :             CALL trace_sigma_gw(t_3c_ctr_AO, t_3c_ctr_RI, vec_Sigma_c_gw_pos_tau(:, jquad), mo_start, mo_bounds, para_env)
    5589             :          END DO
    5590         680 :          CALL dbt_batched_contract_finalize(t_3c_overl_int_gw_AO)
    5591         680 :          CALL dbt_batched_contract_finalize(t_3c_overl_int_gw_RI)
    5592         680 :          CALL dbt_batched_contract_finalize(t_3c_ctr_AO)
    5593         680 :          CALL dbt_batched_contract_finalize(t_3c_ctr_RI)
    5594         680 :          CALL dbt_batched_contract_finalize(t_W)
    5595         680 :          CALL dbt_batched_contract_finalize(t_greens_fct_occ)
    5596         680 :          CALL dbt_batched_contract_finalize(t_greens_fct_virt)
    5597             : 
    5598         680 :          CALL dbt_clear(t_3c_ctr_AO)
    5599         680 :          CALL dbt_clear(t_3c_ctr_RI)
    5600             : 
    5601             :          vec_Sigma_c_gw_cos_tau(:, jquad) = 0.5_dp*(vec_Sigma_c_gw_pos_tau(:, jquad) + &
    5602        8320 :                                                     vec_Sigma_c_gw_neg_tau(:, jquad))
    5603             : 
    5604             :          vec_Sigma_c_gw_sin_tau(:, jquad) = 0.5_dp*(vec_Sigma_c_gw_pos_tau(:, jquad) - &
    5605        8382 :                                                     vec_Sigma_c_gw_neg_tau(:, jquad))
    5606             : 
    5607             :       END DO ! jquad (tau)
    5608          62 :       CALL dbt_destroy(t_W)
    5609             : 
    5610          62 :       CALL dbt_destroy(t_greens_fct_occ)
    5611          62 :       CALL dbt_destroy(t_greens_fct_virt)
    5612             : 
    5613             :       ! Fourier transform from time to frequency
    5614         404 :       DO jquad = 1, num_fit_points
    5615             : 
    5616        6424 :          DO iquad = 1, num_integ_points
    5617             : 
    5618        6020 :             omega = tj(jquad)
    5619        6020 :             tau = tau_tj(iquad)
    5620        6020 :             weight_cos = weights_cos_tf_t_to_w(jquad, iquad)*COS(omega*tau)
    5621        6020 :             weight_sin = weights_sin_tf_t_to_w(jquad, iquad)*SIN(omega*tau)
    5622             : 
    5623             :             vec_Sigma_c_gw_cos_omega(:, jquad) = vec_Sigma_c_gw_cos_omega(:, jquad) + &
    5624       86140 :                                                  weight_cos*vec_Sigma_c_gw_cos_tau(:, iquad)
    5625             : 
    5626             :             vec_Sigma_c_gw_sin_omega(:, jquad) = vec_Sigma_c_gw_sin_omega(:, jquad) + &
    5627       86482 :                                                  weight_sin*vec_Sigma_c_gw_sin_tau(:, iquad)
    5628             : 
    5629             :          END DO
    5630             : 
    5631             :       END DO
    5632             : 
    5633             :       ! for occupied levels, we need the correlation self-energy for negative omega. Therefore, weight_sin
    5634             :       ! should be computed with -omega, which results in an additional minus for vec_Sigma_c_gw_sin_omega:
    5635        2922 :       vec_Sigma_c_gw_sin_omega(1:gw_corr_lev_occ, :) = -vec_Sigma_c_gw_sin_omega(1:gw_corr_lev_occ, :)
    5636             : 
    5637             :       vec_Sigma_c_gw(:, 1:num_fit_points, 1) = vec_Sigma_c_gw_cos_omega(:, 1:num_fit_points) + &
    5638        4440 :                                                gaussi*vec_Sigma_c_gw_sin_omega(:, 1:num_fit_points)
    5639             : 
    5640          62 :       CALL dbcsr_release(mat_greens_fct_occ)
    5641          62 :       CALL dbcsr_release(mat_greens_fct_virt)
    5642             : 
    5643          66 :       IF (do_ri_Sigma_x .AND. count_ev_sc_GW == 1 .AND. count_sc_GW0 == 1) THEN
    5644             : 
    5645           2 :          CALL timeset(routineN//"_RI_HFX_operation_1", handle3)
    5646             : 
    5647             :          ! get density matrix
    5648             :          CALL parallel_gemm(transa="N", transb="T", m=nmo, n=nmo, k=nmo, alpha=1.0_dp, &
    5649             :                             matrix_a=fm_mo_coeff_occ, matrix_b=fm_mo_coeff_occ, beta=0.0_dp, &
    5650           2 :                             matrix_c=fm_scaled_dm_occ_tau)
    5651             : 
    5652           2 :          CALL timestop(handle3)
    5653             : 
    5654           2 :          CALL timeset(routineN//"_RI_HFX_operation_2", handle3)
    5655             : 
    5656             :          CALL copy_fm_to_dbcsr(fm_scaled_dm_occ_tau, &
    5657             :                                mat_dm%matrix, &
    5658           2 :                                keep_sparsity=.FALSE.)
    5659             : 
    5660           2 :          CALL timestop(handle3)
    5661             : 
    5662             :          CALL create_2c_tensor(t_dm, dist1, dist2, pgrid_2d, sizes_AO, sizes_AO, name="(AO|AO)")
    5663           2 :          DEALLOCATE (dist1, dist2)
    5664             : 
    5665           2 :          CALL dbt_copy_matrix_to_tensor(mat_dm%matrix, t_AO_tmp)
    5666           2 :          CALL dbt_copy(t_AO_tmp, t_dm)
    5667             : 
    5668             :          CALL create_2c_tensor(t_SinvVSinv, dist1, dist2, pgrid_2d, sizes_RI, sizes_RI, name="(RI|RI)")
    5669           2 :          DEALLOCATE (dist1, dist2)
    5670             : 
    5671           2 :          CALL dbt_copy_matrix_to_tensor(mat_MinvVMinv%matrix, t_RI_tmp)
    5672           2 :          CALL dbt_copy(t_RI_tmp, t_SinvVSinv)
    5673             : 
    5674           2 :          CALL dbt_batched_contract_init(t_3c_overl_int_gw_AO, batch_range_3=batch_range_mo)
    5675           2 :          CALL dbt_batched_contract_init(t_3c_overl_int_gw_RI, batch_range_3=batch_range_mo)
    5676           2 :          CALL dbt_batched_contract_init(t_3c_ctr_RI, batch_range_3=batch_range_mo)
    5677           2 :          CALL dbt_batched_contract_init(t_3c_ctr_AO, batch_range_3=batch_range_mo)
    5678           2 :          CALL dbt_batched_contract_init(t_dm)
    5679           2 :          CALL dbt_batched_contract_init(t_SinvVSinv)
    5680             : 
    5681           4 :          DO iblk_mo = 2, nblk_mo - 1
    5682           6 :             mo_bounds = [mo_offsets(iblk_mo), mo_offsets(iblk_mo) + mo_bsizes(iblk_mo) - 1]
    5683             : 
    5684             :             CALL contract_cubic_gw(t_3c_overl_int_gw_AO, t_3c_overl_int_gw_RI, &
    5685             :                                    t_dm, t_SinvVSinv, [1.0_dp, -1.0_dp], &
    5686             :                                    mo_bounds, unit_nr_prv, &
    5687           2 :                                    t_3c_ctr_RI, t_3c_ctr_AO, calculate_ctr_ri=.TRUE.)
    5688             : 
    5689           4 :             CALL trace_sigma_gw(t_3c_ctr_AO, t_3c_ctr_RI, vec_Sigma_x_gw(mo_start:mo_end, 1), mo_start, mo_bounds, para_env)
    5690             :          END DO
    5691           2 :          CALL dbt_batched_contract_finalize(t_3c_overl_int_gw_AO)
    5692           2 :          CALL dbt_batched_contract_finalize(t_3c_overl_int_gw_RI)
    5693           2 :          CALL dbt_batched_contract_finalize(t_dm)
    5694           2 :          CALL dbt_batched_contract_finalize(t_SinvVSinv)
    5695           2 :          CALL dbt_batched_contract_finalize(t_3c_ctr_RI)
    5696           2 :          CALL dbt_batched_contract_finalize(t_3c_ctr_AO)
    5697             : 
    5698           2 :          CALL dbt_destroy(t_dm)
    5699           2 :          CALL dbt_destroy(t_SinvVSinv)
    5700             : 
    5701             :          mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, ispin, 1) = &
    5702             :             mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, ispin, 1) + &
    5703          48 :             vec_Sigma_x_gw(:, 1)
    5704             : 
    5705             :       END IF
    5706             : 
    5707          62 :       CALL dbt_pgrid_destroy(pgrid_2d)
    5708             : 
    5709          62 :       CALL dbt_destroy(t_3c_ctr_RI)
    5710          62 :       CALL dbt_destroy(t_3c_ctr_AO)
    5711          62 :       CALL dbt_destroy(t_AO_tmp)
    5712          62 :       CALL dbt_destroy(t_RI_tmp)
    5713             : 
    5714             :       ! compute and add the periodic correction
    5715          62 :       IF (do_periodic) THEN
    5716             : 
    5717           4 :          ext_scaling = 0.2_dp
    5718             : 
    5719             :          ! loop over omega' (integration)
    5720          24 :          DO iquad = 1, num_points_corr
    5721             : 
    5722             :             ! use the Clenshaw-grid
    5723          20 :             t_i_Clenshaw = iquad*pi/(2.0_dp*num_points_corr)
    5724          20 :             omega_i = ext_scaling/TAN(t_i_Clenshaw)
    5725             : 
    5726          20 :             IF (iquad < num_points_corr) THEN
    5727          16 :                weight_i = ext_scaling*pi/(num_points_corr*SIN(t_i_Clenshaw)**2)
    5728             :             ELSE
    5729           4 :                weight_i = ext_scaling*pi/(2.0_dp*num_points_corr*SIN(t_i_Clenshaw)**2)
    5730             :             END IF
    5731             : 
    5732             :             CALL calc_periodic_correction(delta_corr, qs_env, para_env, para_env_RPA, &
    5733             :                                           mp2_env%ri_g0w0%kp_grid, homo, nmo, gw_corr_lev_occ, &
    5734             :                                           gw_corr_lev_virt, omega_i, fm_mo_coeff, Eigenval, &
    5735             :                                           matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
    5736             :                                           first_cycle_periodic_correction, kpoints, &
    5737             :                                           mp2_env%ri_g0w0%do_mo_coeff_gamma, &
    5738             :                                           mp2_env%ri_g0w0%num_kp_grids, mp2_env%ri_g0w0%eps_kpoint, &
    5739             :                                           mp2_env%ri_g0w0%do_extra_kpoints, &
    5740          20 :                                           mp2_env%ri_g0w0%do_aux_bas_gw, mp2_env%ri_g0w0%frac_aux_mos)
    5741             : 
    5742         204 :             DO n_level_gw = 1, gw_corr_lev_tot
    5743             : 
    5744         180 :                n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
    5745             : 
    5746         180 :                IF (n_level_gw <= gw_corr_lev_occ) THEN
    5747             :                   sign_occ_virt = -1.0_dp
    5748             :                ELSE
    5749         100 :                   sign_occ_virt = 1.0_dp
    5750             :                END IF
    5751             : 
    5752        2000 :                DO jquad = 1, num_integ_points
    5753             : 
    5754        1800 :                   omega_sign = tj(jquad)*sign_occ_virt
    5755             : 
    5756             :                   delta_corr_omega(n_level_gw_ref, jquad) = &
    5757             :                      delta_corr_omega(n_level_gw_ref, jquad) - &
    5758             :                      0.5_dp/pi*weight_i/2.0_dp*delta_corr(n_level_gw_ref)* &
    5759             :                      (1.0_dp/(gaussi*(omega_i + omega_sign) + e_fermi - Eigenval(n_level_gw_ref)) + &
    5760        1980 :                       1.0_dp/(gaussi*(-omega_i + omega_sign) + e_fermi - Eigenval(n_level_gw_ref)))
    5761             : 
    5762             :                END DO
    5763             : 
    5764             :             END DO
    5765             : 
    5766             :          END DO
    5767             : 
    5768           4 :          gw_lev_start = 1 + homo - gw_corr_lev_occ
    5769           4 :          gw_lev_end = homo + gw_corr_lev_virt
    5770             : 
    5771             :          ! add the periodic correction
    5772             :          vec_Sigma_c_gw(1:gw_corr_lev_tot, :, 1) = vec_Sigma_c_gw(1:gw_corr_lev_tot, :, 1) + &
    5773         164 :                                                    delta_corr_omega(gw_lev_start:gw_lev_end, 1:num_fit_points)
    5774             : 
    5775             :       END IF
    5776             : 
    5777          62 :       DEALLOCATE (vec_Sigma_c_gw_pos_tau)
    5778          62 :       DEALLOCATE (vec_Sigma_c_gw_neg_tau)
    5779          62 :       DEALLOCATE (vec_Sigma_c_gw_cos_tau)
    5780          62 :       DEALLOCATE (vec_Sigma_c_gw_sin_tau)
    5781          62 :       DEALLOCATE (vec_Sigma_c_gw_cos_omega)
    5782          62 :       DEALLOCATE (vec_Sigma_c_gw_sin_omega)
    5783          62 :       DEALLOCATE (delta_corr_omega)
    5784             : 
    5785          62 :       CALL timestop(handle)
    5786             : 
    5787         372 :    END SUBROUTINE compute_self_energy_cubic_gw
    5788             : 
    5789             : ! **************************************************************************************************
    5790             : !> \brief ...
    5791             : !> \param num_integ_points ...
    5792             : !> \param tau_tj ...
    5793             : !> \param tj ...
    5794             : !> \param matrix_s ...
    5795             : !> \param Eigenval ...
    5796             : !> \param e_fermi ...
    5797             : !> \param fm_mat_W ...
    5798             : !> \param gw_corr_lev_tot ...
    5799             : !> \param gw_corr_lev_occ ...
    5800             : !> \param gw_corr_lev_virt ...
    5801             : !> \param homo ...
    5802             : !> \param count_ev_sc_GW ...
    5803             : !> \param count_sc_GW0 ...
    5804             : !> \param t_3c_O ...
    5805             : !> \param t_3c_M ...
    5806             : !> \param t_3c_O_compressed ...
    5807             : !> \param t_3c_O_ind ...
    5808             : !> \param mat_W ...
    5809             : !> \param mat_MinvVMinv ...
    5810             : !> \param weights_cos_tf_t_to_w ...
    5811             : !> \param weights_sin_tf_t_to_w ...
    5812             : !> \param vec_Sigma_c_gw ...
    5813             : !> \param qs_env ...
    5814             : !> \param para_env ...
    5815             : !> \param mp2_env ...
    5816             : !> \param num_fit_points ...
    5817             : !> \param fm_mo_coeff ...
    5818             : !> \param do_ri_Sigma_x ...
    5819             : !> \param vec_Sigma_x_gw ...
    5820             : !> \param unit_nr ...
    5821             : !> \param nspins ...
    5822             : !> \param starts_array_mc ...
    5823             : !> \param ends_array_mc ...
    5824             : !> \param eps_filter ...
    5825             : ! **************************************************************************************************
    5826          18 :    SUBROUTINE compute_self_energy_cubic_gw_kpoints(num_integ_points, tau_tj, tj, &
    5827          18 :                                                    matrix_s, Eigenval, e_fermi, fm_mat_W, &
    5828          18 :                                                    gw_corr_lev_tot, gw_corr_lev_occ, gw_corr_lev_virt, homo, &
    5829             :                                                    count_ev_sc_GW, count_sc_GW0, &
    5830             :                                                    t_3c_O, t_3c_M, t_3c_O_compressed, t_3c_O_ind, &
    5831             :                                                    mat_W, mat_MinvVMinv, &
    5832          36 :                                                    weights_cos_tf_t_to_w, weights_sin_tf_t_to_w, vec_Sigma_c_gw, &
    5833             :                                                    qs_env, para_env, &
    5834             :                                                    mp2_env, num_fit_points, fm_mo_coeff, &
    5835          18 :                                                    do_ri_Sigma_x, vec_Sigma_x_gw, unit_nr, nspins, &
    5836          18 :                                                    starts_array_mc, ends_array_mc, eps_filter)
    5837             : 
    5838             :       INTEGER, INTENT(IN)                                :: num_integ_points
    5839             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
    5840             :          INTENT(IN)                                      :: tau_tj, tj
    5841             :       TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN)       :: matrix_s
    5842             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: Eigenval
    5843             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: e_fermi
    5844             :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: fm_mat_W
    5845             :       INTEGER, INTENT(IN)                                :: gw_corr_lev_tot
    5846             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: gw_corr_lev_occ, gw_corr_lev_virt, homo
    5847             :       INTEGER, INTENT(IN)                                :: count_ev_sc_GW, count_sc_GW0
    5848             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_3c_O
    5849             :       TYPE(dbt_type)                                     :: t_3c_M
    5850             :       TYPE(hfx_compression_type), ALLOCATABLE, &
    5851             :          DIMENSION(:, :, :)                              :: t_3c_O_compressed
    5852             :       TYPE(block_ind_type), ALLOCATABLE, &
    5853             :          DIMENSION(:, :, :), INTENT(INOUT)               :: t_3c_O_ind
    5854             :       TYPE(dbcsr_type), INTENT(INOUT), TARGET            :: mat_W
    5855             :       TYPE(dbcsr_p_type)                                 :: mat_MinvVMinv
    5856             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: weights_cos_tf_t_to_w, &
    5857             :                                                             weights_sin_tf_t_to_w
    5858             :       COMPLEX(KIND=dp), DIMENSION(:, :, :, :), &
    5859             :          INTENT(OUT)                                     :: vec_Sigma_c_gw
    5860             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    5861             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    5862             :       TYPE(mp2_type), INTENT(INOUT)                      :: mp2_env
    5863             :       INTEGER, INTENT(IN)                                :: num_fit_points
    5864             :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mo_coeff
    5865             :       LOGICAL, INTENT(IN)                                :: do_ri_Sigma_x
    5866             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT)   :: vec_Sigma_x_gw
    5867             :       INTEGER, INTENT(IN)                                :: unit_nr, nspins
    5868             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: starts_array_mc, ends_array_mc
    5869             :       REAL(KIND=dp), INTENT(IN)                          :: eps_filter
    5870             : 
    5871             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_self_energy_cubic_gw_kpoints'
    5872             : 
    5873             :       INTEGER                                            :: cut_memory, handle, handle2, i_mem, &
    5874             :                                                             iquad, ispin, j_mem, jquad, &
    5875             :                                                             nkp_self_energy, num_points, &
    5876             :                                                             unit_nr_prv
    5877          36 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: dist1, dist2, sizes_AO, sizes_RI
    5878             :       INTEGER, DIMENSION(2)                              :: mo_end, mo_start, pdims_2d
    5879             :       INTEGER, DIMENSION(2, 1)                           :: bounds_RI_i
    5880             :       INTEGER, DIMENSION(2, 2)                           :: bounds_ao_ao_j
    5881             :       INTEGER, DIMENSION(3)                              :: dims_3c
    5882             :       LOGICAL                                            :: memory_info
    5883             :       REAL(KIND=dp)                                      :: omega, t1, t2, tau, weight_cos, &
    5884             :                                                             weight_sin
    5885          18 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: vec_Sigma_c_gw_cos_omega, &
    5886          18 :          vec_Sigma_c_gw_cos_tau, vec_Sigma_c_gw_neg_tau, vec_Sigma_c_gw_pos_tau, &
    5887          18 :          vec_Sigma_c_gw_sin_omega, vec_Sigma_c_gw_sin_tau
    5888          18 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: mat_p_greens_fct_occ, &
    5889          18 :                                                             mat_p_greens_fct_virt
    5890             :       TYPE(dbcsr_type), TARGET :: mat_greens_fct_occ, mat_greens_fct_virt, mat_mo_coeff, &
    5891             :          mat_self_energy_ao_ao_neg_tau, mat_self_energy_ao_ao_pos_tau
    5892          54 :       TYPE(dbt_pgrid_type)                               :: pgrid_2d
    5893         342 :       TYPE(dbt_type)                                     :: t_3c_M_W_tmp, t_3c_O_all, t_3c_O_W, &
    5894         234 :                                                             t_AO_tmp, t_greens_fct_occ, &
    5895         342 :                                                             t_greens_fct_virt, t_RI_tmp, t_W
    5896             : 
    5897          18 :       CALL timeset(routineN, handle)
    5898             : 
    5899          18 :       memory_info = mp2_env%ri_rpa_im_time%memory_info
    5900          18 :       IF (memory_info) THEN
    5901           0 :          unit_nr_prv = unit_nr
    5902             :       ELSE
    5903          18 :          unit_nr_prv = 0
    5904             :       END IF
    5905             : 
    5906          18 :       cut_memory = mp2_env%ri_rpa_im_time%cut_memory
    5907             : 
    5908          40 :       DO ispin = 1, nspins
    5909          22 :          mo_start(ispin) = homo(ispin) - gw_corr_lev_occ(ispin) + 1
    5910          22 :          mo_end(ispin) = homo(ispin) + gw_corr_lev_virt(ispin)
    5911          40 :          CPASSERT(mo_end(ispin) - mo_start(ispin) + 1 == gw_corr_lev_tot)
    5912             :       END DO
    5913             : 
    5914          18 :       nkp_self_energy = mp2_env%ri_g0w0%nkp_self_energy
    5915             : 
    5916        1672 :       vec_Sigma_c_gw = z_zero
    5917         108 :       ALLOCATE (vec_Sigma_c_gw_pos_tau(gw_corr_lev_tot, num_integ_points, nkp_self_energy, nspins))
    5918        3232 :       vec_Sigma_c_gw_pos_tau = 0.0_dp
    5919          90 :       ALLOCATE (vec_Sigma_c_gw_neg_tau(gw_corr_lev_tot, num_integ_points, nkp_self_energy, nspins))
    5920        3232 :       vec_Sigma_c_gw_neg_tau = 0.0_dp
    5921          90 :       ALLOCATE (vec_Sigma_c_gw_cos_tau(gw_corr_lev_tot, num_integ_points, nkp_self_energy, nspins))
    5922        3232 :       vec_Sigma_c_gw_cos_tau = 0.0_dp
    5923          90 :       ALLOCATE (vec_Sigma_c_gw_sin_tau(gw_corr_lev_tot, num_integ_points, nkp_self_energy, nspins))
    5924        3232 :       vec_Sigma_c_gw_sin_tau = 0.0_dp
    5925             : 
    5926          90 :       ALLOCATE (vec_Sigma_c_gw_cos_omega(gw_corr_lev_tot, num_integ_points, nkp_self_energy, nspins))
    5927        3232 :       vec_Sigma_c_gw_cos_omega = 0.0_dp
    5928          90 :       ALLOCATE (vec_Sigma_c_gw_sin_omega(gw_corr_lev_tot, num_integ_points, nkp_self_energy, nspins))
    5929        3232 :       vec_Sigma_c_gw_sin_omega = 0.0_dp
    5930             : 
    5931             :       CALL dbcsr_create(matrix=mat_greens_fct_occ, &
    5932             :                         template=matrix_s(1)%matrix, &
    5933          18 :                         matrix_type=dbcsr_type_no_symmetry)
    5934             : 
    5935             :       CALL dbcsr_create(matrix=mat_greens_fct_virt, &
    5936             :                         template=matrix_s(1)%matrix, &
    5937          18 :                         matrix_type=dbcsr_type_no_symmetry)
    5938             : 
    5939             :       CALL dbcsr_create(matrix=mat_self_energy_ao_ao_neg_tau, &
    5940             :                         template=matrix_s(1)%matrix, &
    5941          18 :                         matrix_type=dbcsr_type_no_symmetry)
    5942             : 
    5943             :       CALL dbcsr_create(matrix=mat_self_energy_ao_ao_pos_tau, &
    5944             :                         template=matrix_s(1)%matrix, &
    5945          18 :                         matrix_type=dbcsr_type_no_symmetry)
    5946             : 
    5947             :       CALL dbcsr_create(matrix=mat_mo_coeff, &
    5948             :                         template=matrix_s(1)%matrix, &
    5949          18 :                         matrix_type=dbcsr_type_no_symmetry)
    5950             : 
    5951          18 :       CALL copy_fm_to_dbcsr(fm_mo_coeff, mat_mo_coeff, keep_sparsity=.FALSE.)
    5952             : 
    5953          40 :       DO ispin = 1, nspins
    5954         870 :          e_fermi(ispin) = 0.5_dp*(MAXVAL(Eigenval(homo, :, ispin)) + MINVAL(Eigenval(homo + 1, :, ispin)))
    5955             :       END DO
    5956             : 
    5957          18 :       pdims_2d = 0
    5958          18 :       CALL dbt_pgrid_create(para_env, pdims_2d, pgrid_2d)
    5959          54 :       ALLOCATE (sizes_RI(dbt_nblks_total(t_3c_O(1, 1), 1)))
    5960          18 :       CALL dbt_get_info(t_3c_O(1, 1), blk_size_1=sizes_RI)
    5961             : 
    5962          18 :       CALL create_2c_tensor(t_W, dist1, dist2, pgrid_2d, sizes_RI, sizes_RI, name="(RI|RI)")
    5963          18 :       DEALLOCATE (dist1, dist2)
    5964             : 
    5965          18 :       CALL dbt_create(mat_W, t_RI_tmp, name="(RI|RI)")
    5966             : 
    5967          54 :       ALLOCATE (sizes_AO(dbt_nblks_total(t_3c_O(1, 1), 2)))
    5968          18 :       CALL dbt_get_info(t_3c_O(1, 1), blk_size_2=sizes_AO)
    5969             :       CALL create_2c_tensor(t_greens_fct_occ, dist1, dist2, pgrid_2d, sizes_AO, sizes_AO, name="(AO|AO)")
    5970             : 
    5971          18 :       DEALLOCATE (dist1, dist2)
    5972             :       CALL create_2c_tensor(t_greens_fct_virt, dist1, dist2, pgrid_2d, sizes_AO, sizes_AO, name="(AO|AO)")
    5973          18 :       DEALLOCATE (dist1, dist2)
    5974             : 
    5975          18 :       CALL dbt_get_info(t_3c_M, nfull_total=dims_3c)
    5976             : 
    5977          18 :       CALL dbt_create(t_3c_O(1, 1), t_3c_O_all, name="O (RI AO | AO)")
    5978             : 
    5979             :       ! get full 3c tensor
    5980          82 :       DO i_mem = 1, cut_memory
    5981             :          CALL decompress_tensor(t_3c_O(1, 1), &
    5982             :                                 t_3c_O_ind(1, 1, i_mem)%ind, &
    5983             :                                 t_3c_O_compressed(1, 1, i_mem), &
    5984          64 :                                 mp2_env%ri_rpa_im_time%eps_compress)
    5985          82 :          CALL dbt_copy(t_3c_O(1, 1), t_3c_O_all, summation=.TRUE., move_data=.TRUE.)
    5986             :       END DO
    5987             : 
    5988          18 :       CALL dbt_create(t_3c_M, t_3c_M_W_tmp, name="M W (RI | AO AO)")
    5989          18 :       CALL dbt_create(t_3c_O(1, 1), t_3c_O_W, name="M W (RI AO | AO)")
    5990             : 
    5991          18 :       CALL dbt_create(mat_greens_fct_occ, t_AO_tmp, name="(AO|AO)")
    5992             : 
    5993          18 :       IF (count_ev_sc_GW == 1 .AND. count_sc_GW0 == 1 .AND. do_ri_Sigma_x) THEN
    5994          14 :          num_points = num_integ_points + 1
    5995             :       ELSE
    5996           4 :          num_points = num_integ_points
    5997             :       END IF
    5998             : 
    5999         140 :       DO jquad = 1, num_points
    6000             : 
    6001         122 :          t1 = m_walltime()
    6002             : 
    6003         122 :          IF (jquad <= num_integ_points) THEN
    6004         108 :             tau = tau_tj(jquad)
    6005             : 
    6006         108 :             IF (unit_nr > 0) WRITE (unit_nr, '(/T3,A,1X,I3)') &
    6007          54 :                'GW_INFO| Computing self-energy time point', jquad
    6008             :          ELSE
    6009          14 :             tau = 0.0_dp
    6010             : 
    6011          14 :             IF (unit_nr > 0) WRITE (unit_nr, '(/T3,A,1X,I3)') &
    6012           7 :                'GW_INFO| Computing exchange self-energy'
    6013             :          END IF
    6014             : 
    6015         122 :          IF (jquad <= num_integ_points) THEN
    6016         108 :             CALL dbcsr_set(mat_W, 0.0_dp)
    6017         108 :             CALL copy_fm_to_dbcsr(fm_mat_W(jquad), mat_W, keep_sparsity=.FALSE.)
    6018         108 :             CALL dbt_copy_matrix_to_tensor(mat_W, t_RI_tmp)
    6019             :          ELSE
    6020          14 :             CALL dbt_copy_matrix_to_tensor(mat_MinvVMinv%matrix, t_RI_tmp)
    6021             :          END IF
    6022             : 
    6023         122 :          CALL dbt_copy(t_RI_tmp, t_W)
    6024             : 
    6025         272 :          DO ispin = 1, nspins
    6026             : 
    6027             :             CALL compute_periodic_dm(mat_p_greens_fct_occ, qs_env, &
    6028             :                                      ispin, num_points, jquad, e_fermi(ispin), tau, &
    6029             :                                      remove_occ=.FALSE., remove_virt=.TRUE., &
    6030         282 :                                      alloc_dm=(jquad == 1 .AND. ispin == 1))
    6031             : 
    6032             :             CALL compute_periodic_dm(mat_p_greens_fct_virt, qs_env, &
    6033             :                                      ispin, num_points, jquad, e_fermi(ispin), tau, &
    6034             :                                      remove_occ=.TRUE., remove_virt=.FALSE., &
    6035         282 :                                      alloc_dm=(jquad == 1 .AND. ispin == 1))
    6036             : 
    6037         150 :             CALL dbcsr_set(mat_greens_fct_occ, 0.0_dp)
    6038         150 :             CALL dbcsr_copy(mat_greens_fct_occ, mat_p_greens_fct_occ(jquad, 1)%matrix)
    6039             : 
    6040         150 :             CALL dbcsr_set(mat_greens_fct_virt, 0.0_dp)
    6041         150 :             CALL dbcsr_copy(mat_greens_fct_virt, mat_p_greens_fct_virt(jquad, 1)%matrix)
    6042             : 
    6043         150 :             CALL dbt_copy_matrix_to_tensor(mat_greens_fct_occ, t_AO_tmp)
    6044         150 :             CALL dbt_copy(t_AO_tmp, t_greens_fct_occ)
    6045             : 
    6046         150 :             CALL dbt_copy_matrix_to_tensor(mat_greens_fct_virt, t_AO_tmp)
    6047         150 :             CALL dbt_copy(t_AO_tmp, t_greens_fct_virt)
    6048             : 
    6049         150 :             CALL dbcsr_set(mat_self_energy_ao_ao_neg_tau, 0.0_dp)
    6050         150 :             CALL dbcsr_set(mat_self_energy_ao_ao_pos_tau, 0.0_dp)
    6051             : 
    6052         150 :             CALL dbt_copy(t_3c_O_all, t_3c_M)
    6053             : 
    6054         150 :             CALL dbt_batched_contract_init(t_3c_O_W)
    6055             :             !         CALL dbt_batched_contract_init(t_3c_O_G)
    6056             :             !         CALL dbt_batched_contract_init(t_self_energy)
    6057             : 
    6058         666 :             DO i_mem = 1, cut_memory ! memory cut for RI index
    6059             : 
    6060             :                !            CALL dbt_batched_contract_init(t_W)
    6061             :                !            CALL dbt_batched_contract_init(t_3c_M)
    6062             :                !            CALL dbt_batched_contract_init(t_3c_M_W_tmp)
    6063             : 
    6064             :                bounds_RI_i(:, 1) = [qs_env%mp2_env%ri_rpa_im_time%starts_array_mc_RI(i_mem), &
    6065        1548 :                                     qs_env%mp2_env%ri_rpa_im_time%ends_array_mc_RI(i_mem)]
    6066             : 
    6067        2506 :                DO j_mem = 1, cut_memory ! memory cut for ao index
    6068             : 
    6069        5520 :                   bounds_ao_ao_j(:, 1) = [starts_array_mc(j_mem), ends_array_mc(j_mem)]
    6070        5520 :                   bounds_ao_ao_j(:, 2) = [1, dims_3c(3)]
    6071             : 
    6072        1840 :                   CALL timeset("tensor_operation_3c_W", handle2)
    6073             : 
    6074             :                   CALL dbt_contract(1.0_dp, t_W, t_3c_M, 0.0_dp, &
    6075             :                                     t_3c_M_W_tmp, &
    6076             :                                     contract_1=[2], notcontract_1=[1], &
    6077             :                                     contract_2=[1], notcontract_2=[2, 3], &
    6078             :                                     map_1=[1], map_2=[2, 3], &
    6079             :                                     bounds_2=bounds_RI_i, &
    6080             :                                     bounds_3=bounds_ao_ao_j, &
    6081             :                                     filter_eps=eps_filter, &
    6082        1840 :                                     unit_nr=unit_nr_prv)
    6083             : 
    6084        1840 :                   CALL dbt_copy(t_3c_M_W_tmp, t_3c_O_W, order=[1, 2, 3], move_data=.TRUE.)
    6085             : 
    6086        1840 :                   CALL timestop(handle2)
    6087             : 
    6088             :                   CALL contract_to_self_energy(t_3c_O_all, t_greens_fct_occ, t_3c_O_W, &
    6089             :                                                mat_self_energy_ao_ao_neg_tau, &
    6090             :                                                bounds_ao_ao_j, bounds_RI_i, unit_nr_prv, &
    6091        1840 :                                                eps_filter, do_occ=.TRUE., do_virt=.FALSE.)
    6092             : 
    6093             :                   CALL contract_to_self_energy(t_3c_O_all, t_greens_fct_virt, t_3c_O_W, &
    6094             :                                                mat_self_energy_ao_ao_pos_tau, &
    6095             :                                                bounds_ao_ao_j, bounds_RI_i, unit_nr_prv, &
    6096        4196 :                                                eps_filter, do_occ=.FALSE., do_virt=.TRUE.)
    6097             : 
    6098             :                END DO ! j_mem
    6099             : 
    6100             :                !            CALL dbt_batched_contract_finalize(t_W)
    6101             :                !            CALL dbt_batched_contract_finalize(t_3c_M)
    6102             :                !            CALL dbt_batched_contract_finalize(t_3c_M_W_tmp)
    6103             : 
    6104             :             END DO ! i_mem
    6105             : 
    6106         150 :             CALL dbt_batched_contract_finalize(t_3c_O_W)
    6107             :             !         CALL dbt_batched_contract_finalize(t_3c_O_G)
    6108             :             !         CALL dbt_batched_contract_finalize(t_self_energy)
    6109             : 
    6110         272 :             IF (jquad <= num_integ_points) THEN
    6111             : 
    6112             :                CALL trafo_to_mo_and_kpoints(qs_env, mat_self_energy_ao_ao_neg_tau, vec_Sigma_c_gw_neg_tau(:, jquad, :, ispin), &
    6113         132 :                                             homo(ispin), gw_corr_lev_occ(ispin), gw_corr_lev_virt(ispin), ispin)
    6114             : 
    6115             :                CALL trafo_to_mo_and_kpoints(qs_env, mat_self_energy_ao_ao_pos_tau, vec_Sigma_c_gw_pos_tau(:, jquad, :, ispin), &
    6116         132 :                                             homo(ispin), gw_corr_lev_occ(ispin), gw_corr_lev_virt(ispin), ispin)
    6117             : 
    6118             :                vec_Sigma_c_gw_cos_tau(:, jquad, :, ispin) = 0.5_dp*(vec_Sigma_c_gw_pos_tau(:, jquad, :, ispin) + &
    6119        3156 :                                                                     vec_Sigma_c_gw_neg_tau(:, jquad, :, ispin))
    6120             : 
    6121             :                vec_Sigma_c_gw_sin_tau(:, jquad, :, ispin) = 0.5_dp*(vec_Sigma_c_gw_pos_tau(:, jquad, :, ispin) - &
    6122        3156 :                                                                     vec_Sigma_c_gw_neg_tau(:, jquad, :, ispin))
    6123             :             ELSE
    6124             : 
    6125             :                CALL trafo_to_mo_and_kpoints(qs_env, mat_self_energy_ao_ao_neg_tau, &
    6126             :                                             vec_Sigma_x_gw(mo_start(ispin):mo_end(ispin), :, ispin), &
    6127          18 :                                             homo(ispin), gw_corr_lev_occ(ispin), gw_corr_lev_virt(ispin), ispin)
    6128             : 
    6129             :             END IF
    6130             : 
    6131             :          END DO ! spins
    6132             : 
    6133         122 :          t2 = m_walltime()
    6134             : 
    6135         140 :          IF (unit_nr > 0) WRITE (unit_nr, '(T6,A,T56,F25.1)') 'Execution time (s):', t2 - t1
    6136             : 
    6137             :       END DO ! jquad (tau)
    6138             : 
    6139          18 :       IF (count_ev_sc_GW == 1 .AND. count_sc_GW0 == 1) THEN
    6140             : 
    6141          18 :          CALL compute_minus_vxc_kpoints(qs_env)
    6142             : 
    6143          18 :          IF (do_ri_Sigma_x) THEN
    6144          32 :             DO ispin = 1, nspins
    6145             :                mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, ispin, :) = mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, ispin, :) + &
    6146        2672 :                                                                        vec_Sigma_x_gw(:, :, ispin)
    6147             :             END DO
    6148             :          END IF
    6149             : 
    6150             :       END IF
    6151             : 
    6152             :       ! Fourier transform from time to frequency
    6153          70 :       DO jquad = 1, num_fit_points
    6154             : 
    6155         382 :          DO iquad = 1, num_integ_points
    6156             : 
    6157         312 :             omega = tj(jquad)
    6158         312 :             tau = tau_tj(iquad)
    6159         312 :             weight_cos = weights_cos_tf_t_to_w(jquad, iquad)*COS(omega*tau)
    6160         312 :             weight_sin = weights_sin_tf_t_to_w(jquad, iquad)*SIN(omega*tau)
    6161             : 
    6162             :             vec_Sigma_c_gw_cos_omega(:, jquad, :, :) = vec_Sigma_c_gw_cos_omega(:, jquad, :, :) + &
    6163        9480 :                                                        weight_cos*vec_Sigma_c_gw_cos_tau(:, iquad, :, :)
    6164             : 
    6165             :             vec_Sigma_c_gw_sin_omega(:, jquad, :, :) = vec_Sigma_c_gw_sin_omega(:, jquad, :, :) + &
    6166        9532 :                                                        weight_sin*vec_Sigma_c_gw_sin_tau(:, iquad, :, :)
    6167             : 
    6168             :          END DO
    6169             : 
    6170             :       END DO
    6171             : 
    6172             :       ! for occupied levels, we need the correlation self-energy for negative omega. Therefore, weight_sin
    6173             :       ! should be computed with -omega, which results in an additional minus for vec_Sigma_c_gw_sin_omega:
    6174          40 :       DO ispin = 1, nspins
    6175             :          vec_Sigma_c_gw_sin_omega(1:gw_corr_lev_occ(ispin), :, :, ispin) = &
    6176        2224 :             -vec_Sigma_c_gw_sin_omega(1:gw_corr_lev_occ(ispin), :, :, ispin)
    6177             :       END DO
    6178             : 
    6179             :       vec_Sigma_c_gw(:, 1:num_fit_points, :, :) = vec_Sigma_c_gw_cos_omega(:, 1:num_fit_points, :, :) + &
    6180        1672 :                                                   gaussi*vec_Sigma_c_gw_sin_omega(:, 1:num_fit_points, :, :)
    6181             : 
    6182          18 :       CALL dbt_pgrid_destroy(pgrid_2d)
    6183             : 
    6184          18 :       CALL dbcsr_release(mat_greens_fct_occ)
    6185          18 :       CALL dbcsr_release(mat_greens_fct_virt)
    6186          18 :       CALL dbcsr_release(mat_self_energy_ao_ao_neg_tau)
    6187          18 :       CALL dbcsr_release(mat_self_energy_ao_ao_pos_tau)
    6188          18 :       CALL dbcsr_release(mat_mo_coeff)
    6189             : 
    6190          18 :       CALL dbcsr_deallocate_matrix_set(mat_p_greens_fct_occ)
    6191          18 :       CALL dbcsr_deallocate_matrix_set(mat_p_greens_fct_virt)
    6192             : 
    6193          18 :       CALL dbt_destroy(t_W)
    6194          18 :       CALL dbt_destroy(t_RI_tmp)
    6195          18 :       CALL dbt_destroy(t_greens_fct_occ)
    6196          18 :       CALL dbt_destroy(t_greens_fct_virt)
    6197          18 :       CALL dbt_destroy(t_AO_tmp)
    6198          18 :       CALL dbt_destroy(t_3c_O_all)
    6199          18 :       CALL dbt_destroy(t_3c_M_W_tmp)
    6200          18 :       CALL dbt_destroy(t_3c_O_W)
    6201             : 
    6202          18 :       DEALLOCATE (vec_Sigma_c_gw_pos_tau)
    6203          18 :       DEALLOCATE (vec_Sigma_c_gw_neg_tau)
    6204          18 :       DEALLOCATE (vec_Sigma_c_gw_cos_tau)
    6205          18 :       DEALLOCATE (vec_Sigma_c_gw_sin_tau)
    6206          18 :       DEALLOCATE (vec_Sigma_c_gw_cos_omega)
    6207          18 :       DEALLOCATE (vec_Sigma_c_gw_sin_omega)
    6208             : 
    6209          18 :       CALL timestop(handle)
    6210             : 
    6211         108 :    END SUBROUTINE compute_self_energy_cubic_gw_kpoints
    6212             : 
    6213             : ! **************************************************************************************************
    6214             : !> \brief ...
    6215             : !> \param qs_env ...
    6216             : ! **************************************************************************************************
    6217          18 :    SUBROUTINE compute_minus_vxc_kpoints(qs_env)
    6218             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    6219             : 
    6220             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_minus_vxc_kpoints'
    6221             : 
    6222             :       INTEGER                                            :: handle, ikp, ispin, nkp_self_energy, &
    6223             :                                                             nmo, nspins
    6224             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: diag_Sigma_x_minus_vxc_mo_mo
    6225             :       TYPE(cp_cfm_type)                                  :: cfm_mo_coeff, ks_mat_ao_ao, &
    6226             :                                                             ks_mat_no_xc_ao_ao, vxc_ao_ao, &
    6227             :                                                             vxc_ao_mo, vxc_mo_mo
    6228             :       TYPE(cp_fm_struct_type), POINTER                   :: matrix_struct
    6229             :       TYPE(cp_fm_type)                                   :: fm_dummy, fm_Sigma_x_minus_vxc_mo_mo, &
    6230             :                                                             fm_tmp_im, fm_tmp_re
    6231             :       TYPE(dft_control_type), POINTER                    :: dft_control
    6232             :       TYPE(kpoint_type), POINTER                         :: kpoints_Sigma, kpoints_Sigma_no_xc
    6233             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    6234             : 
    6235          18 :       CALL timeset(routineN, handle)
    6236             : 
    6237          18 :       CALL get_qs_env(qs_env, para_env=para_env, dft_control=dft_control)
    6238             : 
    6239          18 :       kpoints_Sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
    6240             : 
    6241          18 :       kpoints_Sigma_no_xc => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma_no_xc
    6242             : 
    6243          18 :       nkp_self_energy = kpoints_Sigma%nkp
    6244             : 
    6245          18 :       nspins = dft_control%nspins
    6246             : 
    6247          18 :       matrix_struct => kpoints_Sigma%kp_env(1)%kpoint_env%wmat(1, 1)%matrix_struct
    6248             : 
    6249          18 :       CALL cp_cfm_create(ks_mat_ao_ao, matrix_struct)
    6250          18 :       CALL cp_cfm_create(ks_mat_no_xc_ao_ao, matrix_struct)
    6251          18 :       CALL cp_cfm_create(vxc_ao_ao, matrix_struct)
    6252          18 :       CALL cp_cfm_create(vxc_ao_mo, matrix_struct)
    6253          18 :       CALL cp_cfm_create(vxc_mo_mo, matrix_struct)
    6254          18 :       CALL cp_cfm_create(cfm_mo_coeff, matrix_struct)
    6255          18 :       CALL cp_fm_create(fm_Sigma_x_minus_vxc_mo_mo, matrix_struct)
    6256          18 :       CALL cp_fm_create(fm_tmp_re, matrix_struct)
    6257          18 :       CALL cp_fm_create(fm_tmp_im, matrix_struct)
    6258             : 
    6259          18 :       CALL cp_cfm_get_info(cfm_mo_coeff, nrow_global=nmo)
    6260          54 :       ALLOCATE (diag_Sigma_x_minus_vxc_mo_mo(nmo))
    6261             : 
    6262          18 :       DEALLOCATE (qs_env%mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw)
    6263             : 
    6264          72 :       ALLOCATE (qs_env%mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(nmo, 2, nkp_self_energy))
    6265             : 
    6266         154 :       DO ikp = 1, nkp_self_energy
    6267             : 
    6268         322 :          DO ispin = 1, nspins
    6269             : 
    6270             :             ASSOCIATE (mos => kpoints_Sigma%kp_env(ikp)%kpoint_env%mos)
    6271         168 :             IF (ASSOCIATED(mos(1, ispin)%mo_coeff)) THEN
    6272         168 :                CALL cp_fm_copy_general(mos(1, ispin)%mo_coeff, fm_tmp_re, para_env)
    6273             :             ELSE
    6274           0 :                CALL cp_fm_copy_general(fm_dummy, fm_tmp_re, para_env)
    6275             :             END IF
    6276         336 :             IF (ASSOCIATED(mos(2, ispin)%mo_coeff)) THEN
    6277         168 :                CALL cp_fm_copy_general(mos(2, ispin)%mo_coeff, fm_tmp_im, para_env)
    6278             :             ELSE
    6279           0 :                CALL cp_fm_copy_general(fm_dummy, fm_tmp_im, para_env)
    6280             :             END IF
    6281             :             END ASSOCIATE
    6282             : 
    6283         168 :             CALL cp_fm_to_cfm(fm_tmp_re, fm_tmp_im, cfm_mo_coeff)
    6284             : 
    6285             :             CALL cp_fm_to_cfm(kpoints_Sigma%kp_env(ikp)%kpoint_env%wmat(1, ispin), &
    6286         168 :                               kpoints_Sigma%kp_env(ikp)%kpoint_env%wmat(2, ispin), ks_mat_ao_ao)
    6287             :             ASSOCIATE (wmat => kpoints_Sigma_no_xc%kp_env(ikp)%kpoint_env%wmat)
    6288         168 :             IF (ASSOCIATED(wmat(1, ispin)%matrix_struct)) THEN
    6289         168 :                CALL cp_fm_copy_general(wmat(1, ispin), fm_tmp_re, para_env)
    6290             :             ELSE
    6291           0 :                CALL cp_fm_copy_general(fm_dummy, fm_tmp_re, para_env)
    6292             :             END IF
    6293         336 :             IF (ASSOCIATED(wmat(2, ispin)%matrix_struct)) THEN
    6294         168 :                CALL cp_fm_copy_general(wmat(2, ispin), fm_tmp_im, para_env)
    6295             :             ELSE
    6296           0 :                CALL cp_fm_copy_general(fm_dummy, fm_tmp_im, para_env)
    6297             :             END IF
    6298             :             END ASSOCIATE
    6299             : 
    6300         168 :             CALL cp_fm_to_cfm(fm_tmp_re, fm_tmp_im, vxc_ao_ao)
    6301             : 
    6302         168 :             CALL parallel_gemm('N', 'N', nmo, nmo, nmo, z_one, vxc_ao_ao, cfm_mo_coeff, z_zero, vxc_ao_mo)
    6303         168 :             CALL parallel_gemm('C', 'N', nmo, nmo, nmo, z_one, cfm_mo_coeff, vxc_ao_mo, z_zero, vxc_mo_mo)
    6304             : 
    6305         168 :             CALL cp_cfm_to_fm(vxc_mo_mo, fm_Sigma_x_minus_vxc_mo_mo)
    6306             : 
    6307         168 :             CALL cp_fm_get_diag(fm_Sigma_x_minus_vxc_mo_mo, diag_Sigma_x_minus_vxc_mo_mo)
    6308             : 
    6309        3544 :             qs_env%mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, ispin, ikp) = diag_Sigma_x_minus_vxc_mo_mo(:)
    6310             : 
    6311             :          END DO
    6312             : 
    6313             :       END DO
    6314             : 
    6315          18 :       CALL cp_cfm_release(ks_mat_ao_ao)
    6316          18 :       CALL cp_cfm_release(ks_mat_no_xc_ao_ao)
    6317          18 :       CALL cp_cfm_release(vxc_ao_ao)
    6318          18 :       CALL cp_cfm_release(vxc_ao_mo)
    6319          18 :       CALL cp_cfm_release(vxc_mo_mo)
    6320          18 :       CALL cp_cfm_release(cfm_mo_coeff)
    6321          18 :       CALL cp_fm_release(fm_Sigma_x_minus_vxc_mo_mo)
    6322          18 :       CALL cp_fm_release(fm_tmp_re)
    6323          18 :       CALL cp_fm_release(fm_tmp_im)
    6324             : 
    6325          18 :       DEALLOCATE (diag_Sigma_x_minus_vxc_mo_mo)
    6326             : 
    6327          18 :       CALL timestop(handle)
    6328             : 
    6329          36 :    END SUBROUTINE compute_minus_vxc_kpoints
    6330             : 
    6331             : ! **************************************************************************************************
    6332             : !> \brief ...
    6333             : !> \param qs_env ...
    6334             : !> \param mat_self_energy_ao_ao ...
    6335             : !> \param vec_Sigma ...
    6336             : !> \param homo ...
    6337             : !> \param gw_corr_lev_occ ...
    6338             : !> \param gw_corr_lev_virt ...
    6339             : !> \param ispin ...
    6340             : ! **************************************************************************************************
    6341         282 :    SUBROUTINE trafo_to_mo_and_kpoints(qs_env, mat_self_energy_ao_ao, vec_Sigma, &
    6342             :                                       homo, gw_corr_lev_occ, gw_corr_lev_virt, ispin)
    6343             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    6344             :       TYPE(dbcsr_type), TARGET                           :: mat_self_energy_ao_ao
    6345             :       REAL(KIND=dp), DIMENSION(:, :)                     :: vec_Sigma
    6346             :       INTEGER                                            :: homo, gw_corr_lev_occ, gw_corr_lev_virt, &
    6347             :                                                             ispin
    6348             : 
    6349             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'trafo_to_mo_and_kpoints'
    6350             : 
    6351             :       INTEGER                                            :: handle, ikp, nkp_self_energy, nmo, &
    6352             :                                                             periodic(3), size_real_space
    6353             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: diag_self_energy
    6354             :       TYPE(cell_type), POINTER                           :: cell
    6355             :       TYPE(cp_cfm_type)                                  :: cfm_mo_coeff, cfm_self_energy_ao_ao, &
    6356             :                                                             cfm_self_energy_ao_mo, &
    6357             :                                                             cfm_self_energy_mo_mo
    6358             :       TYPE(cp_fm_struct_type), POINTER                   :: matrix_struct
    6359             :       TYPE(cp_fm_type)                                   :: fm_self_energy_mo_mo
    6360         282 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_self_energy_ao_ao_kp_im, &
    6361         282 :          mat_self_energy_ao_ao_kp_re, mat_self_energy_ao_ao_real_space
    6362             :       TYPE(kpoint_type), POINTER                         :: kpoints_Sigma
    6363             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    6364             : 
    6365         282 :       CALL timeset(routineN, handle)
    6366             : 
    6367         282 :       CALL get_qs_env(qs_env, cell=cell, para_env=para_env)
    6368         282 :       CALL get_cell(cell=cell, periodic=periodic)
    6369             : 
    6370         282 :       size_real_space = 3**(periodic(1) + periodic(2) + periodic(3))
    6371             : 
    6372         282 :       CALL alloc_mat_set(mat_self_energy_ao_ao_real_space, size_real_space, mat_self_energy_ao_ao)
    6373             : 
    6374         282 :       CALL dbcsr_copy(mat_self_energy_ao_ao_real_space(1)%matrix, mat_self_energy_ao_ao)
    6375             : 
    6376         282 :       kpoints_Sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
    6377             : 
    6378         282 :       CALL get_mat_cell_T_from_mat_gamma(mat_self_energy_ao_ao_real_space, qs_env, kpoints_Sigma, 0, 0)
    6379             : 
    6380         282 :       nkp_self_energy = kpoints_Sigma%nkp
    6381             : 
    6382         282 :       CALL alloc_mat_set(mat_self_energy_ao_ao_kp_re, nkp_self_energy, mat_self_energy_ao_ao)
    6383         282 :       CALL alloc_mat_set(mat_self_energy_ao_ao_kp_im, nkp_self_energy, mat_self_energy_ao_ao)
    6384             : 
    6385             :       CALL real_space_to_kpoint_transform_rpa(mat_self_energy_ao_ao_kp_re, mat_self_energy_ao_ao_kp_im, &
    6386         282 :                                               mat_self_energy_ao_ao_real_space, kpoints_Sigma, 1.0E-50_dp)
    6387             : 
    6388         282 :       CALL dbcsr_get_info(mat_self_energy_ao_ao, nfullrows_total=nmo)
    6389         846 :       ALLOCATE (diag_self_energy(nmo))
    6390             : 
    6391         282 :       matrix_struct => kpoints_Sigma%kp_env(1)%kpoint_env%mos(1, 1)%mo_coeff%matrix_struct
    6392             : 
    6393         282 :       CALL cp_cfm_create(cfm_self_energy_ao_ao, matrix_struct)
    6394         282 :       CALL cp_cfm_create(cfm_self_energy_ao_mo, matrix_struct)
    6395         282 :       CALL cp_cfm_create(cfm_self_energy_mo_mo, matrix_struct)
    6396         282 :       CALL cp_cfm_set_all(cfm_self_energy_ao_ao, z_zero)
    6397         282 :       CALL cp_cfm_set_all(cfm_self_energy_ao_mo, z_zero)
    6398         282 :       CALL cp_cfm_set_all(cfm_self_energy_mo_mo, z_zero)
    6399             : 
    6400         282 :       CALL cp_fm_create(fm_self_energy_mo_mo, matrix_struct)
    6401         282 :       CALL cp_cfm_create(cfm_mo_coeff, matrix_struct)
    6402             : 
    6403        2434 :       DO ikp = 1, nkp_self_energy
    6404             : 
    6405             :          CALL dbcsr_to_cfm(mat_self_energy_ao_ao_kp_re(ikp)%matrix, &
    6406        2152 :                            mat_self_energy_ao_ao_kp_im(ikp)%matrix, cfm_self_energy_ao_ao)
    6407             : 
    6408             :          CALL cp_fm_to_cfm(kpoints_Sigma%kp_env(ikp)%kpoint_env%mos(1, ispin)%mo_coeff, &
    6409        2152 :                            kpoints_Sigma%kp_env(ikp)%kpoint_env%mos(2, ispin)%mo_coeff, cfm_mo_coeff)
    6410             : 
    6411             :          CALL parallel_gemm('N', 'N', nmo, nmo, nmo, z_one, cfm_self_energy_ao_ao, cfm_mo_coeff, &
    6412        2152 :                             z_zero, cfm_self_energy_ao_mo)
    6413             : 
    6414             :          CALL parallel_gemm('C', 'N', nmo, nmo, nmo, z_one, cfm_mo_coeff, cfm_self_energy_ao_mo, &
    6415        2152 :                             z_zero, cfm_self_energy_mo_mo)
    6416             : 
    6417        2152 :          CALL cp_cfm_to_fm(cfm_self_energy_mo_mo, fm_self_energy_mo_mo)
    6418             : 
    6419        2152 :          CALL cp_fm_get_diag(fm_self_energy_mo_mo, diag_self_energy)
    6420             : 
    6421        6738 :          vec_Sigma(:, ikp) = diag_self_energy(homo - gw_corr_lev_occ + 1:homo + gw_corr_lev_virt)
    6422             : 
    6423             :       END DO
    6424             : 
    6425         282 :       CALL dbcsr_deallocate_matrix_set(mat_self_energy_ao_ao_real_space)
    6426         282 :       CALL dbcsr_deallocate_matrix_set(mat_self_energy_ao_ao_kp_re)
    6427         282 :       CALL dbcsr_deallocate_matrix_set(mat_self_energy_ao_ao_kp_im)
    6428             : 
    6429         282 :       CALL cp_cfm_release(cfm_self_energy_ao_ao)
    6430         282 :       CALL cp_cfm_release(cfm_self_energy_ao_mo)
    6431         282 :       CALL cp_cfm_release(cfm_self_energy_mo_mo)
    6432         282 :       CALL cp_cfm_release(cfm_mo_coeff)
    6433         282 :       CALL cp_fm_release(fm_self_energy_mo_mo)
    6434             : 
    6435         282 :       DEALLOCATE (diag_self_energy)
    6436             : 
    6437         282 :       CALL timestop(handle)
    6438             : 
    6439        1128 :    END SUBROUTINE trafo_to_mo_and_kpoints
    6440             : 
    6441             : ! **************************************************************************************************
    6442             : !> \brief ...
    6443             : !> \param dbcsr_re ...
    6444             : !> \param dbcsr_im ...
    6445             : !> \param cfm_mat ...
    6446             : ! **************************************************************************************************
    6447        6456 :    SUBROUTINE dbcsr_to_cfm(dbcsr_re, dbcsr_im, cfm_mat)
    6448             : 
    6449             :       TYPE(dbcsr_type), POINTER                          :: dbcsr_re, dbcsr_im
    6450             :       TYPE(cp_cfm_type), INTENT(IN)                      :: cfm_mat
    6451             : 
    6452             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'dbcsr_to_cfm'
    6453             : 
    6454             :       INTEGER                                            :: handle
    6455             :       TYPE(cp_fm_type)                                   :: fm_mat_im, fm_mat_re
    6456             : 
    6457        2152 :       CALL timeset(routineN, handle)
    6458             : 
    6459        2152 :       CALL cp_fm_create(fm_mat_re, cfm_mat%matrix_struct)
    6460        2152 :       CALL cp_fm_create(fm_mat_im, cfm_mat%matrix_struct)
    6461        2152 :       CALL cp_fm_set_all(fm_mat_re, 0.0_dp)
    6462        2152 :       CALL cp_fm_set_all(fm_mat_im, 0.0_dp)
    6463             : 
    6464        2152 :       CALL copy_dbcsr_to_fm(dbcsr_re, fm_mat_re)
    6465        2152 :       CALL copy_dbcsr_to_fm(dbcsr_im, fm_mat_im)
    6466             : 
    6467        2152 :       CALL cp_fm_to_cfm(fm_mat_re, fm_mat_im, cfm_mat)
    6468             : 
    6469        2152 :       CALL cp_fm_release(fm_mat_re)
    6470        2152 :       CALL cp_fm_release(fm_mat_im)
    6471             : 
    6472        2152 :       CALL timestop(handle)
    6473             : 
    6474        2152 :    END SUBROUTINE dbcsr_to_cfm
    6475             : 
    6476             : ! **************************************************************************************************
    6477             : !> \brief ...
    6478             : !> \param mat_set ...
    6479             : !> \param mat_size ...
    6480             : !> \param template ...
    6481             : !> \param explicitly_no_symmetry ...
    6482             : ! **************************************************************************************************
    6483         846 :    SUBROUTINE alloc_mat_set(mat_set, mat_size, template, explicitly_no_symmetry)
    6484             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: mat_set
    6485             :       INTEGER, INTENT(IN)                                :: mat_size
    6486             :       TYPE(dbcsr_type), TARGET                           :: template
    6487             :       LOGICAL, OPTIONAL                                  :: explicitly_no_symmetry
    6488             : 
    6489             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'alloc_mat_set'
    6490             : 
    6491             :       INTEGER                                            :: handle, i_size
    6492             :       LOGICAL                                            :: my_explicitly_no_symmetry
    6493             : 
    6494         846 :       CALL timeset(routineN, handle)
    6495             : 
    6496         846 :       my_explicitly_no_symmetry = .FALSE.
    6497         846 :       IF (PRESENT(explicitly_no_symmetry)) my_explicitly_no_symmetry = explicitly_no_symmetry
    6498             : 
    6499         846 :       NULLIFY (mat_set)
    6500         846 :       CALL dbcsr_allocate_matrix_set(mat_set, mat_size)
    6501        7688 :       DO i_size = 1, mat_size
    6502        6842 :          ALLOCATE (mat_set(i_size)%matrix)
    6503        6842 :          IF (my_explicitly_no_symmetry) THEN
    6504             :             CALL dbcsr_create(matrix=mat_set(i_size)%matrix, template=template, &
    6505           0 :                               matrix_type=dbcsr_type_no_symmetry)
    6506             :          ELSE
    6507        6842 :             CALL dbcsr_create(matrix=mat_set(i_size)%matrix, template=template)
    6508             :          END IF
    6509        6842 :          CALL dbcsr_copy(mat_set(i_size)%matrix, template)
    6510        7688 :          CALL dbcsr_set(mat_set(i_size)%matrix, 0.0_dp)
    6511             :       END DO
    6512             : 
    6513         846 :       CALL timestop(handle)
    6514             : 
    6515         846 :    END SUBROUTINE alloc_mat_set
    6516             : 
    6517             : ! **************************************************************************************************
    6518             : !> \brief ...
    6519             : !> \param mat_set ...
    6520             : !> \param mat_size_1 ...
    6521             : !> \param mat_size_2 ...
    6522             : !> \param template ...
    6523             : !> \param explicitly_no_symmetry ...
    6524             : ! **************************************************************************************************
    6525           4 :    SUBROUTINE alloc_mat_set_2d(mat_set, mat_size_1, mat_size_2, template, explicitly_no_symmetry)
    6526             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: mat_set
    6527             :       INTEGER, INTENT(IN)                                :: mat_size_1, mat_size_2
    6528             :       TYPE(dbcsr_type), TARGET                           :: template
    6529             :       LOGICAL, OPTIONAL                                  :: explicitly_no_symmetry
    6530             : 
    6531             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'alloc_mat_set_2d'
    6532             : 
    6533             :       INTEGER                                            :: handle, i_size, j_size
    6534             :       LOGICAL                                            :: my_explicitly_no_symmetry
    6535             : 
    6536           4 :       CALL timeset(routineN, handle)
    6537             : 
    6538           4 :       my_explicitly_no_symmetry = .FALSE.
    6539           4 :       IF (PRESENT(explicitly_no_symmetry)) my_explicitly_no_symmetry = explicitly_no_symmetry
    6540             : 
    6541           4 :       NULLIFY (mat_set)
    6542           4 :       CALL dbcsr_allocate_matrix_set(mat_set, mat_size_1, mat_size_2)
    6543          16 :       DO i_size = 1, mat_size_1
    6544         124 :          DO j_size = 1, mat_size_2
    6545         108 :             ALLOCATE (mat_set(i_size, j_size)%matrix)
    6546         108 :             IF (my_explicitly_no_symmetry) THEN
    6547             :                CALL dbcsr_create(matrix=mat_set(i_size, j_size)%matrix, template=template, &
    6548         108 :                                  matrix_type=dbcsr_type_no_symmetry)
    6549             :             ELSE
    6550           0 :                CALL dbcsr_create(matrix=mat_set(i_size, j_size)%matrix, template=template)
    6551             :             END IF
    6552         108 :             CALL dbcsr_copy(mat_set(i_size, j_size)%matrix, template)
    6553         120 :             CALL dbcsr_set(mat_set(i_size, j_size)%matrix, 0.0_dp)
    6554             :          END DO
    6555             :       END DO
    6556             : 
    6557           4 :       CALL timestop(handle)
    6558             : 
    6559           4 :    END SUBROUTINE alloc_mat_set_2d
    6560             : 
    6561             : ! **************************************************************************************************
    6562             : !> \brief ...
    6563             : !> \param t_3c_O_all ...
    6564             : !> \param t_greens_fct ...
    6565             : !> \param t_3c_O_W ...
    6566             : !> \param mat_self_energy_ao_ao ...
    6567             : !> \param bounds_ao_ao_j ...
    6568             : !> \param bounds_RI_i ...
    6569             : !> \param unit_nr ...
    6570             : !> \param eps_filter ...
    6571             : !> \param do_occ ...
    6572             : !> \param do_virt ...
    6573             : ! **************************************************************************************************
    6574        3680 :    SUBROUTINE contract_to_self_energy(t_3c_O_all, t_greens_fct, t_3c_O_W, &
    6575             :                                       mat_self_energy_ao_ao, bounds_ao_ao_j, bounds_RI_i, &
    6576             :                                       unit_nr, eps_filter, do_occ, do_virt)
    6577             : 
    6578             :       TYPE(dbt_type)                                     :: t_3c_O_all, t_greens_fct, t_3c_O_W
    6579             :       TYPE(dbcsr_type), TARGET                           :: mat_self_energy_ao_ao
    6580             :       INTEGER, DIMENSION(2, 2)                           :: bounds_ao_ao_j
    6581             :       INTEGER, DIMENSION(2, 1)                           :: bounds_RI_i
    6582             :       INTEGER                                            :: unit_nr
    6583             :       REAL(KIND=dp)                                      :: eps_filter
    6584             :       LOGICAL                                            :: do_occ, do_virt
    6585             : 
    6586             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'contract_to_self_energy'
    6587             : 
    6588             :       INTEGER                                            :: handle
    6589             :       INTEGER, DIMENSION(2, 1)                           :: bounds_ao_j
    6590             :       INTEGER, DIMENSION(2, 2)                           :: bounds_ao_all_RI_i, bounds_RI_i_ao_j
    6591             :       REAL(KIND=dp)                                      :: sign_self_energy
    6592       92000 :       TYPE(dbt_type)                                     :: t_3c_O_G, t_3c_O_G_tmp, t_self_energy, &
    6593       33120 :                                                             t_self_energy_tmp
    6594             : 
    6595        3680 :       CALL timeset(routineN, handle)
    6596             : 
    6597        3680 :       CPASSERT(do_occ .EQV. (.NOT. do_virt))
    6598             : 
    6599        3680 :       CALL dbt_create(t_3c_O_all, t_3c_O_G, name="M occ (RI AO | AO)")
    6600        3680 :       CALL dbt_create(t_3c_O_all, t_3c_O_G_tmp, name="M occ (RI AO | AO)")
    6601        3680 :       CALL dbt_create(t_greens_fct, t_self_energy, name="(AO|AO)")
    6602        3680 :       CALL dbt_create(mat_self_energy_ao_ao, t_self_energy_tmp)
    6603             : 
    6604       11040 :       bounds_ao_j(:, 1) = bounds_ao_ao_j(:, 1)
    6605       11040 :       bounds_ao_all_RI_i(:, 1) = bounds_RI_i(:, 1)
    6606       11040 :       bounds_ao_all_RI_i(:, 2) = bounds_ao_ao_j(:, 2)
    6607             : 
    6608             :       CALL dbt_contract(1.0_dp, t_greens_fct, t_3c_O_all, 0.0_dp, &
    6609             :                         t_3c_O_G_tmp, &
    6610             :                         contract_1=[2], notcontract_1=[1], &
    6611             :                         contract_2=[3], notcontract_2=[1, 2], &
    6612             :                         map_1=[3], map_2=[1, 2], &
    6613             :                         bounds_2=bounds_ao_j, &
    6614             :                         bounds_3=bounds_ao_all_RI_i, &
    6615             :                         filter_eps=eps_filter, &
    6616        3680 :                         unit_nr=unit_nr)
    6617             : 
    6618        3680 :       CALL dbt_copy(t_3c_O_G_tmp, t_3c_O_G, order=[1, 3, 2], move_data=.TRUE.)
    6619             : 
    6620        3680 :       IF (do_occ) sign_self_energy = -1.0_dp
    6621        3680 :       IF (do_virt) sign_self_energy = 1.0_dp
    6622             : 
    6623       11040 :       bounds_RI_i_ao_j(:, 1) = bounds_RI_i(:, 1)
    6624       11040 :       bounds_RI_i_ao_j(:, 2) = bounds_ao_ao_j(:, 1)
    6625             : 
    6626             :       CALL dbt_contract(sign_self_energy, t_3c_O_W, t_3c_O_G, 0.0_dp, &
    6627             :                         t_self_energy, &
    6628             :                         contract_1=[1, 2], notcontract_1=[3], &
    6629             :                         contract_2=[1, 2], notcontract_2=[3], &
    6630             :                         map_1=[1], map_2=[2], &
    6631             :                         bounds_1=bounds_RI_i_ao_j, &
    6632             :                         filter_eps=eps_filter, &
    6633        3680 :                         unit_nr=unit_nr)
    6634             : 
    6635        3680 :       CALL dbt_copy(t_self_energy, t_self_energy_tmp)
    6636        3680 :       CALL dbt_clear(t_self_energy)
    6637             : 
    6638        3680 :       CALL dbt_copy_tensor_to_matrix(t_self_energy_tmp, mat_self_energy_ao_ao, summation=.TRUE.)
    6639             : 
    6640        3680 :       CALL dbt_destroy(t_3c_O_G)
    6641        3680 :       CALL dbt_destroy(t_3c_O_G_tmp)
    6642        3680 :       CALL dbt_destroy(t_self_energy)
    6643        3680 :       CALL dbt_destroy(t_self_energy_tmp)
    6644             : 
    6645        3680 :       CALL timestop(handle)
    6646             : 
    6647        3680 :    END SUBROUTINE contract_to_self_energy
    6648             : 
    6649             : ! **************************************************************************************************
    6650             : !> \brief ...
    6651             : !> \param t_3c_overl_int_gw_AO ...
    6652             : !> \param t_3c_overl_int_gw_RI ...
    6653             : !> \param t_AO ...
    6654             : !> \param t_RI ...
    6655             : !> \param prefac ...
    6656             : !> \param mo_bounds ...
    6657             : !> \param unit_nr ...
    6658             : !> \param t_3c_ctr_RI ...
    6659             : !> \param t_3c_ctr_AO ...
    6660             : !> \param calculate_ctr_RI ...
    6661             : ! **************************************************************************************************
    6662        1362 :    SUBROUTINE contract_cubic_gw(t_3c_overl_int_gw_AO, t_3c_overl_int_gw_RI, &
    6663             :                                 t_AO, t_RI, prefac, &
    6664             :                                 mo_bounds, unit_nr, &
    6665             :                                 t_3c_ctr_RI, t_3c_ctr_AO, calculate_ctr_RI)
    6666             :       TYPE(dbt_type), INTENT(INOUT)                      :: t_3c_overl_int_gw_AO, &
    6667             :                                                             t_3c_overl_int_gw_RI, t_AO, t_RI
    6668             :       REAL(dp), DIMENSION(2), INTENT(IN)                 :: prefac
    6669             :       INTEGER, DIMENSION(2), INTENT(IN)                  :: mo_bounds
    6670             :       INTEGER, INTENT(IN)                                :: unit_nr
    6671             :       TYPE(dbt_type), INTENT(INOUT)                      :: t_3c_ctr_RI, t_3c_ctr_AO
    6672             :       LOGICAL, INTENT(IN)                                :: calculate_ctr_RI
    6673             : 
    6674             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'contract_cubic_gw'
    6675             : 
    6676             :       INTEGER                                            :: handle
    6677             :       INTEGER, DIMENSION(2, 2)                           :: ctr_bounds_mo
    6678             :       INTEGER, DIMENSION(3)                              :: bounds_3c
    6679             : 
    6680        1362 :       CALL timeset(routineN, handle)
    6681             : 
    6682        1362 :       IF (calculate_ctr_RI) THEN
    6683         682 :          CALL dbt_get_info(t_3c_overl_int_gw_RI, nfull_total=bounds_3c)
    6684        2046 :          ctr_bounds_mo(:, 1) = [1, bounds_3c(2)]
    6685        2046 :          ctr_bounds_mo(:, 2) = mo_bounds
    6686             : 
    6687             :          CALL dbt_contract(prefac(1), t_RI, t_3c_overl_int_gw_RI, 0.0_dp, &
    6688             :                            t_3c_ctr_RI, &
    6689             :                            contract_1=[2], notcontract_1=[1], &
    6690             :                            contract_2=[1], notcontract_2=[2, 3], &
    6691             :                            map_1=[1], map_2=[2, 3], &
    6692             :                            bounds_3=ctr_bounds_mo, &
    6693         682 :                            unit_nr=unit_nr)
    6694             : 
    6695             :       END IF
    6696             : 
    6697        1362 :       CALL dbt_get_info(t_3c_overl_int_gw_AO, nfull_total=bounds_3c)
    6698        4086 :       ctr_bounds_mo(:, 1) = [1, bounds_3c(2)]
    6699        4086 :       ctr_bounds_mo(:, 2) = mo_bounds
    6700             : 
    6701             :       CALL dbt_contract(prefac(2), t_AO, t_3c_overl_int_gw_AO, 0.0_dp, &
    6702             :                         t_3c_ctr_AO, &
    6703             :                         contract_1=[2], notcontract_1=[1], &
    6704             :                         contract_2=[1], notcontract_2=[2, 3], &
    6705             :                         map_1=[1], map_2=[2, 3], &
    6706             :                         bounds_3=ctr_bounds_mo, &
    6707        1362 :                         unit_nr=unit_nr)
    6708             : 
    6709        1362 :       CALL timestop(handle)
    6710             : 
    6711        1362 :    END SUBROUTINE
    6712             : 
    6713             : ! **************************************************************************************************
    6714             : !> \brief ...
    6715             : !> \param t3c_1 ...
    6716             : !> \param t3c_2 ...
    6717             : !> \param vec_sigma ...
    6718             : !> \param mo_offset ...
    6719             : !> \param mo_bounds ...
    6720             : !> \param para_env ...
    6721             : ! **************************************************************************************************
    6722        1362 :    SUBROUTINE trace_sigma_gw(t3c_1, t3c_2, vec_sigma, mo_offset, mo_bounds, para_env)
    6723             :       TYPE(dbt_type), INTENT(INOUT)                      :: t3c_1, t3c_2
    6724             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: vec_Sigma
    6725             :       INTEGER, INTENT(IN)                                :: mo_offset
    6726             :       INTEGER, DIMENSION(2), INTENT(IN)                  :: mo_bounds
    6727             :       TYPE(mp_para_env_type), INTENT(IN)                 :: para_env
    6728             : 
    6729             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'trace_sigma_gw'
    6730             : 
    6731             :       INTEGER                                            :: handle, n, n_end, n_end_block, n_start, &
    6732             :                                                             n_start_block
    6733             :       INTEGER, DIMENSION(1)                              :: trace_shape
    6734             :       INTEGER, DIMENSION(2)                              :: mo_bounds_off
    6735             :       INTEGER, DIMENSION(3)                              :: boff, bsize, ind
    6736             :       LOGICAL                                            :: found
    6737        1362 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: block_1, block_2
    6738             :       REAL(KIND=dp), &
    6739        2724 :          DIMENSION(mo_bounds(2)-mo_bounds(1)+1)          :: vec_Sigma_prv
    6740             :       TYPE(dbt_iterator_type)                            :: iter
    6741       12258 :       TYPE(dbt_type)                                     :: t3c_1_redist
    6742             : 
    6743        1362 :       CALL timeset(routineN, handle)
    6744             : 
    6745        1362 :       CALL dbt_create(t3c_2, t3c_1_redist)
    6746        1362 :       CALL dbt_copy(t3c_1, t3c_1_redist, order=[2, 1, 3], move_data=.TRUE.)
    6747             : 
    6748       16646 :       vec_Sigma_prv = 0.0_dp
    6749             : 
    6750             : !$OMP PARALLEL DEFAULT(NONE) REDUCTION(+:vec_Sigma_prv) &
    6751             : !$OMP SHARED(t3c_1_redist,t3c_2,mo_bounds) &
    6752             : !$OMP PRIVATE(iter,ind,bsize,boff,block_1,block_2,found) &
    6753        1362 : !$OMP PRIVATE(n_start_block,n_start,n_end_block,n_end,trace_shape)
    6754             :       CALL dbt_iterator_start(iter, t3c_1_redist)
    6755             :       DO WHILE (dbt_iterator_blocks_left(iter))
    6756             :          CALL dbt_iterator_next_block(iter, ind, blk_size=bsize, blk_offset=boff)
    6757             :          CALL dbt_get_block(t3c_1_redist, ind, block_1, found)
    6758             :          CPASSERT(found)
    6759             :          CALL dbt_get_block(t3c_2, ind, block_2, found)
    6760             :          IF (.NOT. found) CYCLE
    6761             : 
    6762             :          IF (boff(3) < mo_bounds(1)) THEN
    6763             :             n_start_block = mo_bounds(1) - boff(3) + 1
    6764             :             n_start = 1
    6765             :          ELSE
    6766             :             n_start_block = 1
    6767             :             n_start = boff(3) - mo_bounds(1) + 1
    6768             :          END IF
    6769             : 
    6770             :          IF (boff(3) + bsize(3) - 1 > mo_bounds(2)) THEN
    6771             :             n_end_block = mo_bounds(2) - boff(3) + 1
    6772             :             n_end = mo_bounds(2) - mo_bounds(1) + 1
    6773             :          ELSE
    6774             :             n_end_block = bsize(3)
    6775             :             n_end = boff(3) + bsize(3) - mo_bounds(1)
    6776             :          END IF
    6777             : 
    6778             :          trace_shape(1) = SIZE(block_1, 1)*SIZE(block_1, 2)
    6779             :          vec_Sigma_prv(n_start:n_end) = &
    6780             :             vec_Sigma_prv(n_start:n_end) + &
    6781             :             (/(DOT_PRODUCT(RESHAPE(block_1(:, :, n), trace_shape), &
    6782             :                            RESHAPE(block_2(:, :, n), trace_shape)), &
    6783             :                n=n_start_block, n_end_block)/)
    6784             :          DEALLOCATE (block_1, block_2)
    6785             :       END DO
    6786             :       CALL dbt_iterator_stop(iter)
    6787             : !$OMP END PARALLEL
    6788             : 
    6789        1362 :       CALL dbt_destroy(t3c_1_redist)
    6790             : 
    6791        1362 :       CALL para_env%sum(vec_Sigma_prv)
    6792             : 
    6793        4086 :       mo_bounds_off = mo_bounds - mo_offset + 1
    6794             :       vec_Sigma(mo_bounds_off(1):mo_bounds_off(2)) = &
    6795       16646 :          vec_Sigma(mo_bounds_off(1):mo_bounds_off(2)) + vec_Sigma_prv
    6796             : 
    6797        1362 :       CALL timestop(handle)
    6798        2724 :    END SUBROUTINE
    6799             : 
    6800             : ! **************************************************************************************************
    6801             : !> \brief ...
    6802             : !> \param mat_greens_fct_occ ...
    6803             : !> \param mat_greens_fct_virt ...
    6804             : !> \param fm_mo_coeff_occ ...
    6805             : !> \param fm_mo_coeff_virt ...
    6806             : !> \param fm_mo_coeff_occ_scaled ...
    6807             : !> \param fm_mo_coeff_virt_scaled ...
    6808             : !> \param fm_scaled_dm_occ_tau ...
    6809             : !> \param fm_scaled_dm_virt_tau ...
    6810             : !> \param Eigenval ...
    6811             : !> \param nmo ...
    6812             : !> \param eps_filter ...
    6813             : !> \param e_fermi ...
    6814             : !> \param tau ...
    6815             : !> \param para_env ...
    6816             : ! **************************************************************************************************
    6817        2040 :    SUBROUTINE compute_Greens_function_time(mat_greens_fct_occ, mat_greens_fct_virt, fm_mo_coeff_occ, fm_mo_coeff_virt, &
    6818             :                                            fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
    6819         680 :                                            fm_scaled_dm_occ_tau, fm_scaled_dm_virt_tau, Eigenval, nmo, &
    6820             :                                            eps_filter, e_fermi, tau, para_env)
    6821             : 
    6822             :       TYPE(dbcsr_type), INTENT(INOUT)                    :: mat_greens_fct_occ, mat_greens_fct_virt
    6823             :       TYPE(cp_fm_type), INTENT(IN) :: fm_mo_coeff_occ, fm_mo_coeff_virt, fm_mo_coeff_occ_scaled, &
    6824             :          fm_mo_coeff_virt_scaled, fm_scaled_dm_occ_tau, fm_scaled_dm_virt_tau
    6825             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: Eigenval
    6826             :       INTEGER, INTENT(IN)                                :: nmo
    6827             :       REAL(KIND=dp), INTENT(IN)                          :: eps_filter, e_fermi, tau
    6828             :       TYPE(mp_para_env_type), INTENT(IN)                 :: para_env
    6829             : 
    6830             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_Greens_function_time'
    6831             : 
    6832             :       INTEGER                                            :: handle, i_global, iiB, jjB, ncol_local, &
    6833             :                                                             nrow_local
    6834         680 :       INTEGER, DIMENSION(:), POINTER                     :: col_indices, row_indices
    6835             :       REAL(KIND=dp)                                      :: stabilize_exp
    6836             : 
    6837         680 :       CALL timeset(routineN, handle)
    6838             : 
    6839         680 :       CALL para_env%sync()
    6840             : 
    6841             :       ! get info of fm_mo_coeff_occ
    6842             :       CALL cp_fm_get_info(matrix=fm_mo_coeff_occ, &
    6843             :                           nrow_local=nrow_local, &
    6844             :                           ncol_local=ncol_local, &
    6845             :                           row_indices=row_indices, &
    6846         680 :                           col_indices=col_indices)
    6847             : 
    6848             :       ! Multiply the occupied and the virtual MO coefficients with the factor exp((-e_i-e_F)*tau/2).
    6849             :       ! Then, we simply get the sum over all occ states and virt. states by a simple matrix-matrix
    6850             :       ! multiplication.
    6851             : 
    6852         680 :       stabilize_exp = 70.0_dp
    6853             : 
    6854             :       ! first, the occ
    6855        9890 :       DO jjB = 1, nrow_local
    6856      325840 :          DO iiB = 1, ncol_local
    6857      315950 :             i_global = col_indices(iiB)
    6858             : 
    6859      325160 :             IF (ABS(tau*0.5_dp*(Eigenval(i_global) - e_fermi)) < stabilize_exp) THEN
    6860             :                fm_mo_coeff_occ_scaled%local_data(jjB, iiB) = &
    6861      249734 :                   fm_mo_coeff_occ%local_data(jjB, iiB)*EXP(tau*0.5_dp*(Eigenval(i_global) - e_fermi))
    6862             :             ELSE
    6863       66216 :                fm_mo_coeff_occ_scaled%local_data(jjB, iiB) = 0.0_dp
    6864             :             END IF
    6865             : 
    6866             :          END DO
    6867             :       END DO
    6868             : 
    6869             :       ! the same for virt
    6870        9890 :       DO jjB = 1, nrow_local
    6871      325840 :          DO iiB = 1, ncol_local
    6872      315950 :             i_global = col_indices(iiB)
    6873             : 
    6874      325160 :             IF (ABS(tau*0.5_dp*(Eigenval(i_global) - e_fermi)) < stabilize_exp) THEN
    6875             :                fm_mo_coeff_virt_scaled%local_data(jjB, iiB) = &
    6876      249734 :                   fm_mo_coeff_virt%local_data(jjB, iiB)*EXP(-tau*0.5_dp*(Eigenval(i_global) - e_fermi))
    6877             :             ELSE
    6878       66216 :                fm_mo_coeff_virt_scaled%local_data(jjB, iiB) = 0.0_dp
    6879             :             END IF
    6880             : 
    6881             :          END DO
    6882             :       END DO
    6883             : 
    6884         680 :       CALL para_env%sync()
    6885             : 
    6886             :       CALL parallel_gemm(transa="N", transb="T", m=nmo, n=nmo, k=nmo, alpha=1.0_dp, &
    6887             :                          matrix_a=fm_mo_coeff_occ_scaled, matrix_b=fm_mo_coeff_occ_scaled, beta=0.0_dp, &
    6888         680 :                          matrix_c=fm_scaled_dm_occ_tau)
    6889             : 
    6890             :       CALL parallel_gemm(transa="N", transb="T", m=nmo, n=nmo, k=nmo, alpha=1.0_dp, &
    6891             :                          matrix_a=fm_mo_coeff_virt_scaled, matrix_b=fm_mo_coeff_virt_scaled, beta=0.0_dp, &
    6892         680 :                          matrix_c=fm_scaled_dm_virt_tau)
    6893             : 
    6894         680 :       CALL dbcsr_set(mat_greens_fct_occ, 0.0_dp)
    6895             : 
    6896             :       CALL copy_fm_to_dbcsr(fm_scaled_dm_occ_tau, &
    6897             :                             mat_greens_fct_occ, &
    6898         680 :                             keep_sparsity=.FALSE.)
    6899             : 
    6900         680 :       CALL dbcsr_filter(mat_greens_fct_occ, eps_filter)
    6901             : 
    6902         680 :       CALL dbcsr_set(mat_greens_fct_virt, 0.0_dp)
    6903             : 
    6904             :       CALL copy_fm_to_dbcsr(fm_scaled_dm_virt_tau, &
    6905             :                             mat_greens_fct_virt, &
    6906         680 :                             keep_sparsity=.FALSE.)
    6907             : 
    6908         680 :       CALL dbcsr_filter(mat_greens_fct_virt, eps_filter)
    6909             : 
    6910         680 :       CALL timestop(handle)
    6911             : 
    6912         680 :    END SUBROUTINE compute_Greens_function_time
    6913             : 
    6914             : END MODULE rpa_gw
    6915             : 

Generated by: LCOV version 1.15