LCOV - code coverage report
Current view: top level - src - qs_tddfpt2_bse_utils.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:3db43b4) Lines: 61.6 % 242 149
Test Date: 2026-04-03 06:55:30 Functions: 80.0 % 5 4

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : MODULE qs_tddfpt2_bse_utils
       9              :    USE cp_blacs_env,                    ONLY: cp_blacs_env_type
      10              :    USE cp_dbcsr_api,                    ONLY: dbcsr_create,&
      11              :                                               dbcsr_p_type,&
      12              :                                               dbcsr_release,&
      13              :                                               dbcsr_set,&
      14              :                                               dbcsr_type
      15              :    USE cp_dbcsr_cp2k_link,              ONLY: cp_dbcsr_alloc_block_from_nbl
      16              :    USE cp_dbcsr_operations,             ONLY: copy_dbcsr_to_fm,&
      17              :                                               copy_fm_to_dbcsr,&
      18              :                                               cp_dbcsr_sm_fm_multiply
      19              :    USE cp_fm_basic_linalg,              ONLY: cp_fm_column_scale,&
      20              :                                               cp_fm_matvec,&
      21              :                                               cp_fm_scale_and_add
      22              :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      23              :                                               cp_fm_struct_release,&
      24              :                                               cp_fm_struct_type
      25              :    USE cp_fm_types,                     ONLY: &
      26              :         cp_fm_create, cp_fm_get_info, cp_fm_release, cp_fm_set_all, cp_fm_set_element, &
      27              :         cp_fm_to_fm, cp_fm_to_fm_submat, cp_fm_type, cp_fm_vectorssum, cp_fm_write_formatted
      28              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      29              :                                               cp_logger_get_default_io_unit,&
      30              :                                               cp_logger_type
      31              :    USE exstates_types,                  ONLY: excited_energy_type
      32              :    USE kinds,                           ONLY: dp
      33              :    USE message_passing,                 ONLY: mp_para_env_type
      34              :    USE parallel_gemm_api,               ONLY: parallel_gemm
      35              :    USE qs_environment_types,            ONLY: get_qs_env,&
      36              :                                               qs_environment_type
      37              :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
      38              :    USE qs_tddfpt2_types,                ONLY: tddfpt_ground_state_mos
      39              : #include "./base/base_uses.f90"
      40              : 
      41              :    IMPLICIT NONE
      42              : 
      43              :    PRIVATE
      44              : 
      45              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_tddfpt2_bse_utils'
      46              : 
      47              :    LOGICAL, PARAMETER, PRIVATE          :: debug_this_module = .FALSE.
      48              :    ! number of first derivative components (3: d/dx, d/dy, d/dz)
      49              :    INTEGER, PARAMETER, PRIVATE          :: nderivs = 3
      50              :    INTEGER, PARAMETER, PRIVATE          :: maxspins = 2
      51              : 
      52              :    PUBLIC:: tddfpt_apply_bse_debug, tddfpt_apply_bse
      53              :    PUBLIC:: zeroth_order_gw
      54              : 
      55              : CONTAINS
      56              : ! **************************************************************************************************
      57              : !> \brief ...
      58              : !> \param qs_env ...
      59              : !> \param Aop_evects ...
      60              : !> \param evects ...
      61              : !> \param S_evects ...
      62              : !> \param gs_mos ...
      63              : !> \param matrix_s ...
      64              : !> \param matrix_ks ...
      65              : ! **************************************************************************************************
      66           20 :    SUBROUTINE zeroth_order_gw(qs_env, Aop_evects, evects, S_evects, gs_mos, matrix_s, matrix_ks)
      67              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      68              :       TYPE(cp_fm_type), DIMENSION(:, :), INTENT(INOUT)   :: Aop_evects
      69              :       TYPE(cp_fm_type), DIMENSION(:, :), INTENT(IN)      :: evects, S_evects
      70              :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
      71              :          INTENT(in)                                      :: gs_mos
      72              :       TYPE(dbcsr_type), INTENT(in), POINTER              :: matrix_s
      73              :       TYPE(dbcsr_p_type), DIMENSION(:), INTENT(in)       :: matrix_ks
      74              : 
      75              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'zeroth_order_gw'
      76              : 
      77              :       INTEGER                                            :: handle, i, ispin, ivect, j, nactive, &
      78              :                                                             nao, nmo, nspins, nvects, occ, virt
      79           20 :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:)           :: gw_occ, gw_virt
      80              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
      81              :       TYPE(cp_fm_struct_type), POINTER                   :: fmstruct, matrix_struct
      82              :       TYPE(cp_fm_type)                                   :: fms, hevec, matrixtmp, matrixtmp2, &
      83              :                                                             matrixtmp3, Sweighted_vect, &
      84              :                                                             weighted_vect
      85              :       TYPE(dbcsr_type)                                   :: matrixf
      86              :       TYPE(excited_energy_type), POINTER                 :: ex_env
      87              :       TYPE(mp_para_env_type), POINTER                    :: para_env
      88              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
      89           20 :          POINTER                                         :: sab_orb
      90              : 
      91           20 :       CALL timeset(routineN, handle)
      92              : 
      93           20 :       NULLIFY (ex_env, sab_orb)
      94           20 :       CALL get_qs_env(qs_env, exstate_env=ex_env, sab_orb=sab_orb)
      95              : 
      96           20 :       nspins = SIZE(matrix_ks, 1)
      97           20 :       nspins = SIZE(evects, 1)
      98           20 :       nvects = SIZE(evects, 2)
      99              : 
     100           40 :       DO ispin = 1, nspins
     101              : 
     102           20 :          CPASSERT(.NOT. ASSOCIATED(gs_mos(ispin)%evals_occ_matrix))
     103              : 
     104           20 :          CALL dbcsr_create(matrixf, template=matrix_s)
     105           20 :          nmo = SIZE(ex_env%gw_eigen)
     106              :          CALL cp_fm_get_info(matrix=evects(ispin, 1), matrix_struct=matrix_struct, &
     107           20 :                              nrow_global=nao, ncol_global=nactive)
     108           20 :          NULLIFY (blacs_env, para_env)
     109           20 :          CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
     110              : 
     111           20 :          occ = SIZE(gs_mos(ispin)%evals_occ)
     112           20 :          nactive = gs_mos(ispin)%nmo_active
     113           20 :          nmo = SIZE(ex_env%gw_eigen)
     114           20 :          virt = SIZE(gs_mos(ispin)%evals_virt)
     115           20 :          NULLIFY (fmstruct)
     116              :          CALL cp_fm_struct_create(fmstruct=fmstruct, para_env=para_env, &
     117           20 :                                   context=blacs_env, nrow_global=virt, ncol_global=virt)
     118           20 :          CALL cp_fm_create(matrixtmp, fmstruct)
     119           20 :          CALL cp_fm_struct_release(fmstruct)
     120              : 
     121           20 :          NULLIFY (fmstruct)
     122              :          CALL cp_fm_struct_create(fmstruct=fmstruct, para_env=para_env, &
     123           20 :                                   context=blacs_env, nrow_global=virt, ncol_global=nao)
     124           20 :          CALL cp_fm_create(matrixtmp2, fmstruct)
     125           20 :          CALL cp_fm_struct_release(fmstruct)
     126              : 
     127           20 :          NULLIFY (fmstruct)
     128              :          CALL cp_fm_struct_create(fmstruct=fmstruct, para_env=para_env, &
     129           20 :                                   context=blacs_env, nrow_global=nao, ncol_global=nao)
     130           20 :          CALL cp_fm_create(matrixtmp3, fmstruct)
     131           20 :          CALL cp_fm_create(fms, fmstruct)
     132           20 :          CALL cp_fm_struct_release(fmstruct)
     133           20 :          CALL cp_dbcsr_alloc_block_from_nbl(matrixf, sab_orb)
     134              : 
     135              : !--add virt eigenvalues
     136           20 :          CALL dbcsr_set(matrixf, 0.0_dp)
     137           20 :          CALL cp_fm_create(weighted_vect, gs_mos(ispin)%mos_virt%matrix_struct)
     138           20 :          CALL cp_fm_create(Sweighted_vect, gs_mos(ispin)%mos_virt%matrix_struct)
     139           20 :          CALL cp_fm_to_fm(gs_mos(ispin)%mos_virt, weighted_vect)
     140           20 :          CALL copy_dbcsr_to_fm(matrix_s, fms)
     141              : 
     142           60 :          ALLOCATE (gw_virt(virt))
     143           60 :          ALLOCATE (gw_occ(nactive))
     144          400 :          gw_virt(1:virt) = ex_env%gw_eigen(occ + 1:nmo)
     145          100 :          DO i = 1, nactive
     146           80 :             j = gs_mos(ispin)%index_active(i)
     147          100 :             gw_occ(i) = ex_env%gw_eigen(j)
     148              :          END DO
     149              : 
     150           20 :          CALL cp_fm_set_all(matrixtmp, 0.0_dp)
     151          400 :          DO i = 1, virt
     152          400 :             CALL cp_fm_set_element(matrixtmp, i, i, gw_virt(i))
     153              :          END DO
     154           20 :          DEALLOCATE (gw_virt)
     155           20 :          CALL parallel_gemm('N', 'N', nao, virt, nao, 1.0_dp, fms, weighted_vect, 0.0_dp, Sweighted_vect)
     156           20 :          CALL parallel_gemm('N', 'T', virt, nao, virt, 1.0_dp, matrixtmp, Sweighted_vect, 0.0_dp, matrixtmp2)
     157           20 :          CALL parallel_gemm('N', 'N', nao, nao, virt, 1.0_dp, Sweighted_vect, matrixtmp2, 0.0_dp, matrixtmp3)
     158           20 :          CALL copy_fm_to_dbcsr(matrixtmp3, matrixf)
     159              : 
     160           20 :          CALL cp_fm_release(weighted_vect)
     161           20 :          CALL cp_fm_release(Sweighted_vect)
     162           20 :          CALL cp_fm_release(fmS)
     163              : !--add occ eigenvalues
     164              :          CALL cp_fm_get_info(matrix=evects(ispin, 1), matrix_struct=matrix_struct, &
     165           20 :                              nrow_global=nao, ncol_global=nactive)
     166           20 :          CALL cp_fm_create(hevec, matrix_struct)
     167              : 
     168          212 :          DO ivect = 1, nvects
     169              :             CALL cp_dbcsr_sm_fm_multiply(matrixf, evects(ispin, ivect), &
     170              :                                          Aop_evects(ispin, ivect), ncol=nactive, &
     171          192 :                                          alpha=1.0_dp, beta=1.0_dp)
     172              : 
     173          192 :             CALL cp_fm_to_fm(S_evects(ispin, ivect), hevec)
     174          192 :             CALL cp_fm_column_scale(hevec, gw_occ)
     175              : 
     176          212 :             CALL cp_fm_scale_and_add(1.0_dp, Aop_evects(ispin, ivect), -1.0_dp, hevec)
     177              :          END DO !ivect
     178           20 :          DEALLOCATE (gw_occ)
     179              : 
     180           20 :          CALL cp_fm_release(matrixtmp)
     181           20 :          CALL cp_fm_release(matrixtmp2)
     182           20 :          CALL cp_fm_release(matrixtmp3)
     183              : 
     184           20 :          CALL dbcsr_release(matrixf)
     185          160 :          CALL cp_fm_release(hevec)
     186              :       END DO !ispin
     187              : 
     188           20 :       virt = SIZE(Aop_evects, 2)
     189           20 :       CALL timestop(handle)
     190              : 
     191           40 :    END SUBROUTINE zeroth_order_gw
     192              : 
     193              : ! **************************************************************************************************
     194              : !> \brief Update action of TDDFPT operator on trial vectors by adding BSE W term.
     195              : !> \brief debug version
     196              : !> \param Aop_evects ...
     197              : !> \param evects ...
     198              : !> \param gs_mos ...
     199              : !> \param qs_env ...
     200              : ! **************************************************************************************************
     201            0 :    SUBROUTINE tddfpt_apply_bse_debug(Aop_evects, evects, gs_mos, qs_env)
     202              : 
     203              :       TYPE(cp_fm_type), DIMENSION(:, :), INTENT(INOUT)   :: Aop_evects
     204              :       TYPE(cp_fm_type), DIMENSION(:, :), INTENT(IN)      :: evects
     205              :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
     206              :          INTENT(in)                                      :: gs_mos
     207              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     208              : 
     209              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_apply_bse_debug'
     210              : 
     211              :       INTEGER :: a_nao_col, a_virt_col, b_nao_col, c_virt_col, handle, i_occ_row, i_row_global, &
     212              :          ii, iounit, ispin, ivect, j_col_global, j_occ_row, jj, k_occ_col, mu_col_global, nao, &
     213              :          ncol_block, ncol_block_bse, ncol_block_cs, ncol_local, ncol_local_bse, ncol_local_cs, &
     214              :          nrow_block, nrow_block_bse, nrow_block_cs, nrow_local, nrow_local_bse, nrow_local_cs, &
     215              :          nspins, nvects, nvirt
     216              :       INTEGER, DIMENSION(2)                              :: nactive
     217            0 :       INTEGER, DIMENSION(:), POINTER                     :: col_indices, col_indices_bse, &
     218            0 :                                                             col_indices_cs, row_indices, &
     219            0 :                                                             row_indices_bse, row_indices_cs
     220              :       REAL(KIND=dp)                                      :: alpha
     221              :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :), &
     222            0 :          POINTER                                         :: my_block, my_bse_w_matrix_MO, my_CSvirt
     223              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     224              :       TYPE(cp_fm_struct_type), POINTER                   :: fmstruct, matrix_struct
     225              :       TYPE(cp_fm_type)                                   :: CSvirt, fms, WXaoao, WXmat2, WXvirtao
     226              :       TYPE(cp_fm_type), POINTER                          :: bse_w_matrix_MO
     227              :       TYPE(cp_logger_type), POINTER                      :: logger
     228            0 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
     229              :       TYPE(excited_energy_type), POINTER                 :: ex_env
     230              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     231              : 
     232            0 :       NULLIFY (logger) !get output_unit
     233            0 :       logger => cp_get_default_logger()
     234            0 :       iounit = cp_logger_get_default_io_unit(logger)
     235              : 
     236            0 :       CALL timeset(routineN, handle)
     237              : 
     238            0 :       nspins = SIZE(evects, 1)
     239            0 :       nvects = SIZE(evects, 2)
     240              :       IF (nspins > 1) THEN
     241              :          alpha = 1.0_dp
     242              :       ELSE
     243              :          alpha = 2.0_dp
     244              :       END IF
     245            0 :       CALL cp_fm_get_info(gs_mos(1)%mos_occ, nrow_global=nao)
     246            0 :       DO ispin = 1, nspins
     247            0 :          CALL cp_fm_get_info(evects(ispin, 1), ncol_global=nactive(ispin))
     248              :       END DO
     249              : 
     250            0 :       NULLIFY (ex_env, para_env, blacs_env, matrix_s)
     251              :       CALL get_qs_env(qs_env, exstate_env=ex_env, para_env=para_env, blacs_env=blacs_env, &
     252            0 :                       matrix_s=matrix_s)
     253              : 
     254              :       CALL cp_fm_struct_create(fmstruct=fmstruct, para_env=para_env, &
     255            0 :                                context=blacs_env, nrow_global=nao, ncol_global=nao)
     256            0 :       CALL cp_fm_create(fms, fmstruct)
     257            0 :       CALL cp_fm_struct_release(fmstruct)
     258            0 :       CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, fms)
     259              : 
     260            0 :       NULLIFY (bse_w_matrix_MO)
     261            0 :       bse_w_matrix_MO => ex_env%bse_w_matrix_MO(1, 1)
     262              : 
     263            0 :       DO ivect = 1, nvects
     264            0 :          DO ispin = 1, nspins
     265            0 :             NULLIFY (matrix_struct, fmstruct)
     266              :             CALL cp_fm_get_info(matrix=evects(ispin, 1), matrix_struct=matrix_struct, &
     267            0 :                                 nrow_global=nao, ncol_global=nactive(ispin))
     268            0 :             nvirt = SIZE(gs_mos(ispin)%evals_virt)
     269              : 
     270              :             CALL cp_fm_struct_create(fmstruct=fmstruct, para_env=para_env, &
     271            0 :                                      context=blacs_env, nrow_global=nvirt, ncol_global=nao)
     272            0 :             CALL cp_fm_create(CSvirt, fmstruct)
     273            0 :             CALL cp_fm_struct_release(fmstruct)
     274              : 
     275              :             CALL cp_fm_struct_create(fmstruct=fmstruct, para_env=para_env, &
     276              :                                      context=blacs_env, nrow_global=nactive(ispin)*nactive(ispin), &
     277            0 :                                      ncol_global=nvirt*nao)
     278            0 :             CALL cp_fm_create(WXvirtao, fmstruct)
     279            0 :             CALL cp_fm_struct_release(fmstruct)
     280            0 :             CALL cp_fm_set_all(WXvirtao, 0.0_dp)
     281              : 
     282              :             CALL cp_fm_struct_create(fmstruct=fmstruct, para_env=para_env, &
     283              :                                      context=blacs_env, nrow_global=nactive(ispin)*nactive(ispin), &
     284            0 :                                      ncol_global=nao*nao)
     285            0 :             CALL cp_fm_create(WXaoao, fmstruct)
     286            0 :             CALL cp_fm_struct_release(fmstruct)
     287            0 :             CALL cp_fm_set_all(WXaoao, 0.0_dp)
     288              : 
     289            0 :             CALL parallel_gemm('T', 'N', nvirt, nao, nao, 1.0_dp, gs_mos(ispin)%mos_virt, fms, 0.0_dp, CSvirt)
     290            0 :             NULLIFY (row_indices, col_indices)
     291              :             CALL cp_fm_get_info(matrix=WXvirtao, nrow_local=nrow_local, ncol_local=ncol_local, &
     292              :                                 row_indices=row_indices, col_indices=col_indices, &
     293            0 :                                 nrow_block=nrow_block, ncol_block=ncol_block, local_data=my_block)
     294              :             CALL cp_fm_get_info(matrix=CSvirt, nrow_local=nrow_local_cs, ncol_local=ncol_local_cs, &
     295              :                                 row_indices=row_indices_cs, col_indices=col_indices_cs, &
     296            0 :                                 nrow_block=nrow_block_cs, ncol_block=ncol_block_cs, local_data=my_CSvirt)
     297              :             CALL cp_fm_get_info(matrix=bse_w_matrix_MO, nrow_local=nrow_local_bse, ncol_local=ncol_local_bse, &
     298              :                                 row_indices=row_indices_bse, col_indices=col_indices_bse, &
     299            0 :                                 nrow_block=nrow_block_bse, ncol_block=ncol_block_bse, local_data=my_bse_w_matrix_MO)
     300              : 
     301            0 :             CALL cp_fm_set_all(WXvirtao, 0.0_dp)
     302              : 
     303            0 :             DO ii = 1, nrow_local
     304            0 :                i_row_global = row_indices(ii)
     305            0 :                DO jj = 1, ncol_local
     306            0 :                   j_col_global = col_indices(jj)
     307              : 
     308            0 :                   i_occ_row = (i_row_global - 1)/nactive(ispin) + 1
     309            0 :                   j_occ_row = MOD(i_row_global - 1, nactive(ispin)) + 1
     310            0 :                   a_virt_col = (j_col_global - 1)/nao + 1
     311            0 :                   b_nao_col = MOD(j_col_global - 1, nao) + 1
     312              : 
     313            0 :                   DO c_virt_col = 1, nvirt
     314            0 :                      mu_col_global = (a_virt_col - 1)*nvirt + c_virt_col
     315              : 
     316              :                      WXvirtao%local_data(i_row_global, j_col_global) = WXvirtao%local_data(i_row_global, j_col_global) + &
     317            0 :                                     bse_w_matrix_MO%local_data(i_row_global, mu_col_global)*CSvirt%local_data(c_virt_col, b_nao_col)
     318              : 
     319              :                   END DO
     320              :                END DO
     321              :             END DO
     322              : 
     323            0 :             NULLIFY (row_indices, col_indices) ! redefine indices
     324              :             CALL cp_fm_get_info(matrix=WXaoao, nrow_local=nrow_local, ncol_local=ncol_local, &
     325              :                                 row_indices=row_indices, col_indices=col_indices, &
     326            0 :                                 nrow_block=nrow_block, ncol_block=ncol_block)
     327              : 
     328            0 :             CALL cp_fm_set_all(WXaoao, 0.0_dp)
     329            0 :             DO ii = 1, nrow_local
     330            0 :                i_row_global = row_indices(ii)
     331            0 :                DO jj = 1, ncol_local
     332            0 :                   j_col_global = col_indices(jj)
     333              : 
     334            0 :                   i_occ_row = (i_row_global - 1)/nactive(ispin) + 1
     335            0 :                   j_occ_row = MOD(i_row_global - 1, nactive(ispin)) + 1
     336            0 :                   a_nao_col = (j_col_global - 1)/nao + 1
     337            0 :                   b_nao_col = MOD(j_col_global - 1, nao) + 1
     338              : 
     339            0 :                   DO k_occ_col = 1, nvirt
     340            0 :                      mu_col_global = (k_occ_col - 1)*nao + a_nao_col
     341              : 
     342              :                      WXaoao%local_data(i_row_global, j_col_global) = WXaoao%local_data(i_row_global, j_col_global) + &
     343            0 :                                             WXvirtao%local_data(i_row_global, mu_col_global)*CSvirt%local_data(k_occ_col, b_nao_col)
     344              : 
     345              :                   END DO
     346              :                END DO
     347              :             END DO
     348              : 
     349            0 :             CALL cp_fm_release(WXvirtao)
     350            0 :             CALL cp_fm_release(CSvirt)
     351              : 
     352              :             CALL cp_fm_struct_create(fmstruct=fmstruct, para_env=para_env, &
     353            0 :                                      context=blacs_env, nrow_global=nao, ncol_global=nactive(ispin))
     354            0 :             CALL cp_fm_create(WXmat2, fmstruct)
     355            0 :             CALL cp_fm_struct_release(fmstruct)
     356            0 :             CALL cp_fm_set_all(WXmat2, 0.0_dp)
     357              : 
     358            0 :             DO ii = 1, nrow_local
     359            0 :                i_row_global = row_indices(ii)
     360            0 :                DO jj = 1, ncol_local
     361            0 :                   j_col_global = col_indices(jj)
     362              : 
     363            0 :                   i_occ_row = (i_row_global - 1)/nactive(ispin) + 1
     364            0 :                   j_occ_row = MOD(i_row_global - 1, nactive(ispin)) + 1
     365            0 :                   a_nao_col = (j_col_global - 1)/nao + 1
     366            0 :                   b_nao_col = MOD(j_col_global - 1, nao) + 1
     367              : 
     368              :                   WXmat2%local_data(a_nao_col, i_occ_row) = WXmat2%local_data(a_nao_col, i_occ_row) + &
     369            0 :                                  WXaoao%local_data(i_row_global, j_col_global)*evects(ispin, ivect)%local_data(b_nao_col, j_occ_row)
     370              :                END DO
     371              :             END DO
     372              : 
     373            0 :             CALL cp_fm_release(WXaoao)
     374              : 
     375            0 :             IF (iounit > 0) THEN
     376            0 :                CALL cp_fm_write_formatted(WXmat2, iounit, "WXmat2")
     377              :             END IF
     378              : 
     379            0 :             CALL cp_fm_scale_and_add(1.0_dp, Aop_evects(ispin, ivect), -1.0_dp, WXmat2)
     380              : 
     381            0 :             CALL cp_fm_release(WXmat2)
     382              : 
     383              :          END DO! ispin
     384              :       END DO !ivect
     385              : 
     386            0 :       CALL cp_fm_release(fms)
     387              : 
     388            0 :       CALL timestop(handle)
     389              : 
     390            0 :    END SUBROUTINE tddfpt_apply_bse_debug
     391              : 
     392              : ! **************************************************************************************************
     393              : !> \brief ...
     394              : !> \param Aop_evects ...
     395              : !> \param evects ...
     396              : !> \param gs_mos ...
     397              : !> \param qs_env ...
     398              : !> \param S_evects ...
     399              : ! **************************************************************************************************
     400           36 :    SUBROUTINE tddfpt_apply_bse(Aop_evects, evects, gs_mos, qs_env, S_evects)
     401              : 
     402              :       TYPE(cp_fm_type), DIMENSION(:, :), INTENT(INOUT)   :: Aop_evects
     403              :       TYPE(cp_fm_type), DIMENSION(:, :), INTENT(IN)      :: evects
     404              :       TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
     405              :          INTENT(in)                                      :: gs_mos
     406              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     407              :       TYPE(cp_fm_type), DIMENSION(:, :), INTENT(IN)      :: S_evects
     408              : 
     409              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'tddfpt_apply_bse'
     410              : 
     411              :       INTEGER                                            :: handle, ispin, ivect, nao, nspins, &
     412              :                                                             nvects, nvirt
     413              :       INTEGER, DIMENSION(2)                              :: nactive
     414              :       REAL(KIND=dp)                                      :: alpha
     415           36 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: eigvec_entries, rho
     416              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     417              :       TYPE(cp_fm_struct_type), POINTER                   :: fmstruct
     418              :       TYPE(cp_fm_type)                                   :: CSvirt, evects_mo, evects_unsplit, fms, &
     419              :                                                             rhomu, rhosplit
     420              :       TYPE(cp_fm_type), POINTER                          :: bse_a_matrix_MO
     421           36 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
     422              :       TYPE(excited_energy_type), POINTER                 :: ex_env
     423              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     424              : 
     425           36 :       CALL timeset(routineN, handle)
     426              : 
     427           36 :       nspins = SIZE(evects, 1)
     428           36 :       nvects = SIZE(evects, 2)
     429              :       IF (nspins > 1) THEN
     430              :          alpha = 1.0_dp
     431              :       ELSE
     432              :          alpha = 2.0_dp
     433              :       END IF
     434           36 :       CALL cp_fm_get_info(gs_mos(1)%mos_occ, nrow_global=nao)
     435           72 :       DO ispin = 1, nspins
     436           72 :          CALL cp_fm_get_info(evects(ispin, 1), ncol_global=nactive(ispin))
     437              :       END DO
     438              : 
     439           36 :       NULLIFY (ex_env, para_env, blacs_env, matrix_s)
     440              :       CALL get_qs_env(qs_env, exstate_env=ex_env, para_env=para_env, blacs_env=blacs_env, &
     441           36 :                       matrix_s=matrix_s)
     442              : 
     443              :       CALL cp_fm_struct_create(fmstruct=fmstruct, para_env=para_env, &
     444           36 :                                context=blacs_env, nrow_global=nao, ncol_global=nao)
     445           36 :       CALL cp_fm_create(fms, fmstruct)
     446           36 :       CALL cp_fm_struct_release(fmstruct)
     447           36 :       CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, fms)
     448              : 
     449           36 :       NULLIFY (bse_a_matrix_MO)
     450           36 :       bse_a_matrix_MO => ex_env%bse_a_matrix_MO(1, 1)
     451           36 :       para_env => bse_a_matrix_MO%matrix_struct%para_env
     452              : 
     453          380 :       DO ivect = 1, nvects
     454          724 :          DO ispin = 1, nspins
     455          344 :             NULLIFY (fmstruct)
     456              :             CALL cp_fm_get_info(matrix=evects(ispin, 1), &
     457          344 :                                 nrow_global=nao, ncol_global=nactive(ispin))
     458          344 :             nvirt = SIZE(gs_mos(ispin)%evals_virt)
     459              : 
     460              :             CALL cp_fm_struct_create(fmstruct=fmstruct, para_env=para_env, &
     461          344 :                                      context=blacs_env, nrow_global=nvirt, ncol_global=nao)
     462          344 :             CALL cp_fm_create(CSvirt, fmstruct)
     463          344 :             CALL cp_fm_struct_release(fmstruct)
     464              :             CALL parallel_gemm('T', 'N', nvirt, nao, nao, 1.0_dp, gs_mos(ispin)%mos_virt, &
     465          344 :                                fms, 0.0_dp, CSvirt)
     466              : 
     467          344 :             NULLIFY (fmstruct)
     468              :             CALL cp_fm_struct_create(fmstruct, para_env=para_env, context=blacs_env, &
     469          344 :                                      nrow_global=nvirt, ncol_global=nactive(ispin))
     470          344 :             CALL cp_fm_create(evects_mo, fmstruct)
     471          344 :             CALL cp_fm_struct_release(fmstruct)
     472          344 :             NULLIFY (fmstruct)
     473              :             CALL cp_fm_struct_create(fmstruct, para_env=para_env, context=blacs_env, &
     474          344 :                                      nrow_global=nvirt, ncol_global=nactive(ispin))
     475          344 :             CALL cp_fm_create(rhosplit, fmstruct)
     476          344 :             CALL cp_fm_struct_release(fmstruct)
     477          344 :             NULLIFY (fmstruct)
     478              :             CALL cp_fm_struct_create(fmstruct, para_env=para_env, context=blacs_env, &
     479          344 :                                      nrow_global=nao, ncol_global=nactive(ispin))
     480          344 :             CALL cp_fm_create(rhomu, fmstruct)
     481          344 :             CALL cp_fm_struct_release(fmstruct)
     482          344 :             NULLIFY (fmstruct)
     483              :             CALL cp_fm_struct_create(fmstruct, para_env=para_env, context=blacs_env, &
     484          344 :                                      nrow_global=nactive(ispin)*nvirt, ncol_global=1)
     485          344 :             CALL cp_fm_create(evects_unsplit, fmstruct)
     486          344 :             CALL cp_fm_struct_release(fmstruct)
     487              : 
     488              : !    get X_jb
     489              :             CALL parallel_gemm("T", "N", nvirt, nactive(ispin), nao, 1.0_dp, gs_mos(ispin)%mos_virt, &
     490          344 :                                S_evects(ispin, ivect), 0.0_dp, evects_mo)
     491              : !    rearrange X_jb
     492          344 :             CALL contract_bse(evects_mo, evects_unsplit, nactive(ispin), nvirt, eigvec_entries)
     493              : !    contract A_iajb X_jb
     494         1032 :             ALLOCATE (rho(nvirt*nactive(ispin)))
     495          344 :             CALL cp_fm_matvec(bse_a_matrix_MO, eigvec_entries, rho, 1.0_dp, 0.0_dp)
     496              : !    rearrange rho_ia
     497          344 :             CALL split_bse(rho, rhosplit, nvirt)
     498              : !    get rho_imu
     499              :             CALL parallel_gemm("T", "N", nao, nactive(ispin), nvirt, 1.0_dp, CSvirt, &
     500          344 :                                rhosplit, 0.0_dp, rhomu)
     501              : 
     502          344 :             CALL cp_fm_scale_and_add(1.0_dp, Aop_evects(ispin, ivect), 1.0_dp, rhomu)
     503              : 
     504          344 :             CALL cp_fm_release(rhomu)
     505          344 :             CALL cp_fm_release(CSvirt)
     506          344 :             CALL cp_fm_release(evects_mo)
     507          344 :             CALL cp_fm_release(rhosplit)
     508          344 :             CALL cp_fm_release(evects_unsplit)
     509          344 :             DEALLOCATE (rho)
     510         2752 :             DEALLOCATE (eigvec_entries)
     511              : 
     512              :          END DO! ispin
     513              :       END DO !ivect
     514              : 
     515           36 :       CALL cp_fm_release(fms)
     516              : 
     517           36 :       CALL timestop(handle)
     518              : 
     519           72 :    END SUBROUTINE tddfpt_apply_bse
     520              : 
     521              : ! **************************************************************************************************
     522              : !> \brief ...
     523              : !> \param evects_mo ...
     524              : !> \param evects_unsplit ...
     525              : !> \param nactive ...
     526              : !> \param nvirt ...
     527              : !> \param eigvec_entries ...
     528              : ! **************************************************************************************************
     529          344 :    SUBROUTINE contract_bse(evects_mo, evects_unsplit, nactive, nvirt, eigvec_entries)
     530              :       TYPE(cp_fm_type), INTENT(IN)                       :: evects_mo
     531              :       TYPE(cp_fm_type), INTENT(INOUT)                    :: evects_unsplit
     532              :       INTEGER                                            :: nactive, nvirt
     533              :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:)           :: eigvec_entries
     534              : 
     535              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'contract_bse'
     536              : 
     537              :       INTEGER                                            :: handle, jj
     538              : 
     539          344 :       CALL timeset(routineN, handle)
     540              : 
     541         1032 :       ALLOCATE (eigvec_entries(nvirt*nactive))
     542         1720 :       DO jj = 1, nactive
     543              :          CALL cp_fm_to_fm_submat(msource=evects_mo, mtarget=evects_unsplit, &
     544              :                                  nrow=nvirt, ncol=1, s_firstrow=1, s_firstcol=jj, &
     545         1720 :                                  t_firstrow=(jj - 1)*nvirt + 1, t_firstcol=1)
     546              :       END DO
     547          344 :       CALL cp_fm_vectorssum(evects_unsplit, eigvec_entries, "R")
     548              : 
     549          344 :       CALL timestop(handle)
     550          344 :    END SUBROUTINE contract_bse
     551              : 
     552              : ! **************************************************************************************************
     553              : !> \brief ...
     554              : !> \param rho ...
     555              : !> \param rhosplit ...
     556              : !> \param nvirt ...
     557              : ! **************************************************************************************************
     558          344 :    SUBROUTINE split_bse(rho, rhosplit, nvirt)
     559              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
     560              :          INTENT(IN)                                      :: rho
     561              :       TYPE(cp_fm_type), INTENT(INOUT)                    :: rhosplit
     562              :       INTEGER, INTENT(IN)                                :: nvirt
     563              : 
     564              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'split_bse'
     565              : 
     566              :       INTEGER                                            :: handle, i_occ_row, ii, j_occ_row
     567              : 
     568          344 :       CALL timeset(routineN, handle)
     569              : 
     570          344 :       CALL cp_fm_set_all(rhosplit, 0.0_dp)
     571              : 
     572        26488 :       DO ii = 1, SIZE(rho)
     573        26144 :          i_occ_row = (ii - 1)/nvirt + 1
     574        26144 :          j_occ_row = MOD(ii - 1, nvirt) + 1
     575        26488 :          CALL cp_fm_set_element(rhosplit, j_occ_row, i_occ_row, rho(ii))
     576              :       END DO
     577              : 
     578          344 :       CALL timestop(handle)
     579          344 :    END SUBROUTINE split_bse
     580              : 
     581              : END MODULE qs_tddfpt2_bse_utils
        

Generated by: LCOV version 2.0-1