65#include "./base/base_uses.f90"
71 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'bse_full_diag'
96 SUBROUTINE create_a(fm_S_ia, fm_S_bar_ij, fm_S_ab, &
97 fm_A, Eigenval, unit_nr, &
98 homo, virtual, dimen_RI, bse_env)
100 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: fm_s_ia, fm_s_bar_ij, fm_s_ab
102 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: eigenval
103 INTEGER,
INTENT(IN) :: unit_nr
104 INTEGER,
DIMENSION(:),
INTENT(IN) :: homo, virtual
105 INTEGER,
INTENT(IN) :: dimen_ri
108 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_A'
110 INTEGER :: a_virt_row, handle, i_occ_row, i_row_global, ii, isp, j_col_global, jj, k_isp, &
111 k_ov, n_ov_joint, ncol_local_a, nrow_local_a, nspins, sizeeigen
112 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: eig_offsets, n_ov, offsets
113 INTEGER,
DIMENSION(4) :: reordering
114 INTEGER,
DIMENSION(:),
POINTER :: col_indices_a, row_indices_a
115 REAL(kind=
dp) :: alpha, alpha_screening, eigen_diff
119 TYPE(
cp_fm_type) :: fm_a_copy, fm_s_joint, fm_w
124 CALL timeset(routinen, handle)
127 ALLOCATE (n_ov(nspins), offsets(nspins), eig_offsets(nspins))
132 eig_offsets(isp) = eig_offsets(isp - 1) + homo(isp - 1) + virtual(isp - 1)
135 NULLIFY (dft_control, tddfpt_control)
136 dft_control => bse_env%dft_control
137 tddfpt_control => dft_control%tddfpt2_control
139 IF (unit_nr > 0 .AND. bse_env%bse_debug_print)
THEN
140 WRITE (unit_nr,
'(T2,A10,T13,A10)')
'BSE|DEBUG|',
'Creating A'
144 SELECT CASE (bse_env%bse_spin_config)
152 CALL cp_warn(__location__, &
153 "BSE: SPIN_CONFIG ignored for open-shell reference; using alpha=1.")
158 alpha_screening = bse_env%screening_factor
160 alpha_screening = 1.0_dp
173 nrow_global=n_ov_joint, ncol_global=n_ov_joint, &
174 para_env=fm_s_ia(1)%matrix_struct%para_env)
178 IF (tddfpt_control%do_bse_w_only .AND. nspins == 1)
THEN
179 CALL cp_fm_create(fm_a_copy, fm_struct_a, name=
"fm_A_iajb")
185 IF ((.NOT. tddfpt_control%do_bse) .AND. (.NOT. tddfpt_control%do_bse_w_only))
THEN
189 context=fm_s_ia(1)%matrix_struct%context, &
190 nrow_global=dimen_ri, ncol_global=n_ov_joint, &
191 para_env=fm_s_ia(1)%matrix_struct%para_env)
192 CALL cp_fm_create(fm_s_joint, fm_struct_s_joint, name=
"fm_S_ia_joint")
195 CALL parallel_gemm(transa=
"T", transb=
"N", m=n_ov_joint, n=n_ov_joint, k=dimen_ri, &
196 alpha=alpha, matrix_a=fm_s_joint, matrix_b=fm_s_joint, beta=0.0_dp, &
201 CALL parallel_gemm(transa=
"T", transb=
"N", m=homo(1)*virtual(1), n=homo(1)*virtual(1), &
202 k=dimen_ri, alpha=alpha, &
203 matrix_a=fm_s_ia(1), matrix_b=fm_s_ia(1), &
204 beta=0.0_dp, matrix_c=fm_a)
208 IF (unit_nr > 0 .AND. bse_env%bse_debug_print)
THEN
209 WRITE (unit_nr,
'(T2,A10,T13,A16)')
'BSE|DEBUG|',
'Allocated A_iajb'
218 nrow_global=homo(isp)**2, ncol_global=virtual(isp)**2, &
219 para_env=fm_s_ab(isp)%matrix_struct%para_env)
223 CALL parallel_gemm(transa=
"T", transb=
"N", m=homo(isp)**2, n=virtual(isp)**2, &
224 k=dimen_ri, alpha=alpha_screening, &
225 matrix_a=fm_s_bar_ij(isp), matrix_b=fm_s_ab(isp), &
226 beta=0.0_dp, matrix_c=fm_w)
227 reordering = [1, 3, 2, 4]
229 virtual(isp), virtual(isp), unit_nr, reordering, bse_env, &
230 row_offset=offsets(isp), col_offset=offsets(isp))
231 IF (nspins == 1 .AND. tddfpt_control%do_bse_w_only)
THEN
233 virtual(1), virtual(1), unit_nr, reordering, bse_env)
236 IF (nspins == 1)
THEN
237 IF (tddfpt_control%do_bse .OR. tddfpt_control%do_bse_w_only .OR. &
238 tddfpt_control%do_bse_gw_only)
THEN
240 ex_env => bse_env%exstate_env
241 IF (.NOT. tddfpt_control%do_bse_gw_only)
THEN
242 ALLOCATE (ex_env%bse_w_matrix_MO(1, 1))
243 ALLOCATE (ex_env%bse_a_matrix_MO(1, 1))
244 CALL cp_fm_create(ex_env%bse_w_matrix_MO(1, 1), fm_struct_w)
245 CALL cp_fm_create(ex_env%bse_a_matrix_MO(1, 1), fm_struct_a)
246 CALL cp_fm_to_fm(fm_w, ex_env%bse_w_matrix_MO(1, 1))
247 IF (tddfpt_control%do_bse_w_only)
THEN
248 CALL cp_fm_to_fm(fm_a_copy, ex_env%bse_a_matrix_MO(1, 1))
250 CALL cp_fm_to_fm(fm_a, ex_env%bse_a_matrix_MO(1, 1))
260 IF (unit_nr > 0 .AND. bse_env%bse_debug_print)
THEN
261 WRITE (unit_nr,
'(T2,A10,T13,A16)')
'BSE|DEBUG|',
'Allocated W_ijab'
263 IF (nspins == 1 .AND. tddfpt_control%do_bse_w_only)
CALL cp_fm_release(fm_a_copy)
266 CALL cp_fm_get_info(matrix=fm_a, nrow_local=nrow_local_a, ncol_local=ncol_local_a, &
267 row_indices=row_indices_a, col_indices=col_indices_a)
270 IF (.NOT. tddfpt_control%do_bse)
THEN
271 DO ii = 1, nrow_local_a
272 i_row_global = row_indices_a(ii)
273 DO jj = 1, ncol_local_a
274 j_col_global = col_indices_a(jj)
275 IF (i_row_global == j_col_global)
THEN
278 DO k_isp = 1, nspins - 1
279 IF (i_row_global <= offsets(k_isp) + n_ov(k_isp))
THEN
284 k_ov = i_row_global - offsets(isp)
285 i_occ_row =
occ_of_ia(k_ov, virtual(isp))
287 eigen_diff = eigenval(eig_offsets(isp) + a_virt_row + homo(isp)) - &
288 eigenval(eig_offsets(isp) + i_occ_row)
289 fm_a%local_data(ii, jj) = fm_a%local_data(ii, jj) + eigen_diff
296 IF (nspins == 1)
THEN
297 IF (tddfpt_control%do_bse .OR. tddfpt_control%do_bse_w_only .OR. &
298 tddfpt_control%do_bse_gw_only)
THEN
299 sizeeigen =
SIZE(eigenval)
300 ALLOCATE (ex_env%gw_eigen(sizeeigen))
301 ex_env%gw_eigen(:) = eigenval(:)
306 DEALLOCATE (n_ov, offsets, eig_offsets)
310 CALL timestop(handle)
330 homo, virtual, dimen_RI, unit_nr, bse_env)
332 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: fm_s_ia, fm_s_bar_ia
334 INTEGER,
DIMENSION(:),
INTENT(IN) :: homo, virtual
335 INTEGER,
INTENT(IN) :: dimen_ri, unit_nr
338 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_B'
340 INTEGER :: handle, isp, n_ov_joint, nspins
341 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: n_ov, offsets
342 INTEGER,
DIMENSION(4) :: reordering
343 REAL(kind=
dp) :: alpha, alpha_screening
348 CALL timeset(routinen, handle)
351 ALLOCATE (n_ov(nspins), offsets(nspins))
354 IF (unit_nr > 0 .AND. bse_env%bse_debug_print)
THEN
355 WRITE (unit_nr,
'(T2,A10,T13,A10)')
'BSE|DEBUG|',
'Creating B'
360 SELECT CASE (bse_env%bse_spin_config)
366 IF (nspins > 1) alpha = 1.0_dp
369 alpha_screening = bse_env%screening_factor
371 alpha_screening = 1.0_dp
375 NULLIFY (fm_struct_b)
377 nrow_global=n_ov_joint, ncol_global=n_ov_joint, &
378 para_env=fm_s_ia(1)%matrix_struct%para_env)
384 NULLIFY (fm_struct_s_joint)
386 context=fm_s_ia(1)%matrix_struct%context, &
387 nrow_global=dimen_ri, ncol_global=n_ov_joint, &
388 para_env=fm_s_ia(1)%matrix_struct%para_env)
389 CALL cp_fm_create(fm_s_joint, fm_struct_s_joint, name=
"fm_S_ia_joint")
392 CALL parallel_gemm(transa=
"T", transb=
"N", m=n_ov_joint, n=n_ov_joint, k=dimen_ri, &
393 alpha=alpha, matrix_a=fm_s_joint, matrix_b=fm_s_joint, beta=0.0_dp, &
398 CALL parallel_gemm(transa=
"T", transb=
"N", m=homo(1)*virtual(1), n=homo(1)*virtual(1), &
399 k=dimen_ri, alpha=alpha, &
400 matrix_a=fm_s_ia(1), matrix_b=fm_s_ia(1), &
401 beta=0.0_dp, matrix_c=fm_b)
404 IF (unit_nr > 0 .AND. bse_env%bse_debug_print)
THEN
405 WRITE (unit_nr,
'(T2,A10,T13,A16)')
'BSE|DEBUG|',
'Allocated B_iajb'
412 NULLIFY (fm_struct_w)
414 context=fm_s_ia(isp)%matrix_struct%context, &
415 nrow_global=homo(isp)*virtual(isp), &
416 ncol_global=homo(isp)*virtual(isp), &
417 para_env=fm_s_ia(isp)%matrix_struct%para_env)
420 CALL parallel_gemm(transa=
"T", transb=
"N", m=homo(isp)*virtual(isp), &
421 n=homo(isp)*virtual(isp), k=dimen_ri, alpha=alpha_screening, &
422 matrix_a=fm_s_bar_ia(isp), matrix_b=fm_s_ia(isp), &
423 beta=0.0_dp, matrix_c=fm_w)
424 reordering = [1, 4, 3, 2]
426 virtual(isp), virtual(isp), unit_nr, reordering, bse_env, &
427 row_offset=offsets(isp), col_offset=offsets(isp))
434 DEALLOCATE (n_ov, offsets)
436 CALL timestop(handle)
459 fm_S_bar_ij, fm_A, fm_B, do_abba, Eigenval, unit_nr, &
460 homo, virtual, dimen_RI, bse_env)
462 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: fm_s_ia, fm_s_ij, fm_s_ab, fm_s_bar_ia, &
465 LOGICAL,
INTENT(IN) :: do_abba
466 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: eigenval
467 INTEGER,
INTENT(IN) :: unit_nr
468 INTEGER,
DIMENSION(:),
INTENT(IN) :: homo, virtual
469 INTEGER,
INTENT(IN) :: dimen_ri
474 CALL create_a(fm_s_ia, fm_s_ij, fm_s_ab, fm_a, eigenval, unit_nr, &
475 homo, virtual, dimen_ri, bse_env)
477 CALL create_b(fm_s_ia, fm_s_ia, fm_b, homo, virtual, dimen_ri, unit_nr, &
481 CALL create_a(fm_s_ia, fm_s_bar_ij, fm_s_ab, fm_a, eigenval, unit_nr, &
482 homo, virtual, dimen_ri, bse_env)
484 CALL create_b(fm_s_ia, fm_s_bar_ia, fm_b, homo, virtual, dimen_ri, unit_nr, &
506 fm_sqrt_A_minus_B, fm_inv_sqrt_A_minus_B, &
507 unit_nr, bse_env, diag_est)
510 TYPE(
cp_fm_type),
INTENT(INOUT) :: fm_c, fm_sqrt_a_minus_b, &
511 fm_inv_sqrt_a_minus_b
512 INTEGER,
INTENT(IN) :: unit_nr
514 REAL(kind=
dp),
INTENT(IN) :: diag_est
516 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_hermitian_form_of_ABBA'
518 INTEGER :: dim_mat, handle, n_dependent
519 REAL(kind=
dp),
DIMENSION(2) :: eigvals_ab_diff
520 TYPE(
cp_fm_type) :: fm_a_minus_b, fm_a_plus_b, fm_dummy, &
523 CALL timeset(routinen, handle)
525 IF (unit_nr > 0)
THEN
526 WRITE (unit_nr,
'(T2,A4,T7,A25,A39,ES6.0,A3)')
'BSE|',
'Diagonalizing aux. matrix', &
527 ' with size of A. This will take around ', diag_est,
" s."
544 CALL cp_fm_create(fm_sqrt_a_minus_b, fm_a%matrix_struct)
546 CALL cp_fm_create(fm_inv_sqrt_a_minus_b, fm_a%matrix_struct)
551 IF (unit_nr > 0 .AND. bse_env%bse_debug_print)
THEN
552 WRITE (unit_nr,
'(T2,A10,T13,A19)')
'BSE|DEBUG|',
'Created work arrays'
560 CALL cp_fm_to_fm(fm_a_minus_b, fm_inv_sqrt_a_minus_b)
568 CALL cp_fm_power(fm_inv_sqrt_a_minus_b, fm_dummy, -0.5_dp, 0.0_dp, n_dependent, eigvals=eigvals_ab_diff)
570 IF (unit_nr > 0)
THEN
571 WRITE (unit_nr,
'(T2,A4,T7,A,T65,F16.6)')
'BSE|', &
572 'Smallest eigenvalue of A-B (eV)', eigvals_ab_diff(1)*
evolt
576 IF (eigvals_ab_diff(1) < 0)
THEN
577 CALL cp_abort(__location__, &
578 "Matrix (A-B) is not positive definite. "// &
579 "Hermitian diagonalization of full ABBA matrix is ill-defined.")
586 CALL parallel_gemm(
"N",
"N", dim_mat, dim_mat, dim_mat, 1.0_dp, fm_inv_sqrt_a_minus_b, fm_a_minus_b, 0.0_dp, &
590 CALL parallel_gemm(
"N",
"N", dim_mat, dim_mat, dim_mat, 1.0_dp, fm_sqrt_a_minus_b, fm_a_plus_b, 0.0_dp, &
601 CALL parallel_gemm(
"N",
"N", dim_mat, dim_mat, dim_mat, 1.0_dp, fm_work_product, fm_sqrt_a_minus_b, 0.0_dp, &
605 IF (unit_nr > 0 .AND. bse_env%bse_debug_print)
THEN
606 WRITE (unit_nr,
'(T2,A10,T13,A36)')
'BSE|DEBUG|',
'Filled C=(A-B)^0.5 (A+B) (A-B)^0.5'
609 CALL timestop(handle)
628 fm_sqrt_A_minus_B, fm_inv_sqrt_A_minus_B, &
629 unit_nr, diag_est, bse_env, mo_coeff)
632 INTEGER,
DIMENSION(:),
INTENT(IN) :: homo, virtual, homo_irred
633 TYPE(
cp_fm_type),
INTENT(INOUT) :: fm_sqrt_a_minus_b, fm_inv_sqrt_a_minus_b
634 INTEGER,
INTENT(IN) :: unit_nr
635 REAL(kind=
dp),
INTENT(IN) :: diag_est
637 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: mo_coeff
639 CHARACTER(LEN=*),
PARAMETER :: routinen =
'diagonalize_C'
641 INTEGER :: diag_info, handle, n_ov_joint, nspins
642 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: exc_ens
643 TYPE(
cp_fm_type) :: fm_eigvec_x, fm_eigvec_y, fm_eigvec_z, &
644 fm_mat_eigvec_transform_diff, &
645 fm_mat_eigvec_transform_sum
647 CALL timeset(routinen, handle)
650 n_ov_joint = sum(homo*virtual)
652 IF (unit_nr > 0)
THEN
653 WRITE (unit_nr,
'(T2,A4,T7,A17,A22,ES6.0,A3)')
'BSE|',
'Diagonalizing C. ', &
654 'This will take around ', diag_est,
' s.'
661 ALLOCATE (exc_ens(n_ov_joint))
665 IF (diag_info /= 0)
THEN
666 CALL cp_abort(__location__, &
667 "Diagonalization of C=(A-B)^0.5 (A+B) (A-B)^0.5 failed in BSE")
673 IF (exc_ens(1) < 0)
THEN
674 IF (unit_nr > 0)
THEN
675 CALL cp_abort(__location__, &
676 "Matrix C=(A-B)^0.5 (A+B) (A-B)^0.5 has negative eigenvalues, i.e. "// &
677 "(A+B) is not positive definite.")
680 exc_ens = sqrt(exc_ens)
691 CALL cp_fm_create(fm_mat_eigvec_transform_sum, fm_c%matrix_struct)
693 CALL parallel_gemm(transa=
"N", transb=
"N", m=n_ov_joint, n=n_ov_joint, k=n_ov_joint, alpha=1.0_dp, &
694 matrix_a=fm_sqrt_a_minus_b, matrix_b=fm_eigvec_z, beta=0.0_dp, &
695 matrix_c=fm_mat_eigvec_transform_sum)
701 CALL cp_fm_create(fm_mat_eigvec_transform_diff, fm_c%matrix_struct)
703 CALL parallel_gemm(transa=
"N", transb=
"N", m=n_ov_joint, n=n_ov_joint, k=n_ov_joint, alpha=1.0_dp, &
704 matrix_a=fm_inv_sqrt_a_minus_b, matrix_b=fm_eigvec_z, beta=0.0_dp, &
705 matrix_c=fm_mat_eigvec_transform_diff)
715 CALL cp_fm_to_fm(fm_mat_eigvec_transform_sum, fm_eigvec_x)
721 CALL cp_fm_to_fm(fm_mat_eigvec_transform_sum, fm_eigvec_y)
728 IF (nspins == 1)
THEN
730 homo(1), virtual(1), homo_irred(1), unit_nr, &
731 .false., fm_eigvec_y)
734 CALL bse_open_shell_optical(exc_ens, fm_eigvec_x, homo, virtual, homo_irred, &
735 .false., mo_coeff, bse_env, unit_nr, fm_eigvec_y)
742 CALL timestop(handle)
758 unit_nr, diag_est, bse_env, mo_coeff)
761 INTEGER,
DIMENSION(:),
INTENT(IN) :: homo, virtual, homo_irred
762 INTEGER,
INTENT(IN) :: unit_nr
763 REAL(kind=
dp),
INTENT(IN) :: diag_est
765 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: mo_coeff
767 CHARACTER(LEN=*),
PARAMETER :: routinen =
'diagonalize_A'
769 INTEGER :: diag_info, handle, n_ov_joint, nspins
770 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: exc_ens
773 CALL timeset(routinen, handle)
776 n_ov_joint = sum(homo*virtual)
778 IF (unit_nr > 0)
THEN
779 WRITE (unit_nr,
'(T2,A4,T7,A17,A22,ES6.0,A3)')
'BSE|',
'Diagonalizing A. ', &
780 'This will take around ', diag_est,
' s.'
785 ALLOCATE (exc_ens(n_ov_joint))
789 IF (diag_info /= 0)
THEN
790 CALL cp_abort(__location__, &
791 "Diagonalization of A failed in TDA-BSE")
794 IF (nspins == 1)
THEN
796 homo(1), virtual(1), homo_irred(1), unit_nr, .true.)
798 CALL bse_open_shell_optical(exc_ens, fm_eigvec, homo, virtual, homo_irred, &
799 .true., mo_coeff, bse_env, unit_nr)
805 CALL timestop(handle)
824 SUBROUTINE bse_open_shell_optical(Exc_ens, fm_eigvec_X, homo, virtual, homo_irred, &
825 flag_tda, mo_coeff, bse_env, unit_nr, fm_eigvec_Y)
827 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: exc_ens
829 INTEGER,
DIMENSION(:),
INTENT(IN) :: homo, virtual, homo_irred
830 LOGICAL,
INTENT(IN) :: flag_tda
831 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: mo_coeff
833 INTEGER,
INTENT(IN) :: unit_nr
834 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: fm_eigvec_y
836 CHARACTER(LEN=*),
PARAMETER :: routinen =
'bse_open_shell_optical'
838 CHARACTER(LEN=10) :: info_approximation, multiplet
839 INTEGER :: handle, idir, isp, jdir, n, n_ov_joint, &
841 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: n_ov_sp, offsets_sp
842 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: oscill_str_joint
843 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: pol_res_joint, trans_mom_joint
846 TYPE(
cp_fm_type) :: fm_dip_reord_sp, fm_eigvec_sp, &
848 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_dip_ab_sp, fm_dip_ai_sp, fm_dip_ij_sp
849 TYPE(
cp_fm_type),
DIMENSION(3) :: fm_trans_mom_joint
851 CALL timeset(routinen, handle)
854 ALLOCATE (n_ov_sp(nspins), offsets_sp(nspins))
861 info_approximation =
" -TDA- "
863 info_approximation =
"-ABBA-"
866 IF (unit_nr > 0)
THEN
867 WRITE (unit_nr,
'(T2,A4,T7,A43)')
'BSE|',
'Joint open-shell BSE excitation energies:'
870 info_approximation, bse_env, unit_nr)
874 info_approximation, bse_env, unit_nr, fm_eigvec_y)
877 CALL cp_fm_create(fm_trans_coeff, fm_eigvec_x%matrix_struct)
879 IF (
PRESENT(fm_eigvec_y))
CALL cp_fm_scale_and_add(1.0_dp, fm_trans_coeff, 1.0_dp, fm_eigvec_y)
883 ALLOCATE (fm_dip_ai_sp(3), fm_dip_ij_sp(3), fm_dip_ab_sp(3))
884 ALLOCATE (oscill_str_joint(n_ov_joint), trans_mom_joint(3, 1, n_ov_joint))
885 ALLOCATE (pol_res_joint(3, 3, n_ov_joint))
886 trans_mom_joint(:, :, :) = 0.0_dp
887 NULLIFY (fm_struct_dip_reord, fm_struct_sp, fm_struct_tmom)
889 fm_trans_coeff%matrix_struct%context, 1, n_ov_joint)
891 CALL cp_fm_create(fm_trans_mom_joint(idir), fm_struct_tmom)
896 bse_env%matrix_dipole_ao, bse_env%mos, mo_coeff(isp:isp), &
897 homo(isp), virtual(isp), fm_trans_coeff%matrix_struct%context, &
899 NULLIFY (fm_struct_sp, fm_struct_dip_reord)
901 fm_trans_coeff%matrix_struct%context, n_ov_sp(isp), n_ov_joint)
905 offsets_sp(isp) + 1, 1, 1, 1)
907 fm_trans_coeff%matrix_struct%context, 1, n_ov_sp(isp))
909 CALL cp_fm_create(fm_dip_reord_sp, fm_struct_dip_reord, name=
"bse_dip_reord")
912 1, 1, 1, virtual(isp), unit_nr, [2, 4, 3, 1], bse_env)
913 CALL parallel_gemm(
'N',
'N', 1, n_ov_joint, n_ov_sp(isp), 1.0_dp, &
914 fm_dip_reord_sp, fm_eigvec_sp, 1.0_dp, fm_trans_mom_joint(idir))
922 NULLIFY (fm_struct_sp)
924 NULLIFY (fm_struct_dip_reord)
934 pol_res_joint(idir, jdir, n) = 2.0_dp*exc_ens(n)*trans_mom_joint(idir, 1, n) &
935 *trans_mom_joint(jdir, 1, n)
938 oscill_str_joint(n) = 2.0_dp/3.0_dp*exc_ens(n)*sum(abs(trans_mom_joint(:, 1, n))**2)
941 n_ov_joint, 1, sum(homo_irred), flag_tda, info_approximation, &
942 bse_env, unit_nr, open_shell=.true.)
944 CALL cp_warn(__location__, &
945 "Open-shell (UKS) BSE: exciton descriptors and NTO analysis are not yet "// &
946 "implemented and have been skipped.")
948 DEALLOCATE (fm_dip_ai_sp, fm_dip_ij_sp, fm_dip_ab_sp)
949 DEALLOCATE (n_ov_sp, offsets_sp, oscill_str_joint, trans_mom_joint, pol_res_joint)
951 CALL timestop(handle)
953 END SUBROUTINE bse_open_shell_optical
969 homo, virtual, homo_irred, unit_nr, &
970 flag_TDA, fm_eigvec_Y)
972 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: exc_ens
975 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: mo_coeff
976 INTEGER :: homo, virtual, homo_irred, unit_nr
977 LOGICAL,
OPTIONAL :: flag_tda
978 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: fm_eigvec_y
980 CHARACTER(LEN=*),
PARAMETER :: routinen =
'postprocess_bse'
982 CHARACTER(LEN=10) :: info_approximation, multiplet
983 INTEGER :: handle, i_exc, idir, n_moments_di, &
985 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: oscill_str, ref_point_multipole
986 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: polarizability_residues, trans_mom_bse
988 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_dipole_ab_trunc, fm_dipole_ai_trunc, &
989 fm_dipole_ij_trunc, fm_quadpole_ab_trunc, fm_quadpole_ai_trunc, fm_quadpole_ij_trunc
991 DIMENSION(:) :: exc_descr
994 CALL timeset(routinen, handle)
997 IF (bse_env%bse_spin_config == 0)
THEN
998 multiplet =
"Singlet"
1000 multiplet =
"Triplet"
1002 IF (.NOT.
PRESENT(flag_tda))
THEN
1006 info_approximation =
" -TDA- "
1008 info_approximation =
"-ABBA-"
1015 ALLOCATE (fm_dipole_ij_trunc(n_moments_di))
1016 ALLOCATE (fm_dipole_ab_trunc(n_moments_di))
1017 ALLOCATE (fm_dipole_ai_trunc(n_moments_di))
1018 ALLOCATE (ref_point_multipole(3))
1019 ref_point_multipole(:) = bse_env%multipole_ref_point
1021 CALL get_multipoles_mo(fm_dipole_ai_trunc, fm_dipole_ij_trunc, fm_dipole_ab_trunc, &
1022 bse_env%matrix_dipole_ao, bse_env%mos, mo_coeff, &
1023 homo, virtual, fm_eigvec_x%matrix_struct%context)
1025 IF (bse_env%num_print_exc_descr > 0)
THEN
1027 ALLOCATE (fm_quadpole_ij_trunc(n_moments_quad))
1028 ALLOCATE (fm_quadpole_ab_trunc(n_moments_quad))
1029 ALLOCATE (fm_quadpole_ai_trunc(n_moments_quad))
1031 cpassert(
ASSOCIATED(bse_env%matrix_quadpole_ao))
1032 CALL get_multipoles_mo(fm_quadpole_ai_trunc, fm_quadpole_ij_trunc, fm_quadpole_ab_trunc, &
1033 bse_env%matrix_quadpole_ao, bse_env%mos, mo_coeff, &
1034 homo, virtual, fm_eigvec_x%matrix_struct%context)
1036 ALLOCATE (exc_descr(bse_env%num_print_exc_descr))
1037 DO i_exc = 1, bse_env%num_print_exc_descr
1039 .false., unit_nr, bse_env)
1040 IF (.NOT. flag_tda)
THEN
1042 .false., unit_nr, bse_env)
1045 fm_quadpole_ij_trunc, fm_quadpole_ab_trunc, &
1046 fm_quadpole_ai_trunc, &
1047 i_exc, homo, virtual, &
1051 fm_quadpole_ij_trunc, fm_quadpole_ab_trunc, &
1052 fm_quadpole_ai_trunc, &
1053 i_exc, homo, virtual)
1056 IF (.NOT. flag_tda)
THEN
1062 IF (bse_env%bse_spin_config == 0)
THEN
1064 trans_mom_bse, oscill_str, polarizability_residues, &
1065 bse_env, homo, virtual, unit_nr, &
1076 info_approximation, bse_env, unit_nr)
1080 info_approximation, bse_env, unit_nr, fm_eigvec_y)
1084 homo, virtual, homo_irred, flag_tda, &
1085 info_approximation, bse_env, unit_nr)
1087 IF (bse_env%num_print_exc_descr > 0)
THEN
1088 CALL qs_subsys_get(bse_env%subsys, particle_set=particle_set)
1090 bse_env%num_print_exc_descr, bse_env%bse_debug_print, &
1091 bse_env%print_directional_exc_descr, &
1092 bse_env%print_directional_crosscorrelation, &
1093 'BSE|', particle_set)
1097 IF (bse_env%do_nto_analysis)
THEN
1098 IF (unit_nr > 0)
THEN
1099 WRITE (unit_nr,
'(T2,A4)')
'BSE|'
1100 WRITE (unit_nr,
'(T2,A4,T7,A47)') &
1101 'BSE|',
"Calculating Natural Transition Orbitals (NTOs)."
1102 WRITE (unit_nr,
'(T2,A4)')
'BSE|'
1105 mo_coeff, homo, virtual, &
1106 info_approximation, &
1111 DO idir = 1, n_moments_di
1116 IF (bse_env%num_print_exc_descr > 0)
THEN
1117 DO idir = 1, n_moments_quad
1122 DEALLOCATE (fm_quadpole_ai_trunc, fm_quadpole_ij_trunc, fm_quadpole_ab_trunc)
1123 DEALLOCATE (exc_descr)
1125 DEALLOCATE (fm_dipole_ai_trunc, fm_dipole_ij_trunc, fm_dipole_ab_trunc)
1126 DEALLOCATE (ref_point_multipole)
1127 IF (bse_env%bse_spin_config == 0)
THEN
1128 DEALLOCATE (oscill_str, trans_mom_bse, polarizability_residues)
1130 IF (unit_nr > 0)
THEN
1131 WRITE (unit_nr,
'(T2,A4)')
'BSE|'
1132 WRITE (unit_nr,
'(T2,A4)')
'BSE|'
1135 CALL timestop(handle)
Routines for the full diagonalization of GW + Bethe-Salpeter for computing electronic excitations.
subroutine, public postprocess_bse(exc_ens, fm_eigvec_x, bse_env, mo_coeff, homo, virtual, homo_irred, unit_nr, flag_tda, fm_eigvec_y)
Prints the success message (incl. energies) for full diag of BSE (TDA/full ABBA via flag).
subroutine, public create_b(fm_s_ia, fm_s_bar_ia, fm_b, homo, virtual, dimen_ri, unit_nr, bse_env)
Matrix B constructed from 3c-B-matrices (cf. subroutine screen_slabs) B_ia,jb = α * v_ia,...
subroutine, public create_a_and_b(fm_s_ia, fm_s_ij, fm_s_ab, fm_s_bar_ia, fm_s_bar_ij, fm_a, fm_b, do_abba, eigenval, unit_nr, homo, virtual, dimen_ri, bse_env)
Explicit A, and B for ABBA, from the slabs the screening method contracts: the bare ones for TDHF and...
subroutine, public diagonalize_a(fm_a, homo, virtual, homo_irred, unit_nr, diag_est, bse_env, mo_coeff)
Solving hermitian eigenvalue equation A X^n = Ω^n X^n.
subroutine, public create_hermitian_form_of_abba(fm_a, fm_b, fm_c, fm_sqrt_a_minus_b, fm_inv_sqrt_a_minus_b, unit_nr, bse_env, diag_est)
Construct Matrix C=(A-B)^0.5 (A+B) (A-B)^0.5 to solve full BSE matrix as a hermitian problem (cf....
subroutine, public diagonalize_c(fm_c, homo, virtual, homo_irred, fm_sqrt_a_minus_b, fm_inv_sqrt_a_minus_b, unit_nr, diag_est, bse_env, mo_coeff)
Solving eigenvalue equation C Z^n = (Ω^n)^2 Z^n . Here, the eigenvectors Z^n relate to X^n via Eq....
subroutine, public create_a(fm_s_ia, fm_s_bar_ij, fm_s_ab, fm_a, eigenval, unit_nr, homo, virtual, dimen_ri, bse_env)
Matrix A constructed from GW energies and 3c-B-matrices (cf. subroutine screen_slabs) A_ia,...
Routines for printing information in context of the BSE calculation.
subroutine, public print_transition_amplitudes(fm_eigvec_x, homo, virtual, homo_irred, info_approximation, bse_env, unit_nr, fm_eigvec_y)
...
subroutine, public print_excitation_energies(exc_ens, homo, virtual, flag_tda, multiplet, info_approximation, bse_env, unit_nr)
...
subroutine, public print_output_header(homo, virtual, homo_irred, flag_tda, bse_env, unit_nr)
Banner, defining equations and legend of one BSE problem, printed before it is solved.
subroutine, public print_optical_properties(exc_ens, oscill_str, trans_mom_bse, polarizability_residues, homo, virtual, homo_irred, flag_tda, info_approximation, bse_env, unit_nr, open_shell)
...
subroutine, public print_exciton_descriptors(exc_descr, ref_point_multipole, unit_nr, num_print_exc_descr, print_checkvalue, print_directional_exc_descr, print_directional_crosscorrelation, prefix_output, particle_set)
Prints exciton descriptors, cf. Mewes et al., JCTC 14, 710-725 (2018).
Routines for computing excitonic properties, e.g. exciton diameter, from the BSE.
subroutine, public get_oscillator_strengths(fm_eigvec_x, exc_ens, fm_dipole_ai_trunc, trans_mom_bse, oscill_str, polarizability_residues, bse_env, homo_red, virtual_red, unit_nr, fm_eigvec_y)
Compute and return BSE dipoles d_r^n = sqrt(2) sum_ia < ψ_i | r | ψ_a > ( X_ia^n + Y_ia^n ) and oscil...
subroutine, public get_exciton_descriptors(exc_descr, fm_x_ia, fm_multipole_ij_trunc, fm_multipole_ab_trunc, fm_multipole_ai_trunc, i_exc, homo, virtual, fm_y_ia)
...
subroutine, public calculate_ntos(fm_x, fm_y, mo_coeff, homo, virtual, info_approximation, oscill_str, bse_env, unit_nr)
...
The BSE environment: the settings of the &BSE section and the state a GW path prepares for the solver...
Auxiliary routines for GW + Bethe-Salpeter for computing electronic excitations.
subroutine, public assemble_joint_ov_slab(fm_s_ia, offsets, n_ov, dimen_ri, fm_s_joint)
Column-concatenate per-spin ia-slabs into the joint dimen_RI x n_ov_joint slab. Sigma-block of spin i...
subroutine, public get_multipoles_mo(fm_multipole_ai_trunc, fm_multipole_ij_trunc, fm_multipole_ab_trunc, matrix_multipole, mos, mo_coeff, homo_red, virtual_red, context_bse, ispin)
The multipoles in the MO window, D^k_pq = sum_µν C_µp M^k_µν C_νq, cut to the ai, ij and ab blocks of...
pure integer function, public occ_of_ia(ia, virt)
Occupied level of the compound transition index ia = (i-1)*virt + a.
subroutine, public reshuffle_eigvec(fm_eigvec, fm_eigvec_reshuffled, homo, virtual, n_exc, do_transpose, unit_nr, bse_env)
...
subroutine, public get_bse_spin_block_layout(homo_red, virt_red, n_ov, offsets, n_ov_joint)
Spin-block layout for the open-shell (joint) BSE matrix: per-spin OV-pair counts and the block offset...
pure integer function, public virt_of_ia(ia, virt)
Virtual level of the compound transition index ia = (i-1)*virt + a.
subroutine, public comp_eigvec_coeff_bse(fm_work, eig_vals, beta, gamma, do_transpose)
Routine for computing the coefficients of the eigenvectors of the BSE matrix from a multiplication wi...
subroutine, public fm_general_add_bse(fm_out, fm_in, beta, nrow_secidx_in, ncol_secidx_in, nrow_secidx_out, ncol_secidx_out, unit_nr, reordering, bse_env, row_offset, col_offset)
Adds and reorders full matrices with a combined index structure, e.g. adding W_ij,...
methods related to the blacs parallel environment
subroutine, public cp_blacs_env_release(blacs_env)
releases the given blacs_env
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
subroutine, public cp_fm_power(matrix, work, exponent, threshold, n_dependent, verbose, eigvals)
...
subroutine, public choose_eigv_solver(matrix, eigenvectors, eigenvalues, info)
Choose the Eigensolver depending on which library is available ELPA seems to be unstable for small sy...
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_to_fm_submat(msource, mtarget, nrow, ncol, s_firstrow, s_firstcol, t_firstrow, t_firstcol)
copy just a part ot the matrix
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
Types for excited states potential energies.
Calculation of the incomplete Gamma function F_n(t) for multi-center integrals over Cartesian Gaussia...
Defines the basic variable types.
integer, parameter, public dp
basic linear algebra operations for full matrixes
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public evolt
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...
Settings of the &BSE section (read_bse_section, re-read before every BSE run, normalised in place by ...
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
Contains information on the excited states energy.