LCOV - code coverage report
Current view: top level - src - gw_small_cell_full_kp.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 464 466 99.6 %
Date: 2024-12-21 06:28:57 Functions: 22 22 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief
      10             : !> \author Jan Wilhelm
      11             : !> \date 05.2024
      12             : ! **************************************************************************************************
      13             : MODULE gw_small_cell_full_kp
      14             :    USE cp_cfm_types,                    ONLY: cp_cfm_create,&
      15             :                                               cp_cfm_get_info,&
      16             :                                               cp_cfm_release,&
      17             :                                               cp_cfm_to_cfm,&
      18             :                                               cp_cfm_to_fm,&
      19             :                                               cp_cfm_type
      20             :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      21             :                                               cp_fm_get_diag,&
      22             :                                               cp_fm_release,&
      23             :                                               cp_fm_set_all,&
      24             :                                               cp_fm_type
      25             :    USE dbt_api,                         ONLY: dbt_clear,&
      26             :                                               dbt_contract,&
      27             :                                               dbt_copy,&
      28             :                                               dbt_create,&
      29             :                                               dbt_destroy,&
      30             :                                               dbt_type
      31             :    USE gw_communication,                ONLY: fm_to_local_array,&
      32             :                                               fm_to_local_tensor,&
      33             :                                               local_array_to_fm,&
      34             :                                               local_dbt_to_global_fm
      35             :    USE gw_kp_to_real_space_and_back,    ONLY: add_ikp_to_all_rs,&
      36             :                                               fm_add_ikp_to_rs,&
      37             :                                               fm_trafo_rs_to_ikp,&
      38             :                                               trafo_rs_to_ikp
      39             :    USE gw_utils,                        ONLY: add_R,&
      40             :                                               analyt_conti_and_print,&
      41             :                                               de_init_bs_env,&
      42             :                                               get_V_tr_R,&
      43             :                                               is_cell_in_index_to_cell,&
      44             :                                               power,&
      45             :                                               time_to_freq
      46             :    USE kinds,                           ONLY: dp
      47             :    USE kpoint_coulomb_2c,               ONLY: build_2c_coulomb_matrix_kp_small_cell
      48             :    USE machine,                         ONLY: m_walltime
      49             :    USE mathconstants,                   ONLY: z_one,&
      50             :                                               z_zero
      51             :    USE parallel_gemm_api,               ONLY: parallel_gemm
      52             :    USE post_scf_bandstructure_types,    ONLY: post_scf_bandstructure_type
      53             :    USE post_scf_bandstructure_utils,    ONLY: get_all_VBM_CBM_bandgaps
      54             :    USE qs_environment_types,            ONLY: qs_environment_type
      55             : #include "./base/base_uses.f90"
      56             : 
      57             :    IMPLICIT NONE
      58             : 
      59             :    PRIVATE
      60             : 
      61             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'gw_small_cell_full_kp'
      62             : 
      63             :    PUBLIC :: gw_calc_small_cell_full_kp
      64             : 
      65             : CONTAINS
      66             : 
      67             : ! **************************************************************************************************
      68             : !> \brief Perform GW band structure calculation
      69             : !> \param qs_env ...
      70             : !> \param bs_env ...
      71             : !> \par History
      72             : !>    * 05.2024 created [Jan Wilhelm]
      73             : ! **************************************************************************************************
      74           6 :    SUBROUTINE gw_calc_small_cell_full_kp(qs_env, bs_env)
      75             :       TYPE(qs_environment_type), POINTER                 :: qs_env
      76             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
      77             : 
      78             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'gw_calc_small_cell_full_kp'
      79             : 
      80             :       INTEGER                                            :: handle
      81             : 
      82           6 :       CALL timeset(routineN, handle)
      83             : 
      84             :       ! G^occ_µλ(i|τ|,k) = sum_n^occ C_µn(k)^* e^(-|(ϵ_nk-ϵ_F)τ|) C_λn(k)
      85             :       ! G^vir_µλ(i|τ|,k) = sum_n^vir C_µn(k)^* e^(-|(ϵ_nk-ϵ_F)τ|) C_λn(k)
      86             :       ! k-point k -> cell S: G^occ/vir_µλ^S(i|τ|) = sum_k w_k G^occ/vir_µλ(i|τ|,k) e^(ikS)
      87             :       ! χ_PQ^R(iτ) = sum_λR1νR2 [ sum_µS (µR1-S νR2 | P0) G^vir_λµ^S(i|τ|) ]
      88             :       !                         [ sum_σS (σR2-S λR1 | QR) G^occ_νσ^S(i|τ|) ]
      89           6 :       CALL compute_chi(bs_env)
      90             : 
      91             :       ! χ_PQ^R(iτ) -> χ_PQ(iω,k) -> ε_PQ(iω,k) -> W_PQ(iω,k) -> Ŵ(iω,k) = M^-1(k)*W(iω,k)*M^-1(k)
      92             :       !            -> Ŵ_PQ^R(iτ)
      93           6 :       CALL compute_W_real_space(bs_env, qs_env)
      94             : 
      95             :       ! D_µν(k) = sum_n^occ C^*_µn(k) C_νn(k), V^tr_PQ^R = <phi_P,0|V^tr|phi_Q,R>
      96             :       ! V^tr(k) = sum_R e^ikR V^tr^R, M(k) = sum_R e^ikR M^R, M(k) -> M^-1(k)
      97             :       ! -> Ṽ^tr(k) = M^-1(k) * V^tr(k) * M^-1(k) -> Ṽ^tr_PQ^R = sum_k w_k e^-ikR Ṽ^tr_PQ(k)
      98             :       ! Σ^x_λσ^R = sum_PR1νS1 [ sum_µS2 (λ0 µS1-S2 | PR1   ) D_µν^S2    ]
      99             :       !                       [ sum_QR2 (σR νS1    | QR1-R2) Ṽ^tr_PQ^R2 ]
     100           6 :       CALL compute_Sigma_x(bs_env, qs_env)
     101             : 
     102             :       ! Σ^c_λσ^R(iτ) = sum_PR1νS1 [ sum_µS2 (λ0 µS1-S2 | PR1   ) G^occ/vir_µν^S2(i|τ|) ]
     103             :       !                           [ sum_QR2 (σR νS1    | QR1-R2) Ŵ_PQ^R2(iτ)           ]
     104           6 :       CALL compute_Sigma_c(bs_env)
     105             : 
     106             :       ! Σ^c_λσ^R(iτ,k=0) -> Σ^c_nn(ϵ,k); ϵ_nk^GW = ϵ_nk^DFT + Σ^c_nn(ϵ,k) + Σ^x_nn(k) - v^xc_nn(k)
     107           6 :       CALL compute_QP_energies(bs_env)
     108             : 
     109           6 :       CALL de_init_bs_env(bs_env)
     110             : 
     111           6 :       CALL timestop(handle)
     112             : 
     113           6 :    END SUBROUTINE gw_calc_small_cell_full_kp
     114             : 
     115             : ! **************************************************************************************************
     116             : !> \brief ...
     117             : !> \param bs_env ...
     118             : ! **************************************************************************************************
     119           6 :    SUBROUTINE compute_chi(bs_env)
     120             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
     121             : 
     122             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'compute_chi'
     123             : 
     124             :       INTEGER                                            :: cell_DR(3), cell_R1(3), cell_R2(3), &
     125             :                                                             handle, i_cell_Delta_R, i_cell_R1, &
     126             :                                                             i_cell_R2, i_t, i_task_Delta_R_local, &
     127             :                                                             ispin
     128             :       LOGICAL                                            :: cell_found
     129             :       REAL(KIND=dp)                                      :: t1, tau
     130           6 :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: Gocc_S, Gvir_S, t_chi_R
     131           6 :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_Gocc, t_Gvir
     132             : 
     133           6 :       CALL timeset(routineN, handle)
     134             : 
     135          58 :       DO i_t = 1, bs_env%num_time_freq_points
     136             : 
     137          52 :          CALL dbt_create_2c_R(Gocc_S, bs_env%t_G, bs_env%nimages_scf_desymm)
     138          52 :          CALL dbt_create_2c_R(Gvir_S, bs_env%t_G, bs_env%nimages_scf_desymm)
     139          52 :          CALL dbt_create_2c_R(t_chi_R, bs_env%t_chi, bs_env%nimages_scf_desymm)
     140          52 :          CALL dbt_create_3c_R1_R2(t_Gocc, bs_env%t_RI_AO__AO, bs_env%nimages_3c, bs_env%nimages_3c)
     141          52 :          CALL dbt_create_3c_R1_R2(t_Gvir, bs_env%t_RI_AO__AO, bs_env%nimages_3c, bs_env%nimages_3c)
     142             : 
     143          52 :          t1 = m_walltime()
     144          52 :          tau = bs_env%imag_time_points(i_t)
     145             : 
     146         104 :          DO ispin = 1, bs_env%n_spin
     147             : 
     148             :             ! 1. compute G^occ,S(iτ) and G^vir^S(iτ) in imaginary time for cell S
     149             :             !    Background: G^σ,S(iτ) = G^occ,S,σ(iτ) * Θ(-τ) + G^vir,S,σ(iτ) * Θ(τ), σ ∈ {↑,↓}
     150             :             !    G^occ_µλ(i|τ|,k) = sum_n^occ C_µn(k)^* e^(-|(ϵ_nk-ϵ_F)τ|) C_λn(k)
     151             :             !    G^vir_µλ(i|τ|,k) = sum_n^vir C_µn(k)^* e^(-|(ϵ_nk-ϵ_F)τ|) C_λn(k)
     152             :             !    k-point k -> cell S: G^occ/vir_µλ^S(i|τ|) = sum_k w_k G^occ/vir_µλ(i|τ|,k) e^(ikS)
     153          52 :             CALL G_occ_vir(bs_env, tau, Gocc_S, ispin, occ=.TRUE., vir=.FALSE.)
     154          52 :             CALL G_occ_vir(bs_env, tau, Gvir_S, ispin, occ=.FALSE., vir=.TRUE.)
     155             : 
     156             :             ! loop over ΔR = R_1 - R_2 which are local in the tensor subgroup
     157         544 :             DO i_task_Delta_R_local = 1, bs_env%n_tasks_Delta_R_local
     158             : 
     159         440 :                i_cell_Delta_R = bs_env%task_Delta_R(i_task_Delta_R_local)
     160             : 
     161        3900 :                DO i_cell_R2 = 1, bs_env%nimages_3c
     162             : 
     163       13840 :                   cell_R2(1:3) = bs_env%index_to_cell_3c(i_cell_R2, 1:3)
     164       13840 :                   cell_DR(1:3) = bs_env%index_to_cell_Delta_R(i_cell_Delta_R, 1:3)
     165             : 
     166             :                   ! R_1 = R_2 + ΔR (from ΔR = R_2 - R_1)
     167             :                   CALL add_R(cell_R2, cell_DR, bs_env%index_to_cell_3c, cell_R1, &
     168        3460 :                              cell_found, bs_env%cell_to_index_3c, i_cell_R1)
     169             : 
     170             :                   ! 3-cells check because in M^vir_νR2,λR1,QR (step 3.): R2 is index on ν
     171        3460 :                   IF (.NOT. cell_found) CYCLE
     172             :                   ! 2. M^occ/vir_λR1,νR2,P0 = sum_µS (λR1 µR2-S | P0) G^occ/vir_νµ^S(iτ)
     173        1310 :                   CALL G_times_3c(Gocc_S, t_Gocc, bs_env, i_cell_R1, i_cell_R2)
     174        5210 :                   CALL G_times_3c(Gvir_S, t_Gvir, bs_env, i_cell_R2, i_cell_R1)
     175             : 
     176             :                END DO ! i_cell_R2
     177             : 
     178             :                ! 3. χ_PQ^R(iτ) = sum_λR1,νR2 M^occ_λR1,νR2,P0 M^vir_νR2,λR1,QR
     179             :                CALL contract_M_occ_vir_to_chi(t_Gocc, t_Gvir, t_chi_R, &
     180         492 :                                               bs_env, i_cell_Delta_R)
     181             : 
     182             :             END DO ! i_cell_Delta_R_local
     183             : 
     184             :          END DO ! ispin
     185             : 
     186          52 :          CALL bs_env%para_env%sync()
     187             : 
     188             :          CALL local_dbt_to_global_fm(t_chi_R, bs_env%fm_chi_R_t(:, i_t), bs_env%mat_RI_RI, &
     189          52 :                                      bs_env%mat_RI_RI_tensor, bs_env)
     190             : 
     191          52 :          CALL destroy_t_1d(Gocc_S)
     192          52 :          CALL destroy_t_1d(Gvir_S)
     193          52 :          CALL destroy_t_1d(t_chi_R)
     194          52 :          CALL destroy_t_2d(t_Gocc)
     195          52 :          CALL destroy_t_2d(t_Gvir)
     196             : 
     197          58 :          IF (bs_env%unit_nr > 0) THEN
     198             :             WRITE (bs_env%unit_nr, '(T2,A,I13,A,I3,A,F7.1,A)') &
     199          26 :                'Computed χ^R(iτ) for time point', i_t, ' /', bs_env%num_time_freq_points, &
     200          52 :                ',      Execution time', m_walltime() - t1, ' s'
     201             :          END IF
     202             : 
     203             :       END DO ! i_t
     204             : 
     205           6 :       CALL timestop(handle)
     206             : 
     207           6 :    END SUBROUTINE compute_chi
     208             : 
     209             : ! *************************************************************************************************
     210             : !> \brief ...
     211             : !> \param R ...
     212             : !> \param template ...
     213             : !> \param nimages ...
     214             : ! **************************************************************************************************
     215         204 :    SUBROUTINE dbt_create_2c_R(R, template, nimages)
     216             : 
     217             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: R
     218             :       TYPE(dbt_type)                                     :: template
     219             :       INTEGER                                            :: nimages
     220             : 
     221             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'dbt_create_2c_R'
     222             : 
     223             :       INTEGER                                            :: handle, i_cell_S
     224             : 
     225         204 :       CALL timeset(routineN, handle)
     226             : 
     227        4080 :       ALLOCATE (R(nimages))
     228        2040 :       DO i_cell_S = 1, nimages
     229        2040 :          CALL dbt_create(template, R(i_cell_S))
     230             :       END DO
     231             : 
     232         204 :       CALL timestop(handle)
     233             : 
     234         204 :    END SUBROUTINE dbt_create_2c_R
     235             : 
     236             : ! **************************************************************************************************
     237             : !> \brief ...
     238             : !> \param t_3c_R1_R2 ...
     239             : !> \param t_3c_template ...
     240             : !> \param nimages_1 ...
     241             : !> \param nimages_2 ...
     242             : ! **************************************************************************************************
     243         116 :    SUBROUTINE dbt_create_3c_R1_R2(t_3c_R1_R2, t_3c_template, nimages_1, nimages_2)
     244             : 
     245             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_3c_R1_R2
     246             :       TYPE(dbt_type)                                     :: t_3c_template
     247             :       INTEGER                                            :: nimages_1, nimages_2
     248             : 
     249             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'dbt_create_3c_R1_R2'
     250             : 
     251             :       INTEGER                                            :: handle, i_cell, j_cell
     252             : 
     253         116 :       CALL timeset(routineN, handle)
     254             : 
     255        8400 :       ALLOCATE (t_3c_R1_R2(nimages_1, nimages_2))
     256         892 :       DO i_cell = 1, nimages_1
     257        7124 :          DO j_cell = 1, nimages_2
     258        7008 :             CALL dbt_create(t_3c_template, t_3c_R1_R2(i_cell, j_cell))
     259             :          END DO
     260             :       END DO
     261             : 
     262         116 :       CALL timestop(handle)
     263             : 
     264         116 :    END SUBROUTINE dbt_create_3c_R1_R2
     265             : 
     266             : ! **************************************************************************************************
     267             : !> \brief ...
     268             : !> \param t_G_S ...
     269             : !> \param t_M ...
     270             : !> \param bs_env ...
     271             : !> \param i_cell_R1 ...
     272             : !> \param i_cell_R2 ...
     273             : ! **************************************************************************************************
     274        2620 :    SUBROUTINE G_times_3c(t_G_S, t_M, bs_env, i_cell_R1, i_cell_R2)
     275             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: t_G_S
     276             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_M
     277             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
     278             :       INTEGER                                            :: i_cell_R1, i_cell_R2
     279             : 
     280             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'G_times_3c'
     281             : 
     282             :       INTEGER                                            :: handle, i_cell_R1_p_S, i_cell_S
     283             :       INTEGER, DIMENSION(3)                              :: cell_R1, cell_R1_plus_cell_S, cell_R2, &
     284             :                                                             cell_S
     285             :       LOGICAL                                            :: cell_found
     286       23580 :       TYPE(dbt_type)                                     :: t_3c_int
     287             : 
     288        2620 :       CALL timeset(routineN, handle)
     289             : 
     290        2620 :       CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_int)
     291             : 
     292       10480 :       cell_R1(1:3) = bs_env%index_to_cell_3c(i_cell_R1, 1:3)
     293       10480 :       cell_R2(1:3) = bs_env%index_to_cell_3c(i_cell_R2, 1:3)
     294             : 
     295       26200 :       DO i_cell_S = 1, bs_env%nimages_scf_desymm
     296             : 
     297       94320 :          cell_S(1:3) = bs_env%kpoints_scf_desymm%index_to_cell(i_cell_S, 1:3)
     298       94320 :          cell_R1_plus_cell_S(1:3) = cell_R1(1:3) + cell_S(1:3)
     299             : 
     300       23580 :          CALL is_cell_in_index_to_cell(cell_R1_plus_cell_S, bs_env%index_to_cell_3c, cell_found)
     301             : 
     302       23580 :          IF (.NOT. cell_found) CYCLE
     303             : 
     304             :          i_cell_R1_p_S = bs_env%cell_to_index_3c(cell_R1_plus_cell_S(1), cell_R1_plus_cell_S(2), &
     305       13776 :                                                  cell_R1_plus_cell_S(3))
     306             : 
     307       13776 :          IF (bs_env%nblocks_3c(i_cell_R2, i_cell_R1_p_S) == 0) CYCLE
     308             : 
     309        7228 :          CALL get_t_3c_int(t_3c_int, bs_env, i_cell_R2, i_cell_R1_p_S)
     310             : 
     311             :          CALL dbt_contract(alpha=1.0_dp, &
     312             :                            tensor_1=t_3c_int, &
     313             :                            tensor_2=t_G_S(i_cell_S), &
     314             :                            beta=1.0_dp, &
     315             :                            tensor_3=t_M(i_cell_R1, i_cell_R2), &
     316             :                            contract_1=[3], notcontract_1=[1, 2], map_1=[1, 2], &
     317             :                            contract_2=[2], notcontract_2=[1], map_2=[3], &
     318       26200 :                            filter_eps=bs_env%eps_filter)
     319             :       END DO
     320             : 
     321        2620 :       CALL dbt_destroy(t_3c_int)
     322             : 
     323        2620 :       CALL timestop(handle)
     324             : 
     325        2620 :    END SUBROUTINE G_times_3c
     326             : 
     327             : ! **************************************************************************************************
     328             : !> \brief ...
     329             : !> \param t_3c_int ...
     330             : !> \param bs_env ...
     331             : !> \param j_cell ...
     332             : !> \param k_cell ...
     333             : ! **************************************************************************************************
     334       22419 :    SUBROUTINE get_t_3c_int(t_3c_int, bs_env, j_cell, k_cell)
     335             : 
     336             :       TYPE(dbt_type)                                     :: t_3c_int
     337             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
     338             :       INTEGER                                            :: j_cell, k_cell
     339             : 
     340             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'get_t_3c_int'
     341             : 
     342             :       INTEGER                                            :: handle
     343             : 
     344       22419 :       CALL timeset(routineN, handle)
     345             : 
     346       22419 :       CALL dbt_clear(t_3c_int)
     347       22419 :       IF (j_cell < k_cell) THEN
     348        9465 :          CALL dbt_copy(bs_env%t_3c_int(k_cell, j_cell), t_3c_int, order=[1, 3, 2])
     349             :       ELSE
     350       12954 :          CALL dbt_copy(bs_env%t_3c_int(j_cell, k_cell), t_3c_int)
     351             :       END IF
     352             : 
     353       22419 :       CALL timestop(handle)
     354             : 
     355       22419 :    END SUBROUTINE get_t_3c_int
     356             : 
     357             : ! **************************************************************************************************
     358             : !> \brief ...
     359             : !> \param bs_env ...
     360             : !> \param tau ...
     361             : !> \param G_S ...
     362             : !> \param ispin ...
     363             : !> \param occ ...
     364             : !> \param vir ...
     365             : ! **************************************************************************************************
     366         428 :    SUBROUTINE G_occ_vir(bs_env, tau, G_S, ispin, occ, vir)
     367             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
     368             :       REAL(KIND=dp)                                      :: tau
     369             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: G_S
     370             :       INTEGER                                            :: ispin
     371             :       LOGICAL                                            :: occ, vir
     372             : 
     373             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'G_occ_vir'
     374             : 
     375             :       INTEGER                                            :: handle, homo, i_cell_S, ikp, j, &
     376             :                                                             j_col_local, n_mo, ncol_local, &
     377             :                                                             nimages, nkp
     378         214 :       INTEGER, DIMENSION(:), POINTER                     :: col_indices
     379             :       REAL(KIND=dp)                                      :: tau_E
     380             : 
     381         214 :       CALL timeset(routineN, handle)
     382             : 
     383         214 :       CPASSERT(occ .NEQV. vir)
     384             : 
     385             :       CALL cp_cfm_get_info(matrix=bs_env%cfm_work_mo, &
     386             :                            ncol_local=ncol_local, &
     387         214 :                            col_indices=col_indices)
     388             : 
     389         214 :       nkp = bs_env%nkp_scf_desymm
     390         214 :       nimages = bs_env%nimages_scf_desymm
     391         214 :       n_mo = bs_env%n_ao
     392         214 :       homo = bs_env%n_occ(ispin)
     393             : 
     394        2140 :       DO i_cell_S = 1, bs_env%nimages_scf_desymm
     395        2140 :          CALL cp_fm_set_all(bs_env%fm_G_S(i_cell_S), 0.0_dp)
     396             :       END DO
     397             : 
     398        3638 :       DO ikp = 1, nkp
     399             : 
     400             :          ! get C_µn(k)
     401        3424 :          CALL cp_cfm_to_cfm(bs_env%cfm_mo_coeff_kp(ikp, ispin), bs_env%cfm_work_mo)
     402             : 
     403             :          ! G^occ/vir_µλ(i|τ|,k) = sum_n^occ/vir C_µn(k)^* e^(-|(ϵ_nk-ϵ_F)τ|) C_λn(k)
     404       38240 :          DO j_col_local = 1, ncol_local
     405             : 
     406       34816 :             j = col_indices(j_col_local)
     407             : 
     408             :             ! 0.5 * |(ϵ_nk-ϵ_F)τ|
     409       34816 :             tau_E = ABS(tau*0.5_dp*(bs_env%eigenval_scf(j, ikp, ispin) - bs_env%e_fermi(ispin)))
     410             : 
     411       34816 :             IF (tau_E < bs_env%stabilize_exp) THEN
     412             :                bs_env%cfm_work_mo%local_data(:, j_col_local) = &
     413      219488 :                   bs_env%cfm_work_mo%local_data(:, j_col_local)*EXP(-tau_E)
     414             :             ELSE
     415           0 :                bs_env%cfm_work_mo%local_data(:, j_col_local) = z_zero
     416             :             END IF
     417             : 
     418       38240 :             IF ((occ .AND. j > homo) .OR. (vir .AND. j <= homo)) THEN
     419      120928 :                bs_env%cfm_work_mo%local_data(:, j_col_local) = z_zero
     420             :             END IF
     421             : 
     422             :          END DO
     423             : 
     424             :          CALL parallel_gemm(transa="N", transb="C", m=n_mo, n=n_mo, k=n_mo, alpha=z_one, &
     425             :                             matrix_a=bs_env%cfm_work_mo, matrix_b=bs_env%cfm_work_mo, &
     426        3424 :                             beta=z_zero, matrix_c=bs_env%cfm_work_mo_2)
     427             : 
     428             :          ! trafo k-point k -> cell S:  G^occ/vir_µλ(i|τ|,k) -> G^occ/vir,S_µλ(i|τ|)
     429             :          CALL fm_add_ikp_to_rs(bs_env%cfm_work_mo_2, bs_env%fm_G_S, &
     430        3638 :                                bs_env%kpoints_scf_desymm, ikp)
     431             : 
     432             :       END DO ! ikp
     433             : 
     434             :       ! replicate to tensor from local tensor group
     435        2140 :       DO i_cell_S = 1, bs_env%nimages_scf_desymm
     436             :          CALL fm_to_local_tensor(bs_env%fm_G_S(i_cell_S), bs_env%mat_ao_ao%matrix, &
     437        2140 :                                  bs_env%mat_ao_ao_tensor%matrix, G_S(i_cell_S), bs_env)
     438             :       END DO
     439             : 
     440         214 :       CALL timestop(handle)
     441             : 
     442         214 :    END SUBROUTINE G_occ_vir
     443             : 
     444             : ! **************************************************************************************************
     445             : !> \brief ...
     446             : !> \param t_Gocc ...
     447             : !> \param t_Gvir ...
     448             : !> \param t_chi_R ...
     449             : !> \param bs_env ...
     450             : !> \param i_cell_Delta_R ...
     451             : ! **************************************************************************************************
     452         440 :    SUBROUTINE contract_M_occ_vir_to_chi(t_Gocc, t_Gvir, t_chi_R, bs_env, i_cell_Delta_R)
     453             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_Gocc, t_Gvir
     454             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: t_chi_R
     455             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
     456             :       INTEGER                                            :: i_cell_Delta_R
     457             : 
     458             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'contract_M_occ_vir_to_chi'
     459             : 
     460             :       INTEGER                                            :: handle, i_cell_R, i_cell_R1, &
     461             :                                                             i_cell_R1_minus_R, i_cell_R2, &
     462             :                                                             i_cell_R2_minus_R
     463             :       INTEGER, DIMENSION(3)                              :: cell_DR, cell_R, cell_R1, &
     464             :                                                             cell_R1_minus_R, cell_R2, &
     465             :                                                             cell_R2_minus_R
     466             :       LOGICAL                                            :: cell_found
     467        7480 :       TYPE(dbt_type)                                     :: t_Gocc_2, t_Gvir_2
     468             : 
     469         440 :       CALL timeset(routineN, handle)
     470             : 
     471         440 :       CALL dbt_create(bs_env%t_RI__AO_AO, t_Gocc_2)
     472         440 :       CALL dbt_create(bs_env%t_RI__AO_AO, t_Gvir_2)
     473             : 
     474             :       ! χ_PQ^R(iτ) = sum_λR1,νR2 M^occ_λR1,νR2,P0 M^vir_νR2,λR1,QR
     475        4400 :       DO i_cell_R = 1, bs_env%nimages_scf_desymm
     476             : 
     477       35540 :          DO i_cell_R2 = 1, bs_env%nimages_3c
     478             : 
     479      124560 :             cell_R(1:3) = bs_env%kpoints_scf_desymm%index_to_cell(i_cell_R, 1:3)
     480      124560 :             cell_R2(1:3) = bs_env%index_to_cell_3c(i_cell_R2, 1:3)
     481      124560 :             cell_DR(1:3) = bs_env%index_to_cell_Delta_R(i_cell_Delta_R, 1:3)
     482             : 
     483             :             ! R_1 = R_2 + ΔR (from ΔR = R_2 - R_1)
     484             :             CALL add_R(cell_R2, cell_DR, bs_env%index_to_cell_3c, cell_R1, &
     485       31140 :                        cell_found, bs_env%cell_to_index_3c, i_cell_R1)
     486       31140 :             IF (.NOT. cell_found) CYCLE
     487             : 
     488             :             ! R_1 - R
     489             :             CALL add_R(cell_R1, -cell_R, bs_env%index_to_cell_3c, cell_R1_minus_R, &
     490       47160 :                        cell_found, bs_env%cell_to_index_3c, i_cell_R1_minus_R)
     491       11790 :             IF (.NOT. cell_found) CYCLE
     492             : 
     493             :             ! R_2 - R
     494             :             CALL add_R(cell_R2, -cell_R, bs_env%index_to_cell_3c, cell_R2_minus_R, &
     495       27552 :                        cell_found, bs_env%cell_to_index_3c, i_cell_R2_minus_R)
     496        6888 :             IF (.NOT. cell_found) CYCLE
     497             : 
     498             :             ! reorder tensors for efficient contraction to χ_PQ^R
     499        4506 :             CALL dbt_copy(t_Gocc(i_cell_R1, i_cell_R2), t_Gocc_2, order=[1, 3, 2])
     500        4506 :             CALL dbt_copy(t_Gvir(i_cell_R2_minus_R, i_cell_R1_minus_R), t_Gvir_2)
     501             : 
     502             :             ! χ_PQ^R(iτ) = sum_λR1,νR2 M^occ_λR1,νR2,P0 M^vir_νR2,λR1,QR
     503             :             CALL dbt_contract(alpha=bs_env%spin_degeneracy, &
     504             :                               tensor_1=t_Gocc_2, tensor_2=t_Gvir_2, &
     505             :                               beta=1.0_dp, tensor_3=t_chi_R(i_cell_R), &
     506             :                               contract_1=[2, 3], notcontract_1=[1], map_1=[1], &
     507             :                               contract_2=[2, 3], notcontract_2=[1], map_2=[2], &
     508       39606 :                               filter_eps=bs_env%eps_filter, move_data=.TRUE.)
     509             :          END DO ! i_cell_R2
     510             : 
     511             :       END DO ! i_cell_R
     512             : 
     513             :       ! remove all data from t_Gocc and t_Gvir to safe memory
     514        3900 :       DO i_cell_R1 = 1, bs_env%nimages_3c
     515       36320 :          DO i_cell_R2 = 1, bs_env%nimages_3c
     516       32420 :             CALL dbt_clear(t_Gocc(i_cell_R1, i_cell_R2))
     517       35880 :             CALL dbt_clear(t_Gvir(i_cell_R1, i_cell_R2))
     518             :          END DO
     519             :       END DO
     520             : 
     521         440 :       CALL dbt_destroy(t_Gocc_2)
     522         440 :       CALL dbt_destroy(t_Gvir_2)
     523             : 
     524         440 :       CALL timestop(handle)
     525             : 
     526         440 :    END SUBROUTINE contract_M_occ_vir_to_chi
     527             : 
     528             : ! **************************************************************************************************
     529             : !> \brief ...
     530             : !> \param bs_env ...
     531             : !> \param qs_env ...
     532             : ! **************************************************************************************************
     533           6 :    SUBROUTINE compute_W_real_space(bs_env, qs_env)
     534             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
     535             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     536             : 
     537             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_W_real_space'
     538             : 
     539           6 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :)     :: chi_k_w, eps_k_w, W_k_w, work
     540           6 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)  :: M_inv, M_inv_V_sqrt, V_sqrt
     541             :       INTEGER                                            :: handle, i_t, ikp, ikp_local, j_w, n_RI, &
     542             :                                                             nimages_scf_desymm
     543             :       REAL(KIND=dp)                                      :: freq_j, t1, time_i, weight_ij
     544             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: chi_R, MWM_R, W_R
     545             : 
     546           6 :       CALL timeset(routineN, handle)
     547             : 
     548           6 :       n_RI = bs_env%n_RI
     549           6 :       nimages_scf_desymm = bs_env%nimages_scf_desymm
     550             : 
     551          60 :       ALLOCATE (chi_k_w(n_RI, n_RI), work(n_RI, n_RI), eps_k_w(n_RI, n_RI), W_k_w(n_RI, n_RI))
     552             :       ALLOCATE (chi_R(n_RI, n_RI, nimages_scf_desymm), W_R(n_RI, n_RI, nimages_scf_desymm), &
     553          66 :                 MWM_R(n_RI, n_RI, nimages_scf_desymm))
     554             : 
     555           6 :       t1 = m_walltime()
     556             : 
     557           6 :       CALL compute_Minv_and_Vsqrt(bs_env, qs_env, M_inv_V_sqrt, M_inv, V_sqrt)
     558             : 
     559           6 :       IF (bs_env%unit_nr > 0) THEN
     560             :          WRITE (bs_env%unit_nr, '(T2,A,T58,A,F7.1,A)') &
     561           3 :             'Computed V_PQ(k),', 'Execution time', m_walltime() - t1, ' s'
     562           3 :          WRITE (bs_env%unit_nr, '(A)') ' '
     563             :       END IF
     564             : 
     565           6 :       t1 = m_walltime()
     566             : 
     567          58 :       DO j_w = 1, bs_env%num_time_freq_points
     568             : 
     569             :          ! χ_PQ^R(iτ) -> χ_PQ^R(iω_j) (which is stored in chi_R, single ω_j from j_w loop)
     570       15856 :          chi_R(:, :, :) = 0.0_dp
     571         524 :          DO i_t = 1, bs_env%num_time_freq_points
     572         472 :             freq_j = bs_env%imag_freq_points(j_w)
     573         472 :             time_i = bs_env%imag_time_points(i_t)
     574         472 :             weight_ij = bs_env%weights_cos_t_to_w(j_w, i_t)*COS(time_i*freq_j)
     575             : 
     576         524 :             CALL fm_to_local_array(bs_env%fm_chi_R_t(:, i_t), chi_R, weight_ij, add=.TRUE.)
     577             :          END DO
     578             : 
     579          52 :          ikp_local = 0
     580       15856 :          W_R(:, :, :) = 0.0_dp
     581       33332 :          DO ikp = 1, bs_env%nkp_chi_eps_W_orig_plus_extra
     582             : 
     583             :             ! trivial parallelization over k-points
     584       33280 :             IF (MODULO(ikp, bs_env%para_env%num_pe) .NE. bs_env%para_env%mepos) CYCLE
     585             : 
     586       16640 :             ikp_local = ikp_local + 1
     587             : 
     588             :             ! 1. χ_PQ^R(iω_j) -> χ_PQ(iω_j,k)
     589             :             CALL trafo_rs_to_ikp(chi_R, chi_k_w, bs_env%kpoints_scf_desymm%index_to_cell, &
     590       16640 :                                  bs_env%kpoints_chi_eps_W%xkp(1:3, ikp))
     591             : 
     592             :             ! 2. remove negative eigenvalues from χ_PQ(iω,k)
     593       16640 :             CALL power(chi_k_w, 1.0_dp, bs_env%eps_eigval_mat_RI)
     594             : 
     595             :             ! 3. ε(iω_j,k_i) = Id - V^0.5(k_i)*M^-1(k_i)*χ(iω_j,k_i)*M^-1(k_i)*V^0.5(k_i)
     596             : 
     597             :             ! 3. a) work = χ(iω_j,k_i)*M^-1(k_i)*V^0.5(k_i)
     598             :             CALL ZGEMM('N', 'N', n_RI, n_RI, n_RI, z_one, chi_k_w, n_RI, &
     599       16640 :                        M_inv_V_sqrt(:, :, ikp_local), n_RI, z_zero, work, n_RI)
     600             : 
     601             :             ! 3. b) eps_work = V^0.5(k_i)*M^-1(k_i)*work
     602             :             CALL ZGEMM('C', 'N', n_RI, n_RI, n_RI, z_one, M_inv_V_sqrt(:, :, ikp_local), n_RI, &
     603       16640 :                        work, n_RI, z_zero, eps_k_w, n_RI)
     604             : 
     605             :             ! 3. c) ε(iω_j,k_i) = eps_work - Id
     606       16640 :             CALL add_on_diag(eps_k_w, z_one)
     607             : 
     608             :             ! 4. W(iω_j,k_i) = M^-1(k_i)*V^0.5(k_i)*(ε^-1(iω_j,k_i)-Id)*V^0.5(k_i)*M^-1(k_i)
     609             : 
     610             :             ! 4. a) Inversion of ε(iω_j,k_i) using its Cholesky decomposition
     611       16640 :             CALL power(eps_k_w, -1.0_dp, 0.0_dp)
     612             : 
     613             :             ! 4. b) ε^-1(iω_j,k_i)-Id
     614       16640 :             CALL add_on_diag(eps_k_w, -z_one)
     615             : 
     616             :             ! 4. c) work = (ε^-1(iω_j,k_i)-Id)*V^0.5(k_i)
     617             :             CALL ZGEMM('N', 'C', n_RI, n_RI, n_RI, z_one, eps_k_w, n_RI, &
     618       16640 :                        V_sqrt(:, :, ikp_local), n_RI, z_zero, work, n_RI)
     619             : 
     620             :             ! 4. d) W(iω,k_i) = V^0.5(k_i)*work
     621             :             CALL ZGEMM('N', 'N', n_RI, n_RI, n_RI, z_one, V_sqrt(:, :, ikp_local), n_RI, &
     622       16640 :                        work, n_RI, z_zero, W_k_w, n_RI)
     623             : 
     624             :             ! 5. W(iω,k_i) -> W^R(iω) = sum_k w_k e^(-ikR) W(iω,k) (k-point extrapolation here)
     625             :             CALL add_ikp_to_all_rs(W_k_w, W_R, bs_env%kpoints_chi_eps_W, ikp, &
     626       33332 :                                    index_to_cell_ext=bs_env%kpoints_scf_desymm%index_to_cell)
     627             : 
     628             :          END DO ! ikp
     629             : 
     630          52 :          CALL bs_env%para_env%sync()
     631          52 :          CALL bs_env%para_env%sum(W_R)
     632             : 
     633             :          ! 6. W^R(iω) -> W(iω,k) [k-mesh is not extrapolated for stable mult. with M^-1(k) ]
     634             :          !            -> M^-1(k)*W(iω,k)*M^-1(k) =: Ŵ(iω,k) -> Ŵ^R(iω) (stored in MWM_R)
     635          52 :          CALL mult_W_with_Minv(W_R, MWM_R, bs_env, qs_env)
     636             : 
     637             :          ! 7. Ŵ^R(iω) -> Ŵ^R(iτ) and to fully distributed fm matrix bs_env%fm_MWM_R_t
     638         530 :          DO i_t = 1, bs_env%num_time_freq_points
     639         472 :             freq_j = bs_env%imag_freq_points(j_w)
     640         472 :             time_i = bs_env%imag_time_points(i_t)
     641         472 :             weight_ij = bs_env%weights_cos_w_to_t(i_t, j_w)*COS(time_i*freq_j)
     642         524 :             CALL local_array_to_fm(MWM_R, bs_env%fm_MWM_R_t(:, i_t), weight_ij, add=.TRUE.)
     643             :          END DO ! i_t
     644             : 
     645             :       END DO ! j_w
     646             : 
     647           6 :       IF (bs_env%unit_nr > 0) THEN
     648             :          WRITE (bs_env%unit_nr, '(T2,A,T60,A,F7.1,A)') &
     649           3 :             'Computed W_PQ(k,iω) for all k and τ,', 'Execution time', m_walltime() - t1, ' s'
     650           3 :          WRITE (bs_env%unit_nr, '(A)') ' '
     651             :       END IF
     652             : 
     653           6 :       CALL timestop(handle)
     654             : 
     655          12 :    END SUBROUTINE compute_W_real_space
     656             : 
     657             : ! **************************************************************************************************
     658             : !> \brief ...
     659             : !> \param bs_env ...
     660             : !> \param qs_env ...
     661             : !> \param M_inv_V_sqrt ...
     662             : !> \param M_inv ...
     663             : !> \param V_sqrt ...
     664             : ! **************************************************************************************************
     665           6 :    SUBROUTINE compute_Minv_and_Vsqrt(bs_env, qs_env, M_inv_V_sqrt, M_inv, V_sqrt)
     666             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
     667             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     668             :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)  :: M_inv_V_sqrt, M_inv, V_sqrt
     669             : 
     670             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_Minv_and_Vsqrt'
     671             : 
     672             :       INTEGER                                            :: handle, ikp, ikp_local, n_RI, nkp, &
     673             :                                                             nkp_local, nkp_orig
     674           6 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: M_R
     675             : 
     676           6 :       CALL timeset(routineN, handle)
     677             : 
     678           6 :       nkp = bs_env%nkp_chi_eps_W_orig_plus_extra
     679           6 :       nkp_orig = bs_env%nkp_chi_eps_W_orig
     680           6 :       n_RI = bs_env%n_RI
     681             : 
     682           6 :       nkp_local = 0
     683        3846 :       DO ikp = 1, nkp
     684             :          ! trivial parallelization over k-points
     685        3840 :          IF (MODULO(ikp, bs_env%para_env%num_pe) .NE. bs_env%para_env%mepos) CYCLE
     686        3846 :          nkp_local = nkp_local + 1
     687             :       END DO
     688             : 
     689           0 :       ALLOCATE (M_inv_V_sqrt(n_RI, n_RI, nkp_local), M_inv(n_RI, n_RI, nkp_local), &
     690          78 :                 V_sqrt(n_RI, n_RI, nkp_local))
     691             : 
     692       67206 :       M_inv_V_sqrt(:, :, :) = z_zero
     693       67206 :       M_inv(:, :, :) = z_zero
     694       67206 :       V_sqrt(:, :, :) = z_zero
     695             : 
     696             :       ! 1. 2c Coulomb integrals for the first "original" k-point grid
     697          24 :       bs_env%kpoints_chi_eps_W%nkp_grid = bs_env%nkp_grid_chi_eps_W_orig
     698             :       CALL build_2c_coulomb_matrix_kp_small_cell(V_sqrt, qs_env, bs_env%kpoints_chi_eps_W, &
     699             :                                                  bs_env%size_lattice_sum_V, basis_type="RI_AUX", &
     700           6 :                                                  ikp_start=1, ikp_end=nkp_orig)
     701             : 
     702             :       ! 2. 2c Coulomb integrals for the second "extrapolation" k-point grid
     703          24 :       bs_env%kpoints_chi_eps_W%nkp_grid = bs_env%nkp_grid_chi_eps_W_extra
     704             :       CALL build_2c_coulomb_matrix_kp_small_cell(V_sqrt, qs_env, bs_env%kpoints_chi_eps_W, &
     705             :                                                  bs_env%size_lattice_sum_V, basis_type="RI_AUX", &
     706           6 :                                                  ikp_start=nkp_orig + 1, ikp_end=nkp)
     707             : 
     708             :       ! now get M^-1(k) and M^-1(k)*V^0.5(k)
     709             : 
     710             :       ! compute M^R_PQ = <phi_P,0|V^tr(rc=3Å)|phi_Q,R> for RI metric
     711           6 :       CALL get_V_tr_R(M_R, bs_env%ri_metric, bs_env%regularization_RI, bs_env, qs_env)
     712             : 
     713           6 :       ikp_local = 0
     714        3846 :       DO ikp = 1, nkp
     715             : 
     716             :          ! trivial parallelization
     717        3840 :          IF (MODULO(ikp, bs_env%para_env%num_pe) .NE. bs_env%para_env%mepos) CYCLE
     718             : 
     719        1920 :          ikp_local = ikp_local + 1
     720             : 
     721             :          ! M(k) = sum_R e^ikR M^R
     722             :          CALL trafo_rs_to_ikp(M_R, M_inv(:, :, ikp_local), &
     723             :                               bs_env%kpoints_scf_desymm%index_to_cell, &
     724        1920 :                               bs_env%kpoints_chi_eps_W%xkp(1:3, ikp))
     725             : 
     726             :          ! invert M_PQ(k)
     727        1920 :          CALL power(M_inv(:, :, ikp_local), -1.0_dp, 0.0_dp)
     728             : 
     729             :          ! V^0.5(k)
     730        1920 :          CALL power(V_sqrt(:, :, ikp_local), 0.5_dp, 0.0_dp)
     731             : 
     732             :          ! M^-1(k)*V^0.5(k)
     733             :          CALL ZGEMM("N", "C", n_RI, n_RI, n_RI, z_one, M_inv(:, :, ikp_local), n_RI, &
     734        3846 :                     V_sqrt(:, :, ikp_local), n_RI, z_zero, M_inv_V_sqrt(:, :, ikp_local), n_RI)
     735             : 
     736             :       END DO ! ikp
     737             : 
     738           6 :       CALL timestop(handle)
     739             : 
     740          12 :    END SUBROUTINE compute_Minv_and_Vsqrt
     741             : 
     742             : ! **************************************************************************************************
     743             : !> \brief ...
     744             : !> \param matrix ...
     745             : !> \param alpha ...
     746             : ! **************************************************************************************************
     747       33280 :    SUBROUTINE add_on_diag(matrix, alpha)
     748             :       COMPLEX(KIND=dp), DIMENSION(:, :)                  :: matrix
     749             :       COMPLEX(KIND=dp)                                   :: alpha
     750             : 
     751             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'add_on_diag'
     752             : 
     753             :       INTEGER                                            :: handle, i, n
     754             : 
     755       33280 :       CALL timeset(routineN, handle)
     756             : 
     757       33280 :       n = SIZE(matrix, 1)
     758       33280 :       CPASSERT(n == SIZE(matrix, 2))
     759             : 
     760      207360 :       DO i = 1, n
     761      207360 :          matrix(i, i) = matrix(i, i) + alpha
     762             :       END DO
     763             : 
     764       33280 :       CALL timestop(handle)
     765             : 
     766       33280 :    END SUBROUTINE add_on_diag
     767             : 
     768             : ! **************************************************************************************************
     769             : !> \brief ...
     770             : !> \param W_R ...
     771             : !> \param MWM_R ...
     772             : !> \param bs_env ...
     773             : !> \param qs_env ...
     774             : ! **************************************************************************************************
     775          52 :    SUBROUTINE mult_W_with_Minv(W_R, MWM_R, bs_env, qs_env)
     776             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: W_R, MWM_R
     777             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
     778             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     779             : 
     780             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'mult_W_with_Minv'
     781             : 
     782          52 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :)     :: M_inv, W_k, work
     783             :       INTEGER                                            :: handle, ikp, n_RI
     784          52 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: M_R
     785             : 
     786          52 :       CALL timeset(routineN, handle)
     787             : 
     788             :       ! compute M^R again
     789          52 :       CALL get_V_tr_R(M_R, bs_env%ri_metric, bs_env%regularization_RI, bs_env, qs_env)
     790             : 
     791          52 :       n_RI = bs_env%n_RI
     792         416 :       ALLOCATE (M_inv(n_RI, n_RI), W_k(n_RI, n_RI), work(n_RI, n_RI))
     793       15856 :       MWM_R(:, :, :) = 0.0_dp
     794             : 
     795         884 :       DO ikp = 1, bs_env%nkp_scf_desymm
     796             : 
     797             :          ! trivial parallelization
     798         832 :          IF (MODULO(ikp, bs_env%para_env%num_pe) .NE. bs_env%para_env%mepos) CYCLE
     799             : 
     800             :          ! M(k) = sum_R e^ikR M^R
     801             :          CALL trafo_rs_to_ikp(M_R, M_inv, &
     802             :                               bs_env%kpoints_scf_desymm%index_to_cell, &
     803         416 :                               bs_env%kpoints_scf_desymm%xkp(1:3, ikp))
     804             : 
     805             :          ! invert M_PQ(k)
     806         416 :          CALL power(M_inv, -1.0_dp, 0.0_dp)
     807             : 
     808             :          ! W(k) = sum_R e^ikR W^R [only R in the supercell that is determined by the SCF k-mesh]
     809             :          CALL trafo_rs_to_ikp(W_R, W_k, &
     810             :                               bs_env%kpoints_scf_desymm%index_to_cell, &
     811         416 :                               bs_env%kpoints_scf_desymm%xkp(1:3, ikp))
     812             : 
     813             :          ! 2e. M^-1(k) W^trunc(k)
     814         416 :          CALL ZGEMM("N", "N", n_RI, n_RI, n_RI, z_one, M_inv, n_RI, W_k, n_RI, z_zero, work, n_RI)
     815             : 
     816             :          ! 2f. Ŵ(k) = M^-1(k) W^trunc(k) M^-1(k)
     817         416 :          CALL ZGEMM("N", "N", n_RI, n_RI, n_RI, z_one, work, n_RI, M_inv, n_RI, z_zero, W_k, n_RI)
     818             : 
     819             :          ! 2g. Ŵ^R = sum_k w_k e^(-ikR) Ŵ^(k)
     820         884 :          CALL add_ikp_to_all_rs(W_k, MWM_R, bs_env%kpoints_scf_desymm, ikp)
     821             : 
     822             :       END DO ! ikp
     823             : 
     824          52 :       CALL bs_env%para_env%sync()
     825          52 :       CALL bs_env%para_env%sum(MWM_R)
     826             : 
     827          52 :       CALL timestop(handle)
     828             : 
     829         104 :    END SUBROUTINE mult_W_with_Minv
     830             : 
     831             : ! **************************************************************************************************
     832             : !> \brief ...
     833             : !> \param bs_env ...
     834             : !> \param qs_env ...
     835             : ! **************************************************************************************************
     836           6 :    SUBROUTINE compute_Sigma_x(bs_env, qs_env)
     837             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
     838             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     839             : 
     840             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'compute_Sigma_x'
     841             : 
     842             :       INTEGER                                            :: handle, i_cell_Delta_R, &
     843             :                                                             i_task_Delta_R_local, ispin
     844             :       REAL(KIND=dp)                                      :: t1
     845           6 :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: D_S, Mi_Vtr_Mi_R, Sigma_x_R
     846           6 :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_V
     847             : 
     848           6 :       CALL timeset(routineN, handle)
     849             : 
     850           6 :       CALL dbt_create_2c_R(Mi_Vtr_Mi_R, bs_env%t_W, bs_env%nimages_scf_desymm)
     851           6 :       CALL dbt_create_2c_R(D_S, bs_env%t_G, bs_env%nimages_scf_desymm)
     852           6 :       CALL dbt_create_2c_R(Sigma_x_R, bs_env%t_G, bs_env%nimages_scf_desymm)
     853           6 :       CALL dbt_create_3c_R1_R2(t_V, bs_env%t_RI_AO__AO, bs_env%nimages_3c, bs_env%nimages_3c)
     854             : 
     855           6 :       t1 = m_walltime()
     856             : 
     857             :       ! V^tr_PQ^R = <phi_P,0|V^tr|phi_Q,R>, V^tr(k) = sum_R e^ikR V^tr^R
     858             :       ! M(k) = sum_R e^ikR M^R, M(k) -> M^-1(k) -> Ṽ^tr(k) = M^-1(k) * V^tr(k) * M^-1(k)
     859             :       !                                         -> Ṽ^tr_PQ^R = sum_k w_k e^-ikR Ṽ^tr_PQ(k)
     860           6 :       CALL get_Minv_Vtr_Minv_R(Mi_Vtr_Mi_R, bs_env, qs_env)
     861             : 
     862             :       ! Σ^x_λσ^R = sum_PR1νS1 [ sum_µS2 (λ0 µS1-S2 | PR1   ) D_µν^S2       ]
     863             :       !                       [ sum_QR2 (σR νS1    | QR1-R2) Ṽ^tr_PQ^R2 ]
     864          12 :       DO ispin = 1, bs_env%n_spin
     865             : 
     866             :          ! compute D^S(iτ) for cell S from D_µν(k) = sum_n^occ C^*_µn(k) C_νn(k):
     867             :          ! trafo k-point k -> cell S: D_µν^S = sum_k w_k D_µν(k) e^(ikS)
     868           6 :          CALL G_occ_vir(bs_env, 0.0_dp, D_S, ispin, occ=.TRUE., vir=.FALSE.)
     869             : 
     870             :          ! loop over ΔR = S_1 - R_1 which are local in the tensor subgroup
     871          62 :          DO i_task_Delta_R_local = 1, bs_env%n_tasks_Delta_R_local
     872             : 
     873          56 :             i_cell_Delta_R = bs_env%task_Delta_R(i_task_Delta_R_local)
     874             : 
     875             :             ! M^V_σ0,νS1,PR1 = sum_QR2 ( σ0 νS1 | QR1-R2 ) Ṽ^tr_QP^R2 for i_task_local
     876          56 :             CALL contract_W(t_V, Mi_Vtr_Mi_R, bs_env, i_cell_Delta_R)
     877             : 
     878             :             ! M^D_λ0,νS1,PR1 = sum_µS2 (λ0 µS1-S2 | PR1) D_µν^S2
     879             :             ! Σ^x_λσ^R = sum_PR1νS1 M^D_λ0,νS1,PR1 * M^V_σR,νS1,PR1 for i_task_local, where
     880             :             !                                        M^V_σR,νS1,PR1 = M^V_σ0,νS1-R,PR1-R
     881             :             CALL contract_to_Sigma(Sigma_x_R, t_V, D_S, i_cell_Delta_R, bs_env, &
     882          62 :                                    occ=.TRUE., vir=.FALSE., clear_t_W=.TRUE.)
     883             : 
     884             :          END DO ! i_cell_Delta_R_local
     885             : 
     886           6 :          CALL bs_env%para_env%sync()
     887             : 
     888             :          CALL local_dbt_to_global_fm(Sigma_x_R, bs_env%fm_Sigma_x_R, bs_env%mat_ao_ao, &
     889          12 :                                      bs_env%mat_ao_ao_tensor, bs_env)
     890             : 
     891             :       END DO ! ispin
     892             : 
     893           6 :       IF (bs_env%unit_nr > 0) THEN
     894             :          WRITE (bs_env%unit_nr, '(T2,A,T58,A,F7.1,A)') &
     895           3 :             'Computed Σ^x,', ' Execution time', m_walltime() - t1, ' s'
     896           3 :          WRITE (bs_env%unit_nr, '(A)') ' '
     897             :       END IF
     898             : 
     899           6 :       CALL destroy_t_1d(Mi_Vtr_Mi_R)
     900           6 :       CALL destroy_t_1d(D_S)
     901           6 :       CALL destroy_t_1d(Sigma_x_R)
     902           6 :       CALL destroy_t_2d(t_V)
     903             : 
     904           6 :       CALL timestop(handle)
     905             : 
     906           6 :    END SUBROUTINE compute_Sigma_x
     907             : 
     908             : ! **************************************************************************************************
     909             : !> \brief ...
     910             : !> \param bs_env ...
     911             : ! **************************************************************************************************
     912           6 :    SUBROUTINE compute_Sigma_c(bs_env)
     913             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
     914             : 
     915             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'compute_Sigma_c'
     916             : 
     917             :       INTEGER                                            :: handle, i_cell_Delta_R, i_t, &
     918             :                                                             i_task_Delta_R_local, ispin
     919             :       REAL(KIND=dp)                                      :: t1, tau
     920           6 :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: Gocc_S, Gvir_S, Sigma_c_R_neg_tau, &
     921           6 :                                                             Sigma_c_R_pos_tau, W_R
     922           6 :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_W
     923             : 
     924           6 :       CALL timeset(routineN, handle)
     925             : 
     926           6 :       CALL dbt_create_2c_R(Gocc_S, bs_env%t_G, bs_env%nimages_scf_desymm)
     927           6 :       CALL dbt_create_2c_R(Gvir_S, bs_env%t_G, bs_env%nimages_scf_desymm)
     928           6 :       CALL dbt_create_2c_R(W_R, bs_env%t_W, bs_env%nimages_scf_desymm)
     929           6 :       CALL dbt_create_3c_R1_R2(t_W, bs_env%t_RI_AO__AO, bs_env%nimages_3c, bs_env%nimages_3c)
     930           6 :       CALL dbt_create_2c_R(Sigma_c_R_neg_tau, bs_env%t_G, bs_env%nimages_scf_desymm)
     931           6 :       CALL dbt_create_2c_R(Sigma_c_R_pos_tau, bs_env%t_G, bs_env%nimages_scf_desymm)
     932             : 
     933             :       ! Σ^c_λσ^R(iτ) = sum_PR1νS1 [ sum_µS2 (λ0 µS1-S2 | PR1   ) G^occ/vir_µν^S2(i|τ|) ]
     934             :       !                           [ sum_QR2 (σR νS1    | QR1-R2) Ŵ_PQ^R2(iτ)           ]
     935          58 :       DO i_t = 1, bs_env%num_time_freq_points
     936             : 
     937         110 :          DO ispin = 1, bs_env%n_spin
     938             : 
     939          52 :             t1 = m_walltime()
     940             : 
     941          52 :             tau = bs_env%imag_time_points(i_t)
     942             : 
     943             :             ! G^occ_µλ(i|τ|,k) = sum_n^occ C_µn(k)^* e^(-|(ϵ_nk-ϵ_F)τ|) C_λn(k), τ < 0
     944             :             ! G^vir_µλ(i|τ|,k) = sum_n^vir C_µn(k)^* e^(-|(ϵ_nk-ϵ_F)τ|) C_λn(k), τ > 0
     945             :             ! k-point k -> cell S: G^occ/vir_µλ^S(i|τ|) = sum_k w_k G^occ/vir_µλ(i|τ|,k) e^(ikS)
     946          52 :             CALL G_occ_vir(bs_env, tau, Gocc_S, ispin, occ=.TRUE., vir=.FALSE.)
     947          52 :             CALL G_occ_vir(bs_env, tau, Gvir_S, ispin, occ=.FALSE., vir=.TRUE.)
     948             : 
     949             :             ! write data of W^R_PQ(iτ) to W_R 2-index tensor
     950          52 :             CALL fm_MWM_R_t_to_local_tensor_W_R(bs_env%fm_MWM_R_t(:, i_t), W_R, bs_env)
     951             : 
     952             :             ! loop over ΔR = S_1 - R_1 which are local in the tensor subgroup
     953         492 :             DO i_task_Delta_R_local = 1, bs_env%n_tasks_Delta_R_local
     954             : 
     955         440 :                i_cell_Delta_R = bs_env%task_Delta_R(i_task_Delta_R_local)
     956             : 
     957             :                ! for i_task_local (i.e. fixed ΔR = S_1 - R_1) and for all τ (W(iτ) = W(-iτ)):
     958             :                ! M^W_σ0,νS1,PR1 = sum_QR2 ( σ0 νS1 | QR1-R2 ) W(iτ)_QP^R2
     959         440 :                CALL contract_W(t_W, W_R, bs_env, i_cell_Delta_R)
     960             : 
     961             :                ! for τ < 0 and for i_task_local (i.e. fixed ΔR = S_1 - R_1):
     962             :                ! M^G_λ0,νS1,PR1 = sum_µS2 (λ0 µS1-S2 | PR1) G^occ(i|τ|)_µν^S2
     963             :                ! Σ^c_λσ^R(iτ) = sum_PR1νS1 M^G_λ0,νS1,PR1 * M^W_σR,νS1,PR1
     964             :                !                                      where M^W_σR,νS1,PR1 = M^W_σ0,νS1-R,PR1-R
     965             :                CALL contract_to_Sigma(Sigma_c_R_neg_tau, t_W, Gocc_S, i_cell_Delta_R, bs_env, &
     966         440 :                                       occ=.TRUE., vir=.FALSE., clear_t_W=.FALSE.)
     967             : 
     968             :                ! for τ > 0: same as for τ < 0, but G^occ -> G^vir
     969             :                CALL contract_to_Sigma(Sigma_c_R_pos_tau, t_W, Gvir_S, i_cell_Delta_R, bs_env, &
     970         492 :                                       occ=.FALSE., vir=.TRUE., clear_t_W=.TRUE.)
     971             : 
     972             :             END DO ! i_cell_Delta_R_local
     973             : 
     974          52 :             CALL bs_env%para_env%sync()
     975             : 
     976             :             CALL local_dbt_to_global_fm(Sigma_c_R_pos_tau, &
     977             :                                         bs_env%fm_Sigma_c_R_pos_tau(:, i_t, ispin), &
     978          52 :                                         bs_env%mat_ao_ao, bs_env%mat_ao_ao_tensor, bs_env)
     979             : 
     980             :             CALL local_dbt_to_global_fm(Sigma_c_R_neg_tau, &
     981             :                                         bs_env%fm_Sigma_c_R_neg_tau(:, i_t, ispin), &
     982          52 :                                         bs_env%mat_ao_ao, bs_env%mat_ao_ao_tensor, bs_env)
     983             : 
     984         104 :             IF (bs_env%unit_nr > 0) THEN
     985             :                WRITE (bs_env%unit_nr, '(T2,A,I10,A,I3,A,F7.1,A)') &
     986          26 :                   'Computed Σ^c(iτ) for time point   ', i_t, ' /', bs_env%num_time_freq_points, &
     987          52 :                   ',      Execution time', m_walltime() - t1, ' s'
     988             :             END IF
     989             : 
     990             :          END DO ! ispin
     991             : 
     992             :       END DO ! i_t
     993             : 
     994           6 :       CALL destroy_t_1d(Gocc_S)
     995           6 :       CALL destroy_t_1d(Gvir_S)
     996           6 :       CALL destroy_t_1d(W_R)
     997           6 :       CALL destroy_t_1d(Sigma_c_R_neg_tau)
     998           6 :       CALL destroy_t_1d(Sigma_c_R_pos_tau)
     999           6 :       CALL destroy_t_2d(t_W)
    1000             : 
    1001           6 :       CALL timestop(handle)
    1002             : 
    1003           6 :    END SUBROUTINE compute_Sigma_c
    1004             : 
    1005             : ! **************************************************************************************************
    1006             : !> \brief ...
    1007             : !> \param Mi_Vtr_Mi_R ...
    1008             : !> \param bs_env ...
    1009             : !> \param qs_env ...
    1010             : ! **************************************************************************************************
    1011           6 :    SUBROUTINE get_Minv_Vtr_Minv_R(Mi_Vtr_Mi_R, bs_env, qs_env)
    1012             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: Mi_Vtr_Mi_R
    1013             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
    1014             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1015             : 
    1016             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'get_Minv_Vtr_Minv_R'
    1017             : 
    1018           6 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :)     :: M_inv_V_tr_kp, M_kp, Mi_Vtr_Mi_kp, &
    1019             :                                                             V_tr_kp
    1020             :       INTEGER                                            :: handle, i_cell_R, ikp, n_RI, &
    1021             :                                                             nimages_scf, nkp_scf
    1022           6 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: M_R, Mi_Vtr_Mi_R_arr, V_tr_R
    1023             : 
    1024           6 :       CALL timeset(routineN, handle)
    1025             : 
    1026           6 :       nimages_scf = bs_env%nimages_scf_desymm
    1027           6 :       nkp_scf = bs_env%kpoints_scf_desymm%nkp
    1028           6 :       n_RI = bs_env%n_RI
    1029             : 
    1030           6 :       CALL get_V_tr_R(V_tr_R, bs_env%trunc_coulomb, 0.0_dp, bs_env, qs_env)
    1031           6 :       CALL get_V_tr_R(M_R, bs_env%ri_metric, bs_env%regularization_RI, bs_env, qs_env)
    1032             : 
    1033             :       ALLOCATE (V_tr_kp(n_RI, n_RI), M_kp(n_RI, n_RI), M_inv_V_tr_kp(n_RI, n_RI), &
    1034          84 :                 Mi_Vtr_Mi_kp(n_RI, n_RI), Mi_Vtr_Mi_R_arr(n_RI, n_RI, nimages_scf))
    1035        1896 :       Mi_Vtr_Mi_R_arr(:, :, :) = 0.0_dp
    1036             : 
    1037         102 :       DO ikp = 1, nkp_scf
    1038             :          ! trivial parallelization
    1039          96 :          IF (MODULO(ikp, bs_env%para_env%num_pe) .NE. bs_env%para_env%mepos) CYCLE
    1040             :          ! V_tr(k) = sum_R e^ikR V_tr^R
    1041             :          CALL trafo_rs_to_ikp(V_tr_R, V_tr_kp, bs_env%kpoints_scf_desymm%index_to_cell, &
    1042          48 :                               bs_env%kpoints_scf_desymm%xkp(1:3, ikp))
    1043             :          ! M(k)    = sum_R e^ikR M^R
    1044             :          CALL trafo_rs_to_ikp(M_R, M_kp, bs_env%kpoints_scf_desymm%index_to_cell, &
    1045          48 :                               bs_env%kpoints_scf_desymm%xkp(1:3, ikp))
    1046             :          ! M(k) -> M^-1(k)
    1047          48 :          CALL power(M_kp, -1.0_dp, 0.0_dp)
    1048             :          ! M^-1(k) * V_tr(k)
    1049             :          CALL ZGEMM('N', 'N', n_RI, n_RI, n_RI, z_one, M_kp, n_RI, &
    1050          48 :                     V_tr_kp, n_RI, z_zero, M_inv_V_tr_kp, n_RI)
    1051             :          ! Ṽ(k) = M^-1(k) * V_tr(k) * M^-1(k)
    1052             :          CALL ZGEMM('N', 'N', n_RI, n_RI, n_RI, z_one, M_inv_V_tr_kp, n_RI, &
    1053          48 :                     M_kp, n_RI, z_zero, Mi_Vtr_Mi_kp, n_RI)
    1054             :          ! Ṽ^R = sum_k w_k e^-ikR Ṽ(k)
    1055         102 :          CALL add_ikp_to_all_rs(Mi_Vtr_Mi_kp, Mi_Vtr_Mi_R_arr, bs_env%kpoints_scf_desymm, ikp)
    1056             :       END DO
    1057           6 :       CALL bs_env%para_env%sync()
    1058           6 :       CALL bs_env%para_env%sum(Mi_Vtr_Mi_R_arr)
    1059             : 
    1060             :       ! use bs_env%fm_chi_R_t for temporary storage
    1061           6 :       CALL local_array_to_fm(Mi_Vtr_Mi_R_arr, bs_env%fm_chi_R_t(:, 1))
    1062             : 
    1063             :       ! communicate Mi_Vtr_Mi_R to tensor format; full replication in tensor group
    1064          60 :       DO i_cell_R = 1, nimages_scf
    1065             :          CALL fm_to_local_tensor(bs_env%fm_chi_R_t(i_cell_R, 1), bs_env%mat_RI_RI%matrix, &
    1066          60 :                                  bs_env%mat_RI_RI_tensor%matrix, Mi_Vtr_Mi_R(i_cell_R), bs_env)
    1067             :       END DO
    1068             : 
    1069           6 :       CALL timestop(handle)
    1070             : 
    1071          12 :    END SUBROUTINE get_Minv_Vtr_Minv_R
    1072             : 
    1073             : ! **************************************************************************************************
    1074             : !> \brief ...
    1075             : !> \param t_1d ...
    1076             : ! **************************************************************************************************
    1077         204 :    SUBROUTINE destroy_t_1d(t_1d)
    1078             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: t_1d
    1079             : 
    1080             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'destroy_t_1d'
    1081             : 
    1082             :       INTEGER                                            :: handle, i
    1083             : 
    1084         204 :       CALL timeset(routineN, handle)
    1085             : 
    1086        2040 :       DO i = 1, SIZE(t_1d)
    1087        2040 :          CALL dbt_destroy(t_1d(i))
    1088             :       END DO
    1089        2040 :       DEALLOCATE (t_1d)
    1090             : 
    1091         204 :       CALL timestop(handle)
    1092             : 
    1093         204 :    END SUBROUTINE destroy_t_1d
    1094             : 
    1095             : ! **************************************************************************************************
    1096             : !> \brief ...
    1097             : !> \param t_2d ...
    1098             : ! **************************************************************************************************
    1099         116 :    SUBROUTINE destroy_t_2d(t_2d)
    1100             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_2d
    1101             : 
    1102             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'destroy_t_2d'
    1103             : 
    1104             :       INTEGER                                            :: handle, i, j
    1105             : 
    1106         116 :       CALL timeset(routineN, handle)
    1107             : 
    1108         892 :       DO i = 1, SIZE(t_2d, 1)
    1109        7124 :       DO j = 1, SIZE(t_2d, 2)
    1110        7008 :          CALL dbt_destroy(t_2d(i, j))
    1111             :       END DO
    1112             :       END DO
    1113        6348 :       DEALLOCATE (t_2d)
    1114             : 
    1115         116 :       CALL timestop(handle)
    1116             : 
    1117         116 :    END SUBROUTINE destroy_t_2d
    1118             : 
    1119             : ! **************************************************************************************************
    1120             : !> \brief ...
    1121             : !> \param t_W ...
    1122             : !> \param W_R ...
    1123             : !> \param bs_env ...
    1124             : !> \param i_cell_Delta_R ...
    1125             : ! **************************************************************************************************
    1126         496 :    SUBROUTINE contract_W(t_W, W_R, bs_env, i_cell_Delta_R)
    1127             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_W
    1128             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: W_R
    1129             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
    1130             :       INTEGER                                            :: i_cell_Delta_R
    1131             : 
    1132             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'contract_W'
    1133             : 
    1134             :       INTEGER                                            :: handle, i_cell_R1, i_cell_R2, &
    1135             :                                                             i_cell_R2_m_R1, i_cell_S1, &
    1136             :                                                             i_cell_S1_m_R1_p_R2
    1137             :       INTEGER, DIMENSION(3)                              :: cell_DR, cell_R1, cell_R2, cell_R2_m_R1, &
    1138             :                                                             cell_S1, cell_S1_m_R2_p_R1
    1139             :       LOGICAL                                            :: cell_found
    1140        8432 :       TYPE(dbt_type)                                     :: t_3c_int, t_W_tmp
    1141             : 
    1142         496 :       CALL timeset(routineN, handle)
    1143             : 
    1144         496 :       CALL dbt_create(bs_env%t_RI__AO_AO, t_W_tmp)
    1145         496 :       CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_int)
    1146             : 
    1147        4446 :       DO i_cell_R1 = 1, bs_env%nimages_3c
    1148             : 
    1149       15800 :          cell_R1(1:3) = bs_env%index_to_cell_3c(i_cell_R1, 1:3)
    1150       15800 :          cell_DR(1:3) = bs_env%index_to_cell_Delta_R(i_cell_Delta_R, 1:3)
    1151             : 
    1152             :          ! S_1 = R_1 + ΔR (from ΔR = S_1 - R_1)
    1153             :          CALL add_R(cell_R1, cell_DR, bs_env%index_to_cell_3c, cell_S1, &
    1154        3950 :                     cell_found, bs_env%cell_to_index_3c, i_cell_S1)
    1155        3950 :          IF (.NOT. cell_found) CYCLE
    1156             : 
    1157       19396 :          DO i_cell_R2 = 1, bs_env%nimages_scf_desymm
    1158             : 
    1159       53820 :             cell_R2(1:3) = bs_env%kpoints_scf_desymm%index_to_cell(i_cell_R2, 1:3)
    1160             : 
    1161             :             ! R_2 - R_1
    1162             :             CALL add_R(cell_R2, -cell_R1, bs_env%index_to_cell_3c, cell_R2_m_R1, &
    1163       53820 :                        cell_found, bs_env%cell_to_index_3c, i_cell_R2_m_R1)
    1164       13455 :             IF (.NOT. cell_found) CYCLE
    1165             : 
    1166             :             ! S_1 - R_1 + R_2
    1167             :             CALL add_R(cell_S1, cell_R2_m_R1, bs_env%index_to_cell_3c, cell_S1_m_R2_p_R1, &
    1168        7455 :                        cell_found, bs_env%cell_to_index_3c, i_cell_S1_m_R1_p_R2)
    1169        7455 :             IF (.NOT. cell_found) CYCLE
    1170             : 
    1171        4705 :             CALL get_t_3c_int(t_3c_int, bs_env, i_cell_S1_m_R1_p_R2, i_cell_R2_m_R1)
    1172             : 
    1173             :             ! M^W_σ0,νS1,PR1 = sum_QR2 ( σ0     νS1       | QR1-R2 ) W_QP^R2
    1174             :             !                = sum_QR2 ( σR2-R1 νS1-R1+R2 | Q0     ) W_QP^R2
    1175             :             ! for ΔR = S_1 - R_1
    1176             :             CALL dbt_contract(alpha=1.0_dp, &
    1177             :                               tensor_1=W_R(i_cell_R2), &
    1178             :                               tensor_2=t_3c_int, &
    1179             :                               beta=0.0_dp, &
    1180             :                               tensor_3=t_W_tmp, &
    1181             :                               contract_1=[1], notcontract_1=[2], map_1=[1], &
    1182             :                               contract_2=[1], notcontract_2=[2, 3], map_2=[2, 3], &
    1183        4705 :                               filter_eps=bs_env%eps_filter)
    1184             : 
    1185             :             ! reorder tensor
    1186             :             CALL dbt_copy(t_W_tmp, t_W(i_cell_S1, i_cell_R1), order=[1, 2, 3], &
    1187       22110 :                           move_data=.TRUE., summation=.TRUE.)
    1188             : 
    1189             :          END DO ! i_cell_R2
    1190             : 
    1191             :       END DO ! i_cell_R1
    1192             : 
    1193         496 :       CALL dbt_destroy(t_W_tmp)
    1194         496 :       CALL dbt_destroy(t_3c_int)
    1195             : 
    1196         496 :       CALL timestop(handle)
    1197             : 
    1198         496 :    END SUBROUTINE contract_W
    1199             : 
    1200             : ! **************************************************************************************************
    1201             : !> \brief ...
    1202             : !> \param Sigma_R ...
    1203             : !> \param t_W ...
    1204             : !> \param G_S ...
    1205             : !> \param i_cell_Delta_R ...
    1206             : !> \param bs_env ...
    1207             : !> \param occ ...
    1208             : !> \param vir ...
    1209             : !> \param clear_t_W ...
    1210             : ! **************************************************************************************************
    1211         936 :    SUBROUTINE contract_to_Sigma(Sigma_R, t_W, G_S, i_cell_Delta_R, bs_env, occ, vir, clear_t_W)
    1212             :       TYPE(dbt_type), DIMENSION(:)                       :: Sigma_R
    1213             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :)       :: t_W
    1214             :       TYPE(dbt_type), DIMENSION(:)                       :: G_S
    1215             :       INTEGER                                            :: i_cell_Delta_R
    1216             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
    1217             :       LOGICAL                                            :: occ, vir, clear_t_W
    1218             : 
    1219             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'contract_to_Sigma'
    1220             : 
    1221             :       INTEGER :: handle, handle2, i_cell_m_R1, i_cell_R, i_cell_R1, i_cell_R1_minus_R, i_cell_S1, &
    1222             :          i_cell_S1_minus_R, i_cell_S1_p_S2_m_R1, i_cell_S2
    1223             :       INTEGER, DIMENSION(3)                              :: cell_DR, cell_m_R1, cell_R, cell_R1, &
    1224             :                                                             cell_R1_minus_R, cell_S1, &
    1225             :                                                             cell_S1_minus_R, cell_S1_p_S2_m_R1, &
    1226             :                                                             cell_S2
    1227             :       LOGICAL                                            :: cell_found
    1228             :       REAL(KIND=dp)                                      :: sign_Sigma
    1229       23400 :       TYPE(dbt_type)                                     :: t_3c_int, t_G, t_G_2
    1230             : 
    1231         936 :       CALL timeset(routineN, handle)
    1232             : 
    1233         936 :       CPASSERT(occ .EQV. (.NOT. vir))
    1234         936 :       IF (occ) sign_Sigma = -1.0_dp
    1235         936 :       IF (vir) sign_Sigma = 1.0_dp
    1236             : 
    1237         936 :       CALL dbt_create(bs_env%t_RI_AO__AO, t_G)
    1238         936 :       CALL dbt_create(bs_env%t_RI_AO__AO, t_G_2)
    1239         936 :       CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_int)
    1240             : 
    1241        8346 :       DO i_cell_R1 = 1, bs_env%nimages_3c
    1242             : 
    1243       29640 :          cell_R1(1:3) = bs_env%index_to_cell_3c(i_cell_R1, 1:3)
    1244       29640 :          cell_DR(1:3) = bs_env%index_to_cell_Delta_R(i_cell_Delta_R, 1:3)
    1245             : 
    1246             :          ! S_1 = R_1 + ΔR (from ΔR = S_1 - R_1)
    1247             :          CALL add_R(cell_R1, cell_DR, bs_env%index_to_cell_3c, cell_S1, cell_found, &
    1248        7410 :                     bs_env%cell_to_index_3c, i_cell_S1)
    1249        7410 :          IF (.NOT. cell_found) CYCLE
    1250             : 
    1251       28050 :          DO i_cell_S2 = 1, bs_env%nimages_scf_desymm
    1252             : 
    1253      100980 :             cell_S2(1:3) = bs_env%kpoints_scf_desymm%index_to_cell(i_cell_S2, 1:3)
    1254      100980 :             cell_m_R1(1:3) = -cell_R1(1:3)
    1255      100980 :             cell_S1_p_S2_m_R1(1:3) = cell_S1(1:3) + cell_S2(1:3) - cell_R1(1:3)
    1256             : 
    1257       25245 :             CALL is_cell_in_index_to_cell(cell_m_R1, bs_env%index_to_cell_3c, cell_found)
    1258       25245 :             IF (.NOT. cell_found) CYCLE
    1259             : 
    1260       22086 :             CALL is_cell_in_index_to_cell(cell_S1_p_S2_m_R1, bs_env%index_to_cell_3c, cell_found)
    1261       22086 :             IF (.NOT. cell_found) CYCLE
    1262             : 
    1263       10486 :             i_cell_m_R1 = bs_env%cell_to_index_3c(cell_m_R1(1), cell_m_R1(2), cell_m_R1(3))
    1264             :             i_cell_S1_p_S2_m_R1 = bs_env%cell_to_index_3c(cell_S1_p_S2_m_R1(1), &
    1265             :                                                           cell_S1_p_S2_m_R1(2), &
    1266       10486 :                                                           cell_S1_p_S2_m_R1(3))
    1267             : 
    1268       10486 :             CALL timeset(routineN//"_3c_x_G", handle2)
    1269             : 
    1270       10486 :             CALL get_t_3c_int(t_3c_int, bs_env, i_cell_m_R1, i_cell_S1_p_S2_m_R1)
    1271             : 
    1272             :             ! M_λ0,νS1,PR1 = sum_µS2 ( λ0   µS1-S2    | PR1 ) G^occ/vir_µν^S2(i|τ|)
    1273             :             !              = sum_µS2 ( λ-R1 µS1-S2-R1 | P0  ) G^occ/vir_µν^S2(i|τ|)
    1274             :             ! for ΔR = S_1 - R_1
    1275             :             CALL dbt_contract(alpha=1.0_dp, &
    1276             :                               tensor_1=G_S(i_cell_S2), &
    1277             :                               tensor_2=t_3c_int, &
    1278             :                               beta=1.0_dp, &
    1279             :                               tensor_3=t_G, &
    1280             :                               contract_1=[2], notcontract_1=[1], map_1=[3], &
    1281             :                               contract_2=[3], notcontract_2=[1, 2], map_2=[1, 2], &
    1282       10486 :                               filter_eps=bs_env%eps_filter)
    1283             : 
    1284       38536 :             CALL timestop(handle2)
    1285             : 
    1286             :          END DO ! i_cell_S2
    1287             : 
    1288        2805 :          CALL dbt_copy(t_G, t_G_2, order=[1, 3, 2], move_data=.TRUE.)
    1289             : 
    1290        2805 :          CALL timeset(routineN//"_contract", handle2)
    1291             : 
    1292       28050 :          DO i_cell_R = 1, bs_env%nimages_scf_desymm
    1293             : 
    1294      100980 :             cell_R = bs_env%kpoints_scf_desymm%index_to_cell(i_cell_R, 1:3)
    1295             : 
    1296             :             ! R_1 - R
    1297             :             CALL add_R(cell_R1, -cell_R, bs_env%index_to_cell_3c, cell_R1_minus_R, &
    1298      100980 :                        cell_found, bs_env%cell_to_index_3c, i_cell_R1_minus_R)
    1299       25245 :             IF (.NOT. cell_found) CYCLE
    1300             : 
    1301             :             ! S_1 - R
    1302             :             CALL add_R(cell_S1, -cell_R, bs_env%index_to_cell_3c, cell_S1_minus_R, &
    1303       59136 :                        cell_found, bs_env%cell_to_index_3c, i_cell_S1_minus_R)
    1304       14784 :             IF (.NOT. cell_found) CYCLE
    1305             : 
    1306             :             ! Σ_λσ^R = sum_PR1νS1 M^G_λ0,νS1,PR1 M^W_σR,νS1,PR1, where
    1307             :             ! M^G_λ0,νS1,PR1 = sum_µS2 (λ0 µS1-S2 | PR1) G_µν^S2
    1308             :             ! M^W_σR,νS1,PR1 = sum_QR2 (σR νS1 | QR1-R2) W_PQ^R2 = M^W_σ0,νS1-R,PR1-R
    1309             :             CALL dbt_contract(alpha=sign_Sigma, &
    1310             :                               tensor_1=t_G_2, &
    1311             :                               tensor_2=t_W(i_cell_S1_minus_R, i_cell_R1_minus_R), &
    1312             :                               beta=1.0_dp, &
    1313             :                               tensor_3=Sigma_R(i_cell_R), &
    1314             :                               contract_1=[1, 2], notcontract_1=[3], map_1=[1], &
    1315             :                               contract_2=[1, 2], notcontract_2=[3], map_2=[2], &
    1316       28050 :                               filter_eps=bs_env%eps_filter)
    1317             : 
    1318             :          END DO ! i_cell_R
    1319             : 
    1320        2805 :          CALL dbt_clear(t_G_2)
    1321             : 
    1322       13956 :          CALL timestop(handle2)
    1323             : 
    1324             :       END DO ! i_cell_R1
    1325             : 
    1326             :       ! release memory
    1327         936 :       IF (clear_t_W) THEN
    1328        4446 :          DO i_cell_S1 = 1, bs_env%nimages_3c
    1329       41836 :             DO i_cell_R1 = 1, bs_env%nimages_3c
    1330       41340 :                CALL dbt_clear(t_W(i_cell_S1, i_cell_R1))
    1331             :             END DO
    1332             :          END DO
    1333             :       END IF
    1334             : 
    1335         936 :       CALL dbt_destroy(t_G)
    1336         936 :       CALL dbt_destroy(t_G_2)
    1337         936 :       CALL dbt_destroy(t_3c_int)
    1338             : 
    1339         936 :       CALL timestop(handle)
    1340             : 
    1341         936 :    END SUBROUTINE contract_to_Sigma
    1342             : 
    1343             : ! **************************************************************************************************
    1344             : !> \brief ...
    1345             : !> \param fm_W_R ...
    1346             : !> \param W_R ...
    1347             : !> \param bs_env ...
    1348             : ! **************************************************************************************************
    1349          52 :    SUBROUTINE fm_MWM_R_t_to_local_tensor_W_R(fm_W_R, W_R, bs_env)
    1350             :       TYPE(cp_fm_type), DIMENSION(:)                     :: fm_W_R
    1351             :       TYPE(dbt_type), ALLOCATABLE, DIMENSION(:)          :: W_R
    1352             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
    1353             : 
    1354             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'fm_MWM_R_t_to_local_tensor_W_R'
    1355             : 
    1356             :       INTEGER                                            :: handle, i_cell_R
    1357             : 
    1358          52 :       CALL timeset(routineN, handle)
    1359             : 
    1360             :       ! communicate fm_W_R to tensor W_R; full replication in tensor group
    1361         520 :       DO i_cell_R = 1, bs_env%nimages_scf_desymm
    1362             :          CALL fm_to_local_tensor(fm_W_R(i_cell_R), bs_env%mat_RI_RI%matrix, &
    1363         520 :                                  bs_env%mat_RI_RI_tensor%matrix, W_R(i_cell_R), bs_env)
    1364             :       END DO
    1365             : 
    1366          52 :       CALL timestop(handle)
    1367             : 
    1368          52 :    END SUBROUTINE fm_MWM_R_t_to_local_tensor_W_R
    1369             : 
    1370             : ! **************************************************************************************************
    1371             : !> \brief ...
    1372             : !> \param bs_env ...
    1373             : ! **************************************************************************************************
    1374           6 :    SUBROUTINE compute_QP_energies(bs_env)
    1375             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
    1376             : 
    1377             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_QP_energies'
    1378             : 
    1379             :       INTEGER                                            :: handle, ikp, ispin, j_t
    1380             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: Sigma_x_ikp_n
    1381             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: Sigma_c_ikp_n_freq, Sigma_c_ikp_n_time
    1382             :       TYPE(cp_cfm_type)                                  :: cfm_mo_coeff
    1383             : 
    1384           6 :       CALL timeset(routineN, handle)
    1385             : 
    1386           6 :       CALL cp_cfm_create(cfm_mo_coeff, bs_env%fm_s_Gamma%matrix_struct)
    1387          18 :       ALLOCATE (Sigma_x_ikp_n(bs_env%n_ao))
    1388          30 :       ALLOCATE (Sigma_c_ikp_n_time(bs_env%n_ao, bs_env%num_time_freq_points, 2))
    1389          24 :       ALLOCATE (Sigma_c_ikp_n_freq(bs_env%n_ao, bs_env%num_time_freq_points, 2))
    1390             : 
    1391          12 :       DO ispin = 1, bs_env%n_spin
    1392             : 
    1393         232 :          DO ikp = 1, bs_env%nkp_bs_and_DOS
    1394             : 
    1395             :             ! 1. get C_µn(k)
    1396         220 :             CALL cp_cfm_to_cfm(bs_env%cfm_mo_coeff_kp(ikp, ispin), cfm_mo_coeff)
    1397             : 
    1398             :             ! 2. Σ^x_µν(k) = sum_R Σ^x_µν^R e^ikR
    1399             :             !    Σ^x_nn(k) = sum_µν C^*_µn(k) Σ^x_µν(k) C_νn(k)
    1400         220 :             CALL trafo_to_k_and_nn(bs_env%fm_Sigma_x_R, Sigma_x_ikp_n, cfm_mo_coeff, bs_env, ikp)
    1401             : 
    1402             :             ! 3. Σ^c_µν(k,+/-i|τ_j|) = sum_R Σ^c_µν^R(+/-i|τ_j|) e^ikR
    1403             :             !    Σ^c_nn(k,+/-i|τ_j|) = sum_µν C^*_µn(k) Σ^c_µν(k,+/-i|τ_j|) C_νn(k)
    1404        2292 :             DO j_t = 1, bs_env%num_time_freq_points
    1405             :                CALL trafo_to_k_and_nn(bs_env%fm_Sigma_c_R_pos_tau(:, j_t, ispin), &
    1406        2072 :                                       Sigma_c_ikp_n_time(:, j_t, 1), cfm_mo_coeff, bs_env, ikp)
    1407             :                CALL trafo_to_k_and_nn(bs_env%fm_Sigma_c_R_neg_tau(:, j_t, ispin), &
    1408        2292 :                                       Sigma_c_ikp_n_time(:, j_t, 2), cfm_mo_coeff, bs_env, ikp)
    1409             :             END DO
    1410             : 
    1411             :             ! 4. Σ^c_nn(k_i,iω) = ∫ from -∞ to ∞ dτ e^-iωτ Σ^c_nn(k_i,iτ)
    1412         220 :             CALL time_to_freq(bs_env, Sigma_c_ikp_n_time, Sigma_c_ikp_n_freq, ispin)
    1413             : 
    1414             :             ! 5. Analytic continuation Σ^c_nn(k_i,iω) -> Σ^c_nn(k_i,ϵ) and
    1415             :             !    ϵ_nk_i^GW = ϵ_nk_i^DFT + Σ^c_nn(k_i,ϵ) + Σ^x_nn(k_i) - v^xc_nn(k_i)
    1416             :             CALL analyt_conti_and_print(bs_env, Sigma_c_ikp_n_freq, Sigma_x_ikp_n, &
    1417             :                                         bs_env%v_xc_n(:, ikp, ispin), &
    1418         226 :                                         bs_env%eigenval_scf(:, ikp, ispin), ikp, ispin)
    1419             : 
    1420             :          END DO ! ikp
    1421             : 
    1422             :       END DO ! ispin
    1423             : 
    1424           6 :       CALL get_all_VBM_CBM_bandgaps(bs_env)
    1425             : 
    1426           6 :       CALL cp_cfm_release(cfm_mo_coeff)
    1427             : 
    1428           6 :       CALL timestop(handle)
    1429             : 
    1430          12 :    END SUBROUTINE compute_QP_energies
    1431             : 
    1432             : ! **************************************************************************************************
    1433             : !> \brief ...
    1434             : !> \param fm_rs ...
    1435             : !> \param array_ikp_n ...
    1436             : !> \param cfm_mo_coeff ...
    1437             : !> \param bs_env ...
    1438             : !> \param ikp ...
    1439             : ! **************************************************************************************************
    1440        4364 :    SUBROUTINE trafo_to_k_and_nn(fm_rs, array_ikp_n, cfm_mo_coeff, bs_env, ikp)
    1441             :       TYPE(cp_fm_type), DIMENSION(:)                     :: fm_rs
    1442             :       REAL(KIND=dp), DIMENSION(:)                        :: array_ikp_n
    1443             :       TYPE(cp_cfm_type)                                  :: cfm_mo_coeff
    1444             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
    1445             :       INTEGER                                            :: ikp
    1446             : 
    1447             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'trafo_to_k_and_nn'
    1448             : 
    1449             :       INTEGER                                            :: handle, n_ao
    1450             :       TYPE(cp_cfm_type)                                  :: cfm_ikp, cfm_tmp
    1451             :       TYPE(cp_fm_type)                                   :: fm_ikp_re
    1452             : 
    1453        4364 :       CALL timeset(routineN, handle)
    1454             : 
    1455        4364 :       CALL cp_cfm_create(cfm_ikp, cfm_mo_coeff%matrix_struct)
    1456        4364 :       CALL cp_cfm_create(cfm_tmp, cfm_mo_coeff%matrix_struct)
    1457        4364 :       CALL cp_fm_create(fm_ikp_re, cfm_mo_coeff%matrix_struct)
    1458             : 
    1459             :       ! Σ_µν(k_i) = sum_R e^ik_iR Σ_µν^R
    1460        4364 :       CALL fm_trafo_rs_to_ikp(cfm_ikp, fm_rs, bs_env%kpoints_DOS, ikp)
    1461             : 
    1462        4364 :       n_ao = bs_env%n_ao
    1463             : 
    1464             :       ! Σ_nm(k_i) = sum_µν C^*_µn(k_i) Σ_µν(k_i) C_νn(k_i)
    1465        4364 :       CALL parallel_gemm('N', 'N', n_ao, n_ao, n_ao, z_one, cfm_ikp, cfm_mo_coeff, z_zero, cfm_tmp)
    1466        4364 :       CALL parallel_gemm('C', 'N', n_ao, n_ao, n_ao, z_one, cfm_mo_coeff, cfm_tmp, z_zero, cfm_ikp)
    1467             : 
    1468             :       ! get Σ_nn(k_i) which is a real quantity as Σ^x and Σ^c(iτ) is Hermitian
    1469        4364 :       CALL cp_cfm_to_fm(cfm_ikp, fm_ikp_re)
    1470        4364 :       CALL cp_fm_get_diag(fm_ikp_re, array_ikp_n)
    1471             : 
    1472        4364 :       CALL cp_cfm_release(cfm_ikp)
    1473        4364 :       CALL cp_cfm_release(cfm_tmp)
    1474        4364 :       CALL cp_fm_release(fm_ikp_re)
    1475             : 
    1476        4364 :       CALL timestop(handle)
    1477             : 
    1478        4364 :    END SUBROUTINE trafo_to_k_and_nn
    1479             : 
    1480             : END MODULE gw_small_cell_full_kp

Generated by: LCOV version 1.15