LCOV - code coverage report
Current view: top level - src - gw_small_cell_full_kp.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 99.6 % 486 484
Test Date: 2025-07-25 12:55:17 Functions: 100.0 % 22 22

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

Generated by: LCOV version 2.0-1