LCOV - code coverage report
Current view: top level - src - bse_main.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:3db43b4) Lines: 89.8 % 59 53
Test Date: 2026-04-03 06:55:30 Functions: 100.0 % 1 1

            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              : ! **************************************************************************************************
       9              : !> \brief Main routines for GW + Bethe-Salpeter for computing electronic excitations
      10              : !> \par History
      11              : !>      04.2024 created [Maximilian Graml]
      12              : ! **************************************************************************************************
      13              : 
      14              : MODULE bse_main
      15              : 
      16              :    USE bse_full_diag,                   ONLY: create_A,&
      17              :                                               create_B,&
      18              :                                               create_hermitian_form_of_ABBA,&
      19              :                                               diagonalize_A,&
      20              :                                               diagonalize_C
      21              :    USE bse_iterative,                   ONLY: do_subspace_iterations,&
      22              :                                               fill_local_3c_arrays
      23              :    USE bse_print,                       ONLY: print_BSE_start_flag
      24              :    USE bse_util,                        ONLY: adapt_BSE_input_params,&
      25              :                                               deallocate_matrices_bse,&
      26              :                                               estimate_BSE_resources,&
      27              :                                               mult_B_with_W,&
      28              :                                               truncate_BSE_matrices
      29              :    USE cp_control_types,                ONLY: dft_control_type,&
      30              :                                               tddfpt2_control_type
      31              :    USE cp_fm_types,                     ONLY: cp_fm_release,&
      32              :                                               cp_fm_type
      33              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      34              :                                               cp_logger_type
      35              :    USE cp_output_handling,              ONLY: debug_print_level
      36              :    USE group_dist_types,                ONLY: group_dist_d1_type
      37              :    USE input_constants,                 ONLY: bse_abba,&
      38              :                                               bse_both,&
      39              :                                               bse_fulldiag,&
      40              :                                               bse_iterdiag,&
      41              :                                               bse_screening_alpha,&
      42              :                                               bse_screening_tdhf,&
      43              :                                               bse_tda
      44              :    USE kinds,                           ONLY: dp
      45              :    USE message_passing,                 ONLY: mp_para_env_type
      46              :    USE mp2_types,                       ONLY: mp2_type
      47              :    USE qs_environment_types,            ONLY: get_qs_env,&
      48              :                                               qs_environment_type
      49              : #include "./base/base_uses.f90"
      50              : 
      51              :    IMPLICIT NONE
      52              : 
      53              :    PRIVATE
      54              : 
      55              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'bse_main'
      56              : 
      57              :    PUBLIC :: start_bse_calculation
      58              : 
      59              : CONTAINS
      60              : 
      61              : ! **************************************************************************************************
      62              : !> \brief Main subroutine managing BSE calculations
      63              : !> \param fm_mat_S_ia_bse ...
      64              : !> \param fm_mat_S_ij_bse ...
      65              : !> \param fm_mat_S_ab_bse ...
      66              : !> \param fm_mat_Q_static_bse_gemm ...
      67              : !> \param Eigenval ...
      68              : !> \param Eigenval_scf ...
      69              : !> \param homo ...
      70              : !> \param virtual ...
      71              : !> \param dimen_RI ...
      72              : !> \param dimen_RI_red ...
      73              : !> \param bse_lev_virt ...
      74              : !> \param gd_array ...
      75              : !> \param color_sub ...
      76              : !> \param mp2_env ...
      77              : !> \param qs_env ...
      78              : !> \param mo_coeff ...
      79              : !> \param unit_nr ...
      80              : ! **************************************************************************************************
      81           34 :    SUBROUTINE start_bse_calculation(fm_mat_S_ia_bse, fm_mat_S_ij_bse, fm_mat_S_ab_bse, &
      82              :                                     fm_mat_Q_static_bse_gemm, &
      83              :                                     Eigenval, Eigenval_scf, &
      84           34 :                                     homo, virtual, dimen_RI, dimen_RI_red, bse_lev_virt, &
      85           34 :                                     gd_array, color_sub, mp2_env, qs_env, mo_coeff, unit_nr)
      86              : 
      87              :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mat_S_ia_bse, fm_mat_S_ij_bse, &
      88              :                                                             fm_mat_S_ab_bse
      89              :       TYPE(cp_fm_type), INTENT(INOUT)                    :: fm_mat_Q_static_bse_gemm
      90              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
      91              :          INTENT(IN)                                      :: Eigenval, Eigenval_scf
      92              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: homo, virtual
      93              :       INTEGER, INTENT(IN)                                :: dimen_RI, dimen_RI_red, bse_lev_virt
      94              :       TYPE(group_dist_d1_type), INTENT(IN)               :: gd_array
      95              :       INTEGER, INTENT(IN)                                :: color_sub
      96              :       TYPE(mp2_type)                                     :: mp2_env
      97              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      98              :       TYPE(cp_fm_type), DIMENSION(:), INTENT(IN)         :: mo_coeff
      99              :       INTEGER, INTENT(IN)                                :: unit_nr
     100              : 
     101              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'start_bse_calculation'
     102              : 
     103              :       INTEGER                                            :: handle, homo_red, virtual_red
     104              :       LOGICAL                                            :: my_do_abba, my_do_fulldiag, &
     105              :                                                             my_do_iterat_diag, my_do_tda
     106              :       REAL(KIND=dp)                                      :: diag_runtime_est
     107           34 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: Eigenval_reduced
     108           34 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: B_abQ_bse_local, B_bar_iaQ_bse_local, &
     109           34 :                                                             B_bar_ijQ_bse_local, B_iaQ_bse_local
     110              :       TYPE(cp_fm_type) :: fm_A_BSE, fm_B_BSE, fm_C_BSE, fm_inv_sqrt_A_minus_B, fm_mat_S_ab_trunc, &
     111              :          fm_mat_S_bar_ia_bse, fm_mat_S_bar_ij_bse, fm_mat_S_ia_trunc, fm_mat_S_ij_trunc, &
     112              :          fm_sqrt_A_minus_B
     113              :       TYPE(cp_logger_type), POINTER                      :: logger
     114              :       TYPE(dft_control_type), POINTER                    :: dft_control
     115              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     116              :       TYPE(tddfpt2_control_type), POINTER                :: tddfpt_control
     117              : 
     118           34 :       CALL timeset(routineN, handle)
     119              : 
     120           34 :       para_env => fm_mat_S_ia_bse%matrix_struct%para_env
     121              : 
     122           34 :       my_do_fulldiag = .FALSE.
     123           34 :       my_do_iterat_diag = .FALSE.
     124           34 :       my_do_tda = .FALSE.
     125           34 :       my_do_abba = .FALSE.
     126              :       !Method: Iterative or full diagonalization
     127           34 :       SELECT CASE (mp2_env%bse%bse_diag_method)
     128              :       CASE (bse_iterdiag)
     129            0 :          my_do_iterat_diag = .TRUE.
     130              :          !MG: Basics of the Davidson solver are implemented, but not rigorously checked.
     131            0 :          CPABORT("Iterative BSE not yet implemented")
     132              :       CASE (bse_fulldiag)
     133           34 :          my_do_fulldiag = .TRUE.
     134              :       END SELECT
     135              :       !Approximation: TDA and/or full ABBA matrix
     136           50 :       SELECT CASE (mp2_env%bse%flag_tda)
     137              :       CASE (bse_tda)
     138           16 :          my_do_tda = .TRUE.
     139              :       CASE (bse_abba)
     140           18 :          my_do_abba = .TRUE.
     141              :       CASE (bse_both)
     142            0 :          my_do_tda = .TRUE.
     143           34 :          my_do_abba = .TRUE.
     144              :       END SELECT
     145              : 
     146           34 :       CALL print_BSE_start_flag(my_do_tda, my_do_abba, unit_nr)
     147              : 
     148              :       ! Link BSE debug flag against debug print level
     149           34 :       logger => cp_get_default_logger()
     150           34 :       IF (logger%iter_info%print_level == debug_print_level) THEN
     151            0 :          mp2_env%bse%bse_debug_print = .TRUE.
     152              :       END IF
     153              : 
     154           34 :       CALL fm_mat_S_ia_bse%matrix_struct%para_env%sync()
     155              :       ! We apply the BSE cutoffs using the DFT Eigenenergies
     156              :       ! Reduce matrices in case of energy cutoff for occupied and unoccupied in A/B-BSE-matrices
     157              :       CALL truncate_BSE_matrices(fm_mat_S_ia_bse, fm_mat_S_ij_bse, fm_mat_S_ab_bse, &
     158              :                                  fm_mat_S_ia_trunc, fm_mat_S_ij_trunc, fm_mat_S_ab_trunc, &
     159              :                                  Eigenval_scf(:, 1, 1), Eigenval(:, 1, 1), Eigenval_reduced, &
     160              :                                  homo(1), virtual(1), dimen_RI, unit_nr, &
     161              :                                  bse_lev_virt, &
     162              :                                  homo_red, virtual_red, &
     163           34 :                                  mp2_env)
     164              :       ! \bar{B}^P_rs = \sum_R W_PR B^R_rs where B^R_rs = \sum_T [1/sqrt(v)]_RT (T|rs)
     165              :       ! r,s: MO-index, P,R,T: RI-index
     166              :       ! B: fm_mat_S_..., W: fm_mat_Q_...
     167              :       CALL mult_B_with_W(fm_mat_S_ij_trunc, fm_mat_S_ia_trunc, fm_mat_S_bar_ia_bse, &
     168              :                          fm_mat_S_bar_ij_bse, fm_mat_Q_static_bse_gemm, &
     169           34 :                          dimen_RI_red, homo_red, virtual_red)
     170              : 
     171           34 :       IF (my_do_iterat_diag) THEN
     172              :          CALL fill_local_3c_arrays(fm_mat_S_ab_trunc, fm_mat_S_ia_trunc, &
     173              :                                    fm_mat_S_bar_ia_bse, fm_mat_S_bar_ij_bse, &
     174              :                                    B_bar_ijQ_bse_local, B_abQ_bse_local, B_bar_iaQ_bse_local, &
     175              :                                    B_iaQ_bse_local, dimen_RI_red, homo_red, virtual_red, &
     176              :                                    gd_array, color_sub, para_env)
     177              :       END IF
     178              : 
     179           34 :       CALL adapt_BSE_input_params(homo_red, virtual_red, unit_nr, mp2_env, qs_env)
     180              : 
     181           34 :       IF (my_do_fulldiag) THEN
     182              :          ! Quick estimate of memory consumption and runtime of diagonalizations
     183              :          CALL estimate_BSE_resources(homo_red, virtual_red, unit_nr, my_do_abba, &
     184           34 :                                      para_env, diag_runtime_est)
     185              :          ! Matrix A constructed from GW energies and 3c-B-matrices (cf. subroutine mult_B_with_W)
     186              :          ! A_ia,jb = (ε_a-ε_i) δ_ij δ_ab + α * v_ia,jb - W_ij,ab
     187              :          ! ε_a, ε_i are GW singleparticle energies from Eigenval_reduced
     188              :          ! α is a spin-dependent factor
     189              :          ! v_ia,jb = \sum_P B^P_ia B^P_jb (unscreened Coulomb interaction)
     190              :          ! W_ij,ab = \sum_P \bar{B}^P_ij B^P_ab (screened Coulomb interaction)
     191              : 
     192              :          ! For unscreened W matrix, we need fm_mat_S_ij_trunc
     193           34 :          IF (mp2_env%bse%screening_method == bse_screening_tdhf .OR. &
     194              :              mp2_env%bse%screening_method == bse_screening_alpha) THEN
     195              :             CALL create_A(fm_mat_S_ia_trunc, fm_mat_S_ij_trunc, fm_mat_S_ab_trunc, &
     196              :                           fm_A_BSE, Eigenval_reduced, unit_nr, &
     197              :                           homo_red, virtual_red, dimen_RI, mp2_env, &
     198            4 :                           para_env, qs_env)
     199              :          ELSE
     200              :             CALL create_A(fm_mat_S_ia_trunc, fm_mat_S_bar_ij_bse, fm_mat_S_ab_trunc, &
     201              :                           fm_A_BSE, Eigenval_reduced, unit_nr, &
     202              :                           homo_red, virtual_red, dimen_RI, mp2_env, &
     203           30 :                           para_env, qs_env)
     204              :          END IF
     205           34 :          IF (my_do_abba) THEN
     206              :             ! Matrix B constructed from 3c-B-matrices (cf. subroutine mult_B_with_W)
     207              :             ! B_ia,jb = α * v_ia,jb - W_ib,aj
     208              :             ! α is a spin-dependent factor
     209              :             ! v_ia,jb = \sum_P B^P_ia B^P_jb (unscreened Coulomb interaction)
     210              :             ! W_ib,aj = \sum_P \bar{B}^P_ib B^P_aj (screened Coulomb interaction)
     211              : 
     212              :             ! For unscreened W matrix, we need fm_mat_S_ia_trunc
     213           18 :             IF (mp2_env%bse%screening_method == bse_screening_tdhf .OR. &
     214              :                 mp2_env%bse%screening_method == bse_screening_alpha) THEN
     215              :                CALL create_B(fm_mat_S_ia_trunc, fm_mat_S_ia_trunc, fm_B_BSE, &
     216            4 :                              homo_red, virtual_red, dimen_RI, unit_nr, mp2_env)
     217              :             ELSE
     218              :                CALL create_B(fm_mat_S_ia_trunc, fm_mat_S_bar_ia_bse, fm_B_BSE, &
     219           14 :                              homo_red, virtual_red, dimen_RI, unit_nr, mp2_env)
     220              :             END IF
     221              :             ! Construct Matrix C=(A-B)^0.5 (A+B) (A-B)^0.5 to solve full BSE matrix as a hermitian problem
     222              :             ! (cf. Eq. (A7) in F. Furche J. Chem. Phys., Vol. 114, No. 14, (2001)).
     223              :             ! We keep fm_sqrt_A_minus_B and fm_inv_sqrt_A_minus_B for print of singleparticle transitions
     224              :             ! of ABBA as described in Eq. (A10) in F. Furche J. Chem. Phys., Vol. 114, No. 14, (2001).
     225              :             CALL create_hermitian_form_of_ABBA(fm_A_BSE, fm_B_BSE, fm_C_BSE, &
     226              :                                                fm_sqrt_A_minus_B, fm_inv_sqrt_A_minus_B, &
     227           18 :                                                homo_red, virtual_red, unit_nr, mp2_env, diag_runtime_est)
     228              :          END IF
     229           34 :          CALL cp_fm_release(fm_B_BSE)
     230              : 
     231           34 :          NULLIFY (dft_control, tddfpt_control)
     232           34 :          CALL get_qs_env(qs_env, dft_control=dft_control)
     233           34 :          tddfpt_control => dft_control%tddfpt2_control
     234           34 :          IF ((my_do_tda) .AND. (.NOT. tddfpt_control%do_bse)) THEN
     235              :             ! Solving the hermitian eigenvalue equation A X^n = Ω^n X^n
     236              :             CALL diagonalize_A(fm_A_BSE, homo_red, virtual_red, homo(1), &
     237           14 :                                unit_nr, diag_runtime_est, mp2_env, qs_env, mo_coeff)
     238              :          END IF
     239              :          ! Release to avoid faulty use of changed A matrix
     240           34 :          CALL cp_fm_release(fm_A_BSE)
     241           34 :          IF (my_do_abba) THEN
     242              :             ! Solving eigenvalue equation C Z^n = (Ω^n)^2 Z^n .
     243              :             ! Here, the eigenvectors Z^n relate to X^n via
     244              :             ! Eq. (A10) in F. Furche J. Chem. Phys., Vol. 114, No. 14, (2001).
     245              :             CALL diagonalize_C(fm_C_BSE, homo_red, virtual_red, homo(1), &
     246              :                                fm_sqrt_A_minus_B, fm_inv_sqrt_A_minus_B, &
     247           18 :                                unit_nr, diag_runtime_est, mp2_env, qs_env, mo_coeff)
     248              :          END IF
     249              :          ! Release to avoid faulty use of changed C matrix
     250           34 :          CALL cp_fm_release(fm_C_BSE)
     251              :       END IF
     252              : 
     253              :       CALL deallocate_matrices_bse(fm_mat_S_bar_ia_bse, fm_mat_S_bar_ij_bse, &
     254              :                                    fm_mat_S_ia_trunc, fm_mat_S_ij_trunc, fm_mat_S_ab_trunc, &
     255           34 :                                    fm_mat_Q_static_bse_gemm, mp2_env)
     256           34 :       DEALLOCATE (Eigenval_reduced)
     257           34 :       IF (my_do_iterat_diag) THEN
     258              :          ! Contains untested Block-Davidson algorithm
     259              :          CALL do_subspace_iterations(B_bar_ijQ_bse_local, B_abQ_bse_local, B_bar_iaQ_bse_local, &
     260              :                                      B_iaQ_bse_local, homo(1), virtual(1), mp2_env%bse%bse_spin_config, unit_nr, &
     261            0 :                                      Eigenval(:, 1, 1), para_env, mp2_env)
     262              :          ! Deallocate local 3c-B-matrices
     263            0 :          DEALLOCATE (B_bar_ijQ_bse_local, B_abQ_bse_local, B_bar_iaQ_bse_local, B_iaQ_bse_local)
     264              :       END IF
     265              : 
     266           34 :       IF (unit_nr > 0) THEN
     267           17 :          WRITE (unit_nr, '(T2,A4,T7,A53)') 'BSE|', 'The BSE was successfully calculated. Have a nice day!'
     268              :       END IF
     269              : 
     270           34 :       CALL timestop(handle)
     271              : 
     272           68 :    END SUBROUTINE start_bse_calculation
     273              : 
     274              : END MODULE bse_main
        

Generated by: LCOV version 2.0-1