40 dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, dbcsr_type_symmetric
123#include "base/base_uses.f90"
135 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'post_scf_bandstructure_utils'
146 CHARACTER(LEN=*),
PARAMETER :: routinen =
'allocate_GW_eigenvalues'
148 INTEGER :: handle, n_ao, n_spin, nkp
150 CALL timeset(routinen, handle)
153 nkp = bs_env%nkp_bs_and_DOS
154 n_spin = bs_env%n_spin
156 IF (.NOT.
ALLOCATED(bs_env%eigenval_GW))
THEN
157 ALLOCATE (bs_env%eigenval_GW(n_ao, nkp, n_spin))
159 IF (.NOT.
ALLOCATED(bs_env%eigenval_HF))
THEN
160 ALLOCATE (bs_env%eigenval_HF(n_ao, nkp, n_spin))
163 SELECT CASE (bs_env%gw_flavour)
165 IF (.NOT.
ALLOCATED(bs_env%eigenval_G0W0))
THEN
166 ALLOCATE (bs_env%eigenval_G0W0(n_ao, nkp, n_spin))
170 IF (bs_env%gw_flavour ==
evgw0 .AND. .NOT.
ALLOCATED(bs_env%eigenval_evGW0))
THEN
171 ALLOCATE (bs_env%eigenval_evGW0(n_ao, nkp, n_spin))
174 CALL timestop(handle)
185 CHARACTER(LEN=default_string_length) :: label
187 SELECT CASE (bs_env%gw_flavour)
193 IF (bs_env%do_static_cohsex) label =
"static COHSEX"
208 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_and_init_bs_env'
212 CALL timeset(routinen, handle)
216 CALL print_header(bs_env)
218 CALL read_bandstructure_input_parameters(bs_env, post_scf_bandstructure_section, qs_env)
220 CALL get_parameters_from_qs_env(qs_env, bs_env)
222 CALL set_heuristic_parameters(bs_env)
224 SELECT CASE (bs_env%gw_implementation)
227 CALL setup_kpoints_dos_large_cell_gamma(qs_env, bs_env, bs_env%kpoints_DOS)
229 CALL allocate_and_fill_fm_ks_fm_s(qs_env, bs_env)
231 CALL diagonalize_ks_matrix(bs_env)
233 CALL check_positive_definite_overlap_mat(bs_env, qs_env)
237 CALL setup_kpoints_scf_desymm(qs_env, bs_env, bs_env%kpoints_scf_desymm, .true.)
239 CALL setup_kpoints_dos_small_cell_full_kp(bs_env, bs_env%kpoints_DOS)
241 CALL allocate_and_fill_fm_ks_fm_s(qs_env, bs_env)
243 CALL compute_cfm_mo_coeff_kp_and_eigenval_scf_kp(qs_env, bs_env)
247 CALL read_bse_input(qs_env, bs_env)
249 CALL timestop(handle)
259 SUBROUTINE read_bse_input(qs_env, bs_env)
263 CHARACTER(LEN=*),
PARAMETER :: routinen =
'read_bse_input'
265 INTEGER :: handle, n_spin
266 INTEGER,
DIMENSION(2) :: n_mo
267 LOGICAL :: do_bse_props
272 CALL timeset(routinen, handle)
274 NULLIFY (bse_sec, input)
279 IF (do_bse_props)
THEN
283 n_spin = bs_env%n_spin
285 n_mo(:) = min(bs_env%n_mo_retained, bs_env%n_ao)
288 bs_env%n_occ(1:n_spin), bse_env%bse_cutoff_occ, &
289 bse_env%bse_cutoff_empty, window, warn=.false.)
294 bs_env%keep_W_freq_zero = do_bse_props
295 bs_env%keep_3c_nl = do_bse_props
297 CALL timestop(handle)
299 END SUBROUTINE read_bse_input
307 SUBROUTINE read_bandstructure_input_parameters(bs_env, bs_sec, qs_env)
312 CHARACTER(LEN=*),
PARAMETER :: routinen =
'read_bandstructure_input_parameters'
314 CHARACTER(LEN=default_string_length) :: ustr
315 CHARACTER(LEN=default_string_length), &
316 DIMENSION(:),
POINTER :: string_ptr
317 CHARACTER(LEN=max_line_length) :: error_msg
318 INTEGER :: handle, i, ikp
319 REAL(kind=
dp),
DIMENSION(3) :: kpptr
320 REAL(kind=
dp),
DIMENSION(3, 3) :: cart_hmat
323 kp_bs_sec, ldos_sec, soc_sec
325 CALL timeset(routinen, handle)
328 cart_hmat(:, :) = cell%hmat(:, :)
329 IF (cell%input_cell_canonicalized) cart_hmat(:, :) = cell%input_hmat(:, :)
335 bs_env%do_static_cohsex = (bs_env%cohsex_flavor /=
cohsex_off)
349 NULLIFY (dos_pdos_sec)
372 NULLIFY (floquet_sec)
385 CALL section_vals_val_get(floquet_sec,
"MEM_FILL_FRACTION", r_val=bs_env%floquet_mem_fill_fraction)
388 CALL section_vals_val_get(floquet_sec,
"QUASI_ENERGIES_FILE_NAME", c_val=bs_env%floquet_qe_file)
392 ALLOCATE (bs_env%xkp_special(3, bs_env%input_kp_bs_n_sp_pts))
393 DO ikp = 1, bs_env%input_kp_bs_n_sp_pts
395 cpassert(
SIZE(string_ptr(:), 1) == 4)
398 IF (len_trim(error_msg) > 0) cpabort(trim(error_msg))
402 bs_env%xkp_special(1:3, ikp) = kpptr(1:3)
403 CASE (
"CART_ANGSTROM")
404 bs_env%xkp_special(1:3, ikp) = (kpptr(1)*cart_hmat(1, 1:3) + &
405 kpptr(2)*cart_hmat(2, 1:3) + &
408 bs_env%xkp_special(1:3, ikp) = (kpptr(1)*cart_hmat(1, 1:3) + &
409 kpptr(2)*cart_hmat(2, 1:3) + &
410 kpptr(3)*cart_hmat(3, 1:3))/
twopi
412 cpabort(
"Unknown unit <"//trim(ustr)//
"> specified for k-point definition")
416 CALL timestop(handle)
418 END SUBROUTINE read_bandstructure_input_parameters
424 SUBROUTINE print_header(bs_env)
428 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_header'
432 CALL timeset(routinen, handle)
439 WRITE (u,
'(T2,A)')
' '
440 WRITE (u,
'(T2,A)') repeat(
'-', 79)
441 WRITE (u,
'(T2,A,A78)')
'-',
'-'
442 WRITE (u,
'(T2,A,A51,A27)')
'-',
'BANDSTRUCTURE CALCULATION',
'-'
443 WRITE (u,
'(T2,A,A78)')
'-',
'-'
444 WRITE (u,
'(T2,A)') repeat(
'-', 79)
445 WRITE (u,
'(T2,A)')
' '
448 CALL timestop(handle)
450 END SUBROUTINE print_header
458 SUBROUTINE setup_kpoints_dos_large_cell_gamma(qs_env, bs_env, kpoints)
464 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_DOS_large_cell_Gamma'
466 INTEGER :: handle, i_dim, i_kp_in_line, &
467 i_special_kp, ikk, n_kp_in_line, &
468 n_special_kp, nkp, nkp_only_bs, &
470 INTEGER,
DIMENSION(3) :: nkp_grid, periodic
472 CALL timeset(routinen, handle)
478 kpoints%kp_scheme =
"GENERAL"
480 n_special_kp = bs_env%input_kp_bs_n_sp_pts
481 n_kp_in_line = bs_env%input_kp_bs_npoints
483 periodic(1:3) = bs_env%periodic(1:3)
487 cpassert(periodic(i_dim) == 0 .OR. periodic(i_dim) == 1)
489 IF (bs_env%nkp_grid_DOS_input(i_dim) < 0)
THEN
490 IF (periodic(i_dim) == 1) nkp_grid(i_dim) = 2
491 IF (periodic(i_dim) == 0) nkp_grid(i_dim) = 1
493 nkp_grid(i_dim) = bs_env%nkp_grid_DOS_input(i_dim)
499 IF (nkp_grid(1) > 1)
THEN
500 nkp_only_dos = (nkp_grid(1) + 1)/2*nkp_grid(2)*nkp_grid(3)
501 ELSE IF (nkp_grid(2) > 1)
THEN
502 nkp_only_dos = nkp_grid(1)*(nkp_grid(2) + 1)/2*nkp_grid(3)
503 ELSE IF (nkp_grid(3) > 1)
THEN
504 nkp_only_dos = nkp_grid(1)*nkp_grid(2)*(nkp_grid(3) + 1)/2
511 IF (n_special_kp > 0)
THEN
512 nkp_only_bs = n_kp_in_line*(n_special_kp - 1) + 1
517 nkp = nkp_only_dos + nkp_only_bs
519 kpoints%nkp_grid(1:3) = nkp_grid(1:3)
522 bs_env%nkp_bs_and_DOS = nkp
523 bs_env%nkp_only_bs = nkp_only_bs
524 bs_env%nkp_only_DOS = nkp_only_dos
526 ALLOCATE (kpoints%xkp(3, nkp), kpoints%wkp(nkp))
527 kpoints%wkp(:) = 0.0_dp
528 kpoints%wkp(1:nkp_only_dos) = 1.0_dp/real(nkp_only_dos, kind=
dp)
530 CALL compute_xkp(kpoints%xkp, 1, nkp_only_dos, nkp_grid)
532 IF (n_special_kp > 0)
THEN
533 kpoints%xkp(1:3, nkp_only_dos + 1) = bs_env%xkp_special(1:3, 1)
534 ikk = nkp_only_dos + 1
535 DO i_special_kp = 2, n_special_kp
536 DO i_kp_in_line = 1, n_kp_in_line
538 kpoints%xkp(1:3, ikk) = bs_env%xkp_special(1:3, i_special_kp - 1) + &
539 REAL(i_kp_in_line, kind=
dp)/real(n_kp_in_line, kind=
dp)* &
540 (bs_env%xkp_special(1:3, i_special_kp) - &
541 bs_env%xkp_special(1:3, i_special_kp - 1))
542 kpoints%wkp(ikk) = 0.0_dp
551 IF (u > 0 .AND. bs_env%do_periodic)
THEN
552 IF (nkp_only_bs > 0)
THEN
553 WRITE (u, fmt=
"(T2,1A,T77,I4)") &
554 "Number of special k-points for the bandstructure", n_special_kp
555 WRITE (u, fmt=
"(T2,1A,T77,I4)")
"Number of k-points for the bandstructure", nkp
556 WRITE (u, fmt=
"(T2,1A,T69,3I4)") &
557 "K-point mesh for the density of states (DOS)", nkp_grid(1:3)
559 WRITE (u, fmt=
"(T2,1A,T69,3I4)") &
560 "K-point mesh for the density of states (DOS) and the self-energy", nkp_grid(1:3)
564 CALL timestop(handle)
566 END SUBROUTINE setup_kpoints_dos_large_cell_gamma
575 SUBROUTINE setup_kpoints_scf_desymm(qs_env, bs_env, kpoints, do_print)
580 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_scf_desymm'
582 INTEGER :: handle, i_cell_x, i_dim, img, j_cell_y, &
583 k_cell_z, nimages, nkp, u
584 INTEGER,
DIMENSION(3) :: cell_grid, cixd, nkp_grid
589 CALL timeset(routinen, handle)
594 CALL get_qs_env(qs_env=qs_env, kpoints=kpoints_scf)
596 nkp_grid(1:3) = kpoints_scf%nkp_grid(1:3)
597 nkp = nkp_grid(1)*nkp_grid(2)*nkp_grid(3)
601 IF (bs_env%periodic(i_dim) == 1)
THEN
602 cpassert(nkp_grid(i_dim) >= 4)
606 kpoints%kp_scheme =
"GENERAL"
607 kpoints%nkp_grid(1:3) = nkp_grid(1:3)
609 bs_env%nkp_scf_desymm = nkp
611 ALLOCATE (kpoints%xkp(1:3, nkp))
614 ALLOCATE (kpoints%wkp(nkp))
615 kpoints%wkp(:) = 1.0_dp/real(nkp, kind=
dp)
619 cell_grid(1:3) = nkp_grid(1:3) -
modulo(nkp_grid(1:3) + 1, 2)
622 cixd(1:3) = cell_grid(1:3)/2
624 nimages = cell_grid(1)*cell_grid(2)*cell_grid(3)
626 bs_env%nimages_scf_desymm = nimages
627 bs_env%cell_grid_scf_desymm(1:3) = cell_grid(1:3)
629 IF (
ASSOCIATED(kpoints%index_to_cell))
DEALLOCATE (kpoints%index_to_cell)
630 IF (
ASSOCIATED(kpoints%cell_to_index))
DEALLOCATE (kpoints%cell_to_index)
632 ALLOCATE (kpoints%cell_to_index(-cixd(1):cixd(1), -cixd(2):cixd(2), -cixd(3):cixd(3)))
633 ALLOCATE (kpoints%index_to_cell(3, nimages))
636 DO i_cell_x = -cixd(1), cixd(1)
637 DO j_cell_y = -cixd(2), cixd(2)
638 DO k_cell_z = -cixd(3), cixd(3)
640 kpoints%cell_to_index(i_cell_x, j_cell_y, k_cell_z) = img
641 kpoints%index_to_cell(1:3, img) = [i_cell_x, j_cell_y, k_cell_z]
647 IF (u > 0 .AND. do_print)
THEN
648 WRITE (u, fmt=
"(T2,A,I49)")
"Number of cells for G, χ, W, Σ", nimages
651 CALL timestop(handle)
653 END SUBROUTINE setup_kpoints_scf_desymm
660 SUBROUTINE setup_kpoints_dos_small_cell_full_kp(bs_env, kpoints)
665 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_DOS_small_cell_full_kp'
667 INTEGER :: handle, i_kp_in_line, i_special_kp, ikk, &
668 n_kp_in_line, n_special_kp, nkp, &
669 nkp_only_bs, nkp_scf_desymm, u
671 CALL timeset(routinen, handle)
677 n_special_kp = bs_env%input_kp_bs_n_sp_pts
678 n_kp_in_line = bs_env%input_kp_bs_npoints
679 nkp_scf_desymm = bs_env%nkp_scf_desymm
683 IF (n_special_kp > 0)
THEN
684 nkp_only_bs = n_kp_in_line*(n_special_kp - 1) + 1
688 nkp = nkp_only_bs + nkp_scf_desymm
690 ALLOCATE (kpoints%xkp(3, nkp))
691 ALLOCATE (kpoints%wkp(nkp))
695 bs_env%nkp_bs_and_DOS = nkp
696 bs_env%nkp_only_bs = nkp_only_bs
697 bs_env%nkp_only_DOS = nkp_scf_desymm
699 kpoints%xkp(1:3, 1:nkp_scf_desymm) = bs_env%kpoints_scf_desymm%xkp(1:3, 1:nkp_scf_desymm)
700 kpoints%wkp(1:nkp_scf_desymm) = 1.0_dp/real(nkp_scf_desymm, kind=
dp)
702 IF (n_special_kp > 0)
THEN
703 kpoints%xkp(1:3, nkp_scf_desymm + 1) = bs_env%xkp_special(1:3, 1)
704 ikk = nkp_scf_desymm + 1
705 DO i_special_kp = 2, n_special_kp
706 DO i_kp_in_line = 1, n_kp_in_line
708 kpoints%xkp(1:3, ikk) = bs_env%xkp_special(1:3, i_special_kp - 1) + &
709 REAL(i_kp_in_line, kind=
dp)/real(n_kp_in_line, kind=
dp)* &
710 (bs_env%xkp_special(1:3, i_special_kp) - &
711 bs_env%xkp_special(1:3, i_special_kp - 1))
712 kpoints%wkp(ikk) = 0.0_dp
717 IF (
ASSOCIATED(kpoints%index_to_cell))
DEALLOCATE (kpoints%index_to_cell)
719 ALLOCATE (kpoints%index_to_cell(3, bs_env%nimages_scf_desymm))
720 kpoints%index_to_cell(:, :) = bs_env%kpoints_scf_desymm%index_to_cell(:, :)
725 WRITE (u, fmt=
"(T2,1A,T77,I4)")
"Number of special k-points for the bandstructure", &
727 WRITE (u, fmt=
"(T2,1A,T77,I4)")
"Number of k-points for the bandstructure", nkp
730 CALL timestop(handle)
732 END SUBROUTINE setup_kpoints_dos_small_cell_full_kp
739 SUBROUTINE compute_cfm_mo_coeff_kp_and_eigenval_scf_kp(qs_env, bs_env)
743 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_cfm_mo_coeff_kp_and_eigenval_scf_kp'
745 INTEGER :: handle, ikp, ispin, nkp_bs_and_dos, &
747 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index_scf
748 REAL(kind=
dp) :: cbm, vbm
749 REAL(kind=
dp),
DIMENSION(3) :: xkp
751 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks, matrix_s
757 CALL timeset(routinen, handle)
760 matrix_ks_kp=matrix_ks, &
761 matrix_s_kp=matrix_s, &
764 NULLIFY (sab_nl, lowdin_kp)
765 IF (
ALLOCATED(kpoints_scf%lowdin_v))
THEN
766 IF (any(kpoints_scf%lowdin_v /= 0.0_dp))
ALLOCATE (lowdin_kp)
768 CALL get_kpoint_info(kpoints_scf, sab_nl=sab_nl, cell_to_index=cell_to_index_scf)
772 CALL cp_cfm_create(cfm_mos, bs_env%cfm_work_mo%matrix_struct)
775 nkp_bs_and_dos = bs_env%nkp_bs_and_DOS
779 ALLOCATE (bs_env%cfm_mo_coeff_kp(nkp_bs_and_dos, bs_env%n_spin))
780 ALLOCATE (bs_env%cfm_ks_kp(nkp_bs_and_dos, bs_env%n_spin))
781 ALLOCATE (bs_env%cfm_s_kp(nkp_bs_and_dos))
782 DO ikp = 1, nkp_bs_and_dos
783 DO ispin = 1, bs_env%n_spin
784 CALL cp_cfm_create(bs_env%cfm_mo_coeff_kp(ikp, ispin), bs_env%cfm_work_mo%matrix_struct)
785 CALL cp_cfm_create(bs_env%cfm_ks_kp(ikp, ispin), bs_env%cfm_work_mo%matrix_struct)
787 CALL cp_cfm_create(bs_env%cfm_s_kp(ikp), bs_env%cfm_work_mo%matrix_struct)
790 DO ikp = 1, nkp_bs_and_dos
792 xkp(1:3) = bs_env%kpoints_DOS%xkp(1:3, ikp)
795 CALL rsmat_to_kp(matrix_s, 1, xkp, cell_to_index_scf, sab_nl, bs_env, cfm_s)
797 IF (
ASSOCIATED(lowdin_kp))
THEN
800 DO ispin = 1, bs_env%n_spin
802 CALL rsmat_to_kp(matrix_ks, ispin, xkp, cell_to_index_scf, sab_nl, bs_env, cfm_ks)
803 IF (
ASSOCIATED(lowdin_kp))
THEN
804 CALL lowdin_kp_apply(lowdin_kp, kpoints_scf%lowdin_v(:, ispin), cmat=cfm_ks)
815 bs_env%eigenval_scf(:, ikp, ispin), &
816 bs_env%cfm_work_mo, bs_env%eps_eigval_mat_s, &
817 nmo_retained=nmo_retained)
818 bs_env%n_mo_retained = min(bs_env%n_mo_retained, nmo_retained)
822 CALL cp_cfm_to_cfm(cfm_mos, bs_env%cfm_mo_coeff_kp(ikp, ispin))
827 DO ispin = 1, bs_env%n_spin
828 vbm = maxval(bs_env%eigenval_scf(bs_env%n_occ(ispin), :, ispin))
829 cbm = minval(bs_env%eigenval_scf(bs_env%n_occ(ispin) + 1, :, ispin))
831 bs_env%e_fermi(ispin) = 0.5_dp*(vbm + cbm)
840 IF (
ASSOCIATED(lowdin_kp))
THEN
843 CALL lowdin_kp%lowdin_gemm%destroy()
844 DEALLOCATE (lowdin_kp)
847 CALL timestop(handle)
849 END SUBROUTINE compute_cfm_mo_coeff_kp_and_eigenval_scf_kp
862 SUBROUTINE rsmat_to_kp(mat_rs, ispin, xkp, cell_to_index_scf, sab_nl, bs_env, cfm_kp, imag_rs_mat)
865 REAL(kind=
dp),
DIMENSION(3) :: xkp
866 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index_scf
871 LOGICAL,
OPTIONAL :: imag_rs_mat
873 CHARACTER(LEN=*),
PARAMETER :: routinen =
'rsmat_to_kp'
876 LOGICAL :: imag_rs_mat_private
877 TYPE(
dbcsr_type),
POINTER :: cmat, nsmat, rmat
879 CALL timeset(routinen, handle)
881 ALLOCATE (rmat, cmat, nsmat)
883 imag_rs_mat_private = .false.
884 IF (
PRESENT(imag_rs_mat)) imag_rs_mat_private = imag_rs_mat
886 IF (imag_rs_mat_private)
THEN
887 CALL dbcsr_create(rmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_antisymmetric)
888 CALL dbcsr_create(cmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
890 CALL dbcsr_create(rmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
891 CALL dbcsr_create(cmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_antisymmetric)
893 CALL dbcsr_create(nsmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_no_symmetry)
899 CALL rskp_transform(rmatrix=rmat, cmatrix=cmat, rsmat=mat_rs, ispin=ispin, &
900 xkp=xkp, cell_to_index=cell_to_index_scf, sab_nl=sab_nl)
906 CALL cp_fm_to_cfm(bs_env%fm_work_mo(1), bs_env%fm_work_mo(2), cfm_kp)
912 CALL timestop(handle)
920 SUBROUTINE diagonalize_ks_matrix(bs_env)
923 CHARACTER(LEN=*),
PARAMETER :: routinen =
'diagonalize_ks_matrix'
925 INTEGER :: handle, ikp, ispin, nmo_retained
926 REAL(kind=
dp) :: cbm, vbm
928 CALL timeset(routinen, handle)
930 ALLOCATE (bs_env%eigenval_scf_Gamma(bs_env%n_ao, bs_env%n_spin))
932 DO ispin = 1, bs_env%n_spin
935 CALL cp_fm_to_fm(bs_env%fm_ks_Gamma(ispin), bs_env%fm_work_mo(1))
936 CALL cp_fm_to_fm(bs_env%fm_s_Gamma, bs_env%fm_work_mo(2))
941 bs_env%fm_work_mo(2), &
942 bs_env%fm_mo_coeff_Gamma(ispin), &
943 bs_env%eigenval_scf_Gamma(:, ispin), &
944 bs_env%fm_work_mo(3), &
945 bs_env%eps_eigval_mat_s, &
946 nmo_retained=nmo_retained)
947 bs_env%n_mo_retained = min(bs_env%n_mo_retained, nmo_retained)
949 vbm = bs_env%eigenval_scf_Gamma(bs_env%n_occ(ispin), ispin)
950 cbm = bs_env%eigenval_scf_Gamma(bs_env%n_occ(ispin) + 1, ispin)
952 bs_env%e_fermi(ispin) = 0.5_dp*(vbm + cbm)
956 CALL timestop(handle)
959 DO ispin = 1, bs_env%n_spin
960 DO ikp = 1, bs_env%nkp_bs_and_DOS
961 bs_env%eigenval_scf(:, ikp, ispin) = bs_env%eigenval_scf_Gamma(:, ispin)
965 END SUBROUTINE diagonalize_ks_matrix
972 SUBROUTINE check_positive_definite_overlap_mat(bs_env, qs_env)
976 CHARACTER(LEN=*),
PARAMETER :: routinen =
'check_positive_definite_overlap_mat'
978 INTEGER :: handle, ikp, info, u
981 CALL timeset(routinen, handle)
983 DO ikp = 1, bs_env%kpoints_DOS%nkp
987 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
998 WRITE (u, fmt=
"(T2,A)")
""
999 WRITE (u, fmt=
"(T2,A)")
"ERROR: The Cholesky decomposition "// &
1000 "of the k-point overlap matrix failed. This is"
1001 WRITE (u, fmt=
"(T2,A)")
"because the algorithm is "// &
1002 "only correct in the limit of large cells. The cell of "
1003 WRITE (u, fmt=
"(T2,A)")
"the calculation is too small. "// &
1004 "Use MULTIPLE_UNIT_CELL to create a larger cell "
1005 WRITE (u, fmt=
"(T2,A)")
"and to prevent this error."
1008 CALL bs_env%para_env%sync()
1009 cpabort(
"Please see information on the error above.")
1017 CALL timestop(handle)
1019 END SUBROUTINE check_positive_definite_overlap_mat
1026 SUBROUTINE get_parameters_from_qs_env(qs_env, bs_env)
1030 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_parameters_from_qs_env'
1032 INTEGER :: color_sub, handle, homo, n_ao, n_atom, &
1034 INTEGER,
DIMENSION(3) :: periodic
1035 REAL(kind=
dp) :: maxocc
1036 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1045 CALL timeset(routinen, handle)
1048 dft_control=dft_control, &
1049 scf_control=scf_control, &
1052 bs_env%n_spin = dft_control%nspins
1053 IF (bs_env%n_spin == 1) bs_env%spin_degeneracy = 2.0_dp
1054 IF (bs_env%n_spin == 2) bs_env%spin_degeneracy = 1.0_dp
1056 CALL get_mo_set(mo_set=mos(1), nao=n_ao, homo=homo, nelectron=nelectron, maxocc=maxocc)
1058 bs_env%n_occ_nosmear(1:2) = nint(nelectron/maxocc)
1059 bs_env%n_electron(1:2) = nelectron
1061 bs_env%n_mo_retained = n_ao
1062 bs_env%n_occ(1:2) = homo
1063 bs_env%n_vir(1:2) = n_ao - homo
1064 IF (bs_env%n_spin == 2)
THEN
1065 CALL get_mo_set(mo_set=mos(2), homo=homo, nelectron=nelectron, maxocc=maxocc)
1066 bs_env%n_occ_nosmear(2) = nint(nelectron/maxocc)
1067 bs_env%n_occ(2) = homo
1068 bs_env%n_vir(2) = n_ao - homo
1069 bs_env%n_electron(2) = nelectron
1071 bs_env%eps_eigval_mat_s = scf_control%eps_eigval
1075 bs_env%do_smear = .false.
1077 bs_env%smear_width = 0.0_dp
1078 IF (scf_control%smear%do_smear)
THEN
1079 SELECT CASE (scf_control%smear%method)
1081 bs_env%do_smear = .true.
1083 bs_env%smear_width = scf_control%smear%electronic_temperature
1085 bs_env%do_smear = .true.
1086 bs_env%smear_method = scf_control%smear%method
1087 bs_env%smear_width = scf_control%smear%smearing_width
1089 IF (bs_env%unit_nr > 0)
THEN
1090 WRITE (bs_env%unit_nr,
'(T2,A)') &
1091 'SMEAR method not supported for the post-SCF Fermi level search, '// &
1092 'falling back to a T=0 bisection.'
1096 cpassert(scf_control%smear%fixed_mag_mom <= 0.0_dp)
1100 ALLOCATE (bs_env%para_env)
1101 CALL bs_env%para_env%from_split(para_env, color_sub)
1103 CALL get_qs_env(qs_env, particle_set=particle_set)
1105 n_atom =
SIZE(particle_set)
1106 bs_env%n_atom = n_atom
1109 CALL get_cell(cell=cell, periodic=periodic, h=hmat)
1110 bs_env%periodic(1:3) = periodic(1:3)
1111 bs_env%do_periodic = any(bs_env%periodic /= 0)
1112 bs_env%hmat(1:3, 1:3) = hmat
1113 bs_env%nimages_scf = dft_control%nimages
1114 IF (dft_control%nimages == 1)
THEN
1115 IF (bs_env%do_gw_ri_rs)
THEN
1116 IF (bs_env%do_periodic)
THEN
1121 ELSE IF (bs_env%do_static_cohsex)
THEN
1126 ELSE IF (dft_control%nimages > 1)
THEN
1127 IF (bs_env%do_gw_ri_rs)
THEN
1128 cpabort(
"RI-RS Not Implemented for K-point Calculations")
1129 ELSE IF (bs_env%do_static_cohsex)
THEN
1130 cpabort(
"COHSEX Not Implemented for K-point Calculations")
1135 cpabort(
"Wrong number of cells from DFT calculation.")
1142 CALL section_vals_val_get(input,
"DFT%REAL_TIME_PROPAGATION%RTBSE%_SECTION_PARAMETERS_", i_val=bs_env%rtp_method)
1145 WRITE (u, fmt=
"(T2,2A,T73,I8)")
"Number of occupied molecular orbitals (MOs) ", &
1146 "= Number of occupied bands", homo
1147 WRITE (u, fmt=
"(T2,2A,T73,I8)")
"Number of unoccupied (= virtual) MOs ", &
1148 "= Number of unoccupied bands", n_ao - homo
1149 WRITE (u, fmt=
"(T2,A,T73,I8)")
"Number of Gaussian basis functions for MOs", n_ao
1151 WRITE (u, fmt=
"(T2,2A,T73,I8)")
"Number of cells considered in the DFT ", &
1152 "calculation", bs_env%nimages_scf
1156 CALL timestop(handle)
1158 END SUBROUTINE get_parameters_from_qs_env
1164 SUBROUTINE set_heuristic_parameters(bs_env)
1167 CHARACTER(LEN=*),
PARAMETER :: routinen =
'set_heuristic_parameters'
1171 CALL timeset(routinen, handle)
1173 bs_env%n_bins_max_for_printing = 5000
1175 CALL timestop(handle)
1177 END SUBROUTINE set_heuristic_parameters
1184 SUBROUTINE allocate_and_fill_fm_ks_fm_s(qs_env, bs_env)
1188 CHARACTER(LEN=*),
PARAMETER :: routinen =
'allocate_and_fill_fm_ks_fm_s'
1190 INTEGER :: handle, i_work, ispin
1193 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks, matrix_s
1196 CALL timeset(routinen, handle)
1199 para_env=para_env, &
1200 blacs_env=blacs_env, &
1201 matrix_ks_kp=matrix_ks, &
1202 matrix_s_kp=matrix_s)
1206 ncol_global=bs_env%n_ao, para_env=para_env)
1208 DO i_work = 1,
SIZE(bs_env%fm_work_mo)
1209 CALL cp_fm_create(bs_env%fm_work_mo(i_work), fm_struct)
1218 DO ispin = 1, bs_env%n_spin
1219 CALL cp_fm_create(bs_env%fm_ks_Gamma(ispin), fm_struct)
1220 CALL copy_dbcsr_to_fm(matrix_ks(ispin, 1)%matrix, bs_env%fm_ks_Gamma(ispin))
1221 CALL cp_fm_create(bs_env%fm_mo_coeff_Gamma(ispin), fm_struct)
1226 NULLIFY (bs_env%mat_ao_ao%matrix)
1227 ALLOCATE (bs_env%mat_ao_ao%matrix)
1228 CALL dbcsr_create(bs_env%mat_ao_ao%matrix, template=matrix_s(1, 1)%matrix, &
1229 matrix_type=dbcsr_type_no_symmetry)
1231 ALLOCATE (bs_env%eigenval_scf(bs_env%n_ao, bs_env%nkp_bs_and_DOS, bs_env%n_spin))
1233 CALL timestop(handle)
1235 END SUBROUTINE allocate_and_fill_fm_ks_fm_s
1246 CHARACTER(LEN=*),
PARAMETER :: routinen =
'eval_bandstructure_properties'
1248 CHARACTER(LEN=default_string_length) :: gw_label, gw_soc_label
1249 INTEGER :: handle, homo, homo_1, homo_2, &
1250 homo_spinor, ikp, ikp_for_file, ispin, &
1251 n_ao, n_e, nkind, nkp
1252 LOGICAL :: is_bandstruc_kpoint, print_dos_kpoints, &
1254 REAL(kind=
dp) :: broadening, e_max, e_max_g0w0, e_min, e_min_g0w0, e_total_window, &
1255 energy_step_dos, energy_window_dos, n_el_spinor, t1
1256 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos_g0w0, dos_g0w0_soc, dos_scf, dos_scf_soc, &
1257 eigenval, eigenval_spinor, eigenval_spinor_g0w0, eigenval_spinor_no_soc
1258 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: eigenval_spinor_all_gw, &
1259 eigenval_spinor_all_scf, pdos_g0w0, pdos_g0w0_soc, pdos_scf, pdos_scf_soc, proj_mo_on_kind
1260 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_g0w0_2d, ldos_scf_2d, &
1263 band_edges_scf, band_edges_scf_guess, &
1265 TYPE(
cp_cfm_type) :: cfm_ks_ikp, cfm_ks_ikp_spinor, cfm_mos_ikp_spinor, cfm_s_ikp, &
1266 cfm_s_ikp_copy, cfm_s_ikp_spinor, cfm_s_ikp_spinor_copy, cfm_soc_ikp_spinor, &
1267 cfm_spinor_wf_ikp, cfm_work_ikp, cfm_work_ikp_spinor
1270 CALL timeset(routinen, handle)
1274 energy_window_dos = bs_env%energy_window_DOS
1275 energy_step_dos = bs_env%energy_step_DOS
1276 broadening = bs_env%broadening_DOS
1279 IF (bs_env%do_gw .OR. &
1281 band_edges_scf = bs_env%band_edges_scf
1282 band_edges_scf_guess = band_edges_scf
1285 IF (bs_env%n_spin == 1)
THEN
1286 homo = bs_env%n_occ(1)
1287 band_edges_scf_guess%VBM = bs_env%eigenval_scf_Gamma(homo, 1)
1288 band_edges_scf_guess%CBM = bs_env%eigenval_scf_Gamma(homo + 1, 1)
1290 homo_1 = bs_env%n_occ(1)
1291 homo_2 = bs_env%n_occ(2)
1292 band_edges_scf_guess%VBM = max(bs_env%eigenval_scf_Gamma(homo_1, 1), &
1293 bs_env%eigenval_scf_Gamma(homo_2, 2))
1294 band_edges_scf_guess%CBM = min(bs_env%eigenval_scf_Gamma(homo_1 + 1, 1), &
1295 bs_env%eigenval_scf_Gamma(homo_2 + 1, 2))
1299 band_edges_scf%VBM = -1000.0_dp
1300 band_edges_scf%CBM = 1000.0_dp
1301 band_edges_scf%DBG = 1000.0_dp
1304 e_min = band_edges_scf_guess%VBM - 0.5_dp*energy_window_dos
1305 e_max = band_edges_scf_guess%CBM + 0.5_dp*energy_window_dos
1307 IF (bs_env%do_gw)
THEN
1308 band_edges_g0w0 = bs_env%band_edges_GW
1309 e_min_g0w0 = band_edges_g0w0%VBM - 0.5_dp*energy_window_dos
1310 e_max_g0w0 = band_edges_g0w0%CBM + 0.5_dp*energy_window_dos
1311 e_min = min(e_min, e_min_g0w0)
1312 e_max = max(e_max, e_max_g0w0)
1315 e_total_window = e_max - e_min
1317 n_e = int(e_total_window/energy_step_dos)
1321 ALLOCATE (proj_mo_on_kind(n_ao, nkind))
1322 proj_mo_on_kind(:, :) = 0.0_dp
1324 ALLOCATE (eigenval(n_ao))
1325 ALLOCATE (eigenval_spinor(2*n_ao))
1326 ALLOCATE (eigenval_spinor_no_soc(2*n_ao))
1327 ALLOCATE (eigenval_spinor_g0w0(2*n_ao))
1332 IF (bs_env%do_soc)
THEN
1333 ALLOCATE (eigenval_spinor_all_scf(2*n_ao, bs_env%nkp_bs_and_DOS))
1334 IF (bs_env%do_gw)
THEN
1335 ALLOCATE (eigenval_spinor_all_gw(2*n_ao, bs_env%nkp_bs_and_DOS))
1339 IF (bs_env%do_dos_pdos)
THEN
1341 ALLOCATE (dos_scf(n_e))
1343 ALLOCATE (pdos_scf(n_e, nkind))
1344 pdos_scf(:, :) = 0.0_dp
1346 IF (bs_env%do_soc)
THEN
1348 ALLOCATE (dos_scf_soc(n_e))
1349 dos_scf_soc(:) = 0.0_dp
1350 ALLOCATE (pdos_scf_soc(n_e, nkind))
1351 pdos_scf_soc(:, :) = 0.0_dp
1355 IF (bs_env%do_gw)
THEN
1357 ALLOCATE (dos_g0w0(n_e))
1358 dos_g0w0(:) = 0.0_dp
1359 ALLOCATE (pdos_g0w0(n_e, nkind))
1360 pdos_g0w0(:, :) = 0.0_dp
1362 IF (bs_env%do_soc)
THEN
1364 ALLOCATE (dos_g0w0_soc(n_e))
1365 dos_g0w0_soc(:) = 0.0_dp
1366 ALLOCATE (pdos_g0w0_soc(n_e, nkind))
1367 pdos_g0w0_soc(:, :) = 0.0_dp
1373 CALL cp_cfm_create(cfm_mos_ikp(1), bs_env%fm_ks_Gamma(1)%matrix_struct)
1374 CALL cp_cfm_create(cfm_mos_ikp(2), bs_env%fm_ks_Gamma(1)%matrix_struct)
1375 CALL cp_cfm_create(cfm_work_ikp, bs_env%fm_ks_Gamma(1)%matrix_struct)
1376 CALL cp_cfm_create(cfm_s_ikp_copy, bs_env%fm_ks_Gamma(1)%matrix_struct)
1378 IF (bs_env%do_soc)
THEN
1380 CALL cp_cfm_create(cfm_mos_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1381 CALL cp_cfm_create(cfm_work_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1382 CALL cp_cfm_create(cfm_s_ikp_spinor_copy, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1383 CALL cp_cfm_create(cfm_ks_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1384 CALL cp_cfm_create(cfm_soc_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1385 CALL cp_cfm_create(cfm_s_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1386 CALL cp_cfm_create(cfm_spinor_wf_ikp, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1388 homo_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
1390 SELECT CASE (bs_env%n_spin)
1392 n_el_spinor = real(bs_env%n_electron(1), kind=
dp)
1394 n_el_spinor = real(bs_env%n_electron(1) + bs_env%n_electron(2), kind=
dp)
1397 band_edges_scf_soc%VBM = -1000.0_dp
1398 band_edges_scf_soc%CBM = 1000.0_dp
1399 band_edges_scf_soc%DBG = 1000.0_dp
1401 IF (bs_env%do_gw)
THEN
1402 band_edges_g0w0_soc%VBM = -1000.0_dp
1403 band_edges_g0w0_soc%CBM = 1000.0_dp
1404 band_edges_g0w0_soc%DBG = 1000.0_dp
1407 IF (bs_env%unit_nr > 0)
THEN
1408 WRITE (bs_env%unit_nr,
'(A)')
''
1409 IF (bs_env%soc_window_occ > 0.0_dp)
THEN
1410 WRITE (bs_env%unit_nr,
'(T2,A,T71,F10.2)')
'SOC requested, SOC energy window occ (eV):', &
1411 bs_env%soc_window_occ*
evolt
1413 WRITE (bs_env%unit_nr,
'(T2,A,T71,A10)')
'SOC requested, SOC energy window occ (eV):', &
1416 IF (bs_env%soc_window_virt > 0.0_dp)
THEN
1417 WRITE (bs_env%unit_nr,
'(T2,A,T71,F10.2)')
'SOC requested, SOC energy window virt (eV):', &
1418 bs_env%soc_window_virt*
evolt
1420 WRITE (bs_env%unit_nr,
'(T2,A,T71,A10)')
'SOC requested, SOC energy window virt (eV):', &
1423 IF (bs_env%soc_window_occ > 0.0_dp .OR. bs_env%soc_window_virt > 0.0_dp)
THEN
1424 WRITE (bs_env%unit_nr,
'(T2,A,T71,F10.2)')
'SOC requested, SOC window smearing (eV):', &
1425 bs_env%soc_window_smearing*
evolt
1430 IF (bs_env%do_ldos)
THEN
1435 CALL cp_cfm_create(cfm_ks_ikp, bs_env%cfm_ks_kp(1, 1)%matrix_struct)
1436 CALL cp_cfm_create(cfm_s_ikp, bs_env%cfm_ks_kp(1, 1)%matrix_struct)
1439 DO ikp = 1, bs_env%nkp_bs_and_DOS
1443 DO ispin = 1, bs_env%n_spin
1445 SELECT CASE (bs_env%gw_implementation)
1450 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
1454 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
1458 CALL cp_cfm_geeig(cfm_ks_ikp, cfm_s_ikp_copy, cfm_mos_ikp(ispin), &
1459 eigenval, cfm_work_ikp)
1461 bs_env%eigenval_scf(:, ikp, ispin) = eigenval(:)
1466 CALL cp_cfm_to_cfm(bs_env%cfm_ks_kp(ikp, ispin), cfm_ks_ikp)
1472 CALL cp_cfm_to_cfm(bs_env%cfm_mo_coeff_kp(ikp, ispin), cfm_mos_ikp(ispin))
1473 eigenval(:) = bs_env%eigenval_scf(:, ikp, ispin)
1479 CALL compute_proj_mo_on_kind(proj_mo_on_kind, qs_env, cfm_mos_ikp(ispin), cfm_s_ikp)
1482 IF (bs_env%do_dos_pdos)
THEN
1483 CALL add_to_dos_pdos(dos_scf, pdos_scf, eigenval, ikp, bs_env, n_e, e_min, &
1486 IF (bs_env%do_gw)
THEN
1487 CALL add_to_dos_pdos(dos_g0w0, pdos_g0w0, bs_env%eigenval_GW(:, ikp, ispin), &
1488 ikp, bs_env, n_e, e_min, proj_mo_on_kind)
1492 IF (bs_env%do_ldos)
THEN
1493 CALL add_to_ldos_2d(ldos_scf_2d, qs_env, ikp, bs_env, cfm_mos_ikp(ispin), &
1494 eigenval(:), band_edges_scf_guess)
1496 IF (bs_env%do_gw)
THEN
1497 CALL add_to_ldos_2d(ldos_g0w0_2d, qs_env, ikp, bs_env, cfm_mos_ikp(ispin), &
1498 bs_env%eigenval_GW(:, ikp, 1), band_edges_g0w0)
1503 homo = bs_env%n_occ(ispin)
1505 band_edges_scf%VBM = max(band_edges_scf%VBM, eigenval(homo))
1506 band_edges_scf%CBM = min(band_edges_scf%CBM, eigenval(homo + 1))
1507 band_edges_scf%DBG = min(band_edges_scf%DBG, eigenval(homo + 1) - eigenval(homo))
1512 IF (bs_env%do_soc)
THEN
1515 print_dos_kpoints = (bs_env%nkp_only_bs <= 0)
1517 is_bandstruc_kpoint = (ikp > bs_env%nkp_only_DOS)
1518 print_ikp = print_dos_kpoints .OR. is_bandstruc_kpoint
1520 IF (print_dos_kpoints)
THEN
1521 nkp = bs_env%nkp_only_DOS
1524 nkp = bs_env%nkp_only_bs
1525 ikp_for_file = ikp - bs_env%nkp_only_DOS
1529 CALL soc_ev(bs_env, qs_env, ikp, bs_env%eigenval_scf, &
1530 e_min, cfm_mos_ikp, dos_scf_soc, pdos_scf_soc, &
1531 band_edges_scf_soc, eigenval_spinor, cfm_spinor_wf_ikp)
1532 eigenval_spinor_all_scf(:, ikp) = eigenval_spinor
1533 IF (.NOT. bs_env%do_gw .AND. print_ikp)
THEN
1534 CALL write_soc_eigenvalues(eigenval_spinor, ikp_for_file, ikp, bs_env)
1537 IF (bs_env%do_ldos)
THEN
1538 CALL add_to_ldos_2d(ldos_scf_2d_soc, qs_env, ikp, bs_env, cfm_spinor_wf_ikp, &
1539 eigenval_spinor, band_edges_scf_guess, .true., cfm_work_ikp)
1542 IF (bs_env%do_gw)
THEN
1545 CALL soc_ev(bs_env, qs_env, ikp, bs_env%eigenval_GW, &
1546 e_min, cfm_mos_ikp, dos_g0w0_soc, pdos_g0w0_soc, &
1547 band_edges_g0w0_soc, eigenval_spinor_g0w0, cfm_spinor_wf_ikp)
1548 eigenval_spinor_all_gw(:, ikp) = eigenval_spinor_g0w0
1552 CALL write_soc_eigenvalues(eigenval_spinor, ikp_for_file, ikp, bs_env, &
1553 eigenval_spinor_g0w0)
1560 IF (bs_env%unit_nr > 0 .AND.
m_walltime() - t1 > 20.0_dp)
THEN
1561 WRITE (bs_env%unit_nr,
'(T2,A,T43,I5,A,I3,A,F7.1,A)') &
1562 'Compute DOS, LDOS for k-point ', ikp,
' /', bs_env%nkp_bs_and_DOS, &
1568 band_edges_scf%IDBG = band_edges_scf%CBM - band_edges_scf%VBM
1570 SELECT CASE (bs_env%n_spin)
1572 CALL get_fermi_level_1c(bs_env, bs_env%eigenval_scf(:, :, 1), &
1573 REAL(bs_env%n_electron(1), kind=
dp), &
1574 bs_env%spin_degeneracy, band_edges_scf%VBM, &
1575 band_edges_scf%CBM, band_edges_scf%E_fermi)
1577 CALL get_fermi_level_2c(bs_env, bs_env%eigenval_scf(:, :, 1:2), &
1578 REAL(bs_env%n_electron(1) + bs_env%n_electron(2), kind=
dp), &
1579 band_edges_scf%VBM, band_edges_scf%CBM, band_edges_scf%E_fermi)
1582 IF (bs_env%do_soc)
THEN
1583 band_edges_scf_soc%IDBG = band_edges_scf_soc%CBM - band_edges_scf_soc%VBM
1587 CALL get_fermi_level_1c(bs_env, eigenval_spinor_all_scf, &
1588 n_el_spinor, 1.0_dp, &
1589 band_edges_scf_soc%VBM, band_edges_scf_soc%CBM, band_edges_scf_soc%E_fermi)
1591 IF (bs_env%do_gw)
THEN
1592 band_edges_g0w0_soc%IDBG = band_edges_g0w0_soc%CBM - band_edges_g0w0_soc%VBM
1593 CALL get_fermi_level_1c(bs_env, eigenval_spinor_all_gw, &
1594 n_el_spinor, 1.0_dp, &
1595 band_edges_g0w0_soc%VBM, band_edges_g0w0_soc%CBM, band_edges_g0w0_soc%E_fermi)
1600 CALL write_band_edges(band_edges_scf,
"SCF", bs_env)
1601 IF (bs_env%do_dos_pdos)
THEN
1602 CALL write_dos_pdos(dos_scf, pdos_scf, bs_env, qs_env,
"SCF", e_min, band_edges_scf%VBM)
1604 IF (bs_env%do_ldos)
THEN
1605 CALL print_ldos_main(ldos_scf_2d, bs_env, band_edges_scf,
"SCF")
1608 IF (bs_env%do_soc)
THEN
1609 CALL write_band_edges(band_edges_scf_soc,
"SCF+SOC", bs_env)
1610 IF (bs_env%do_dos_pdos)
THEN
1611 CALL write_dos_pdos(dos_scf_soc, pdos_scf_soc, bs_env, qs_env,
"SCF_SOC", &
1612 e_min, band_edges_scf_soc%VBM)
1614 IF (bs_env%do_ldos)
THEN
1617 CALL print_ldos_main(ldos_scf_2d_soc, bs_env, band_edges_scf, &
1625 gw_soc_label = trim(gw_label)//
"+SOC"
1627 IF (bs_env%do_gw)
THEN
1628 CALL write_band_edges(band_edges_g0w0, trim(gw_label), bs_env)
1629 CALL write_band_edges(bs_env%band_edges_HF,
"Hartree-Fock with SCF orbitals", bs_env)
1630 IF (bs_env%do_dos_pdos)
THEN
1631 CALL write_dos_pdos(dos_g0w0, pdos_g0w0, bs_env, qs_env,
"G0W0", e_min, &
1632 band_edges_g0w0%VBM)
1634 IF (bs_env%do_ldos)
THEN
1635 CALL print_ldos_main(ldos_g0w0_2d, bs_env, band_edges_g0w0,
"G0W0")
1639 IF (bs_env%do_soc .AND. bs_env%do_gw)
THEN
1640 CALL write_band_edges(band_edges_g0w0_soc, trim(gw_soc_label), bs_env)
1641 IF (bs_env%do_dos_pdos)
THEN
1642 CALL write_dos_pdos(dos_g0w0_soc, pdos_g0w0_soc, bs_env, qs_env,
"G0W0_SOC", e_min, &
1643 band_edges_g0w0_soc%VBM)
1662 CALL timestop(handle)
1673 SUBROUTINE print_ldos_main(LDOS_2d, bs_env, band_edges, scf_gw_soc)
1674 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d
1677 CHARACTER(LEN=*) :: scf_gw_soc
1679 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_LDOS_main'
1681 INTEGER :: handle, i_x, i_x_bin, i_x_end, i_x_end_bin, i_x_end_glob, i_x_start, &
1682 i_x_start_bin, i_x_start_glob, i_y, i_y_bin, i_y_end, i_y_end_bin, i_y_end_glob, &
1683 i_y_start, i_y_start_bin, i_y_start_glob, n_e
1684 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: n_sum_for_bins
1685 INTEGER,
DIMENSION(2) :: bin_mesh
1686 LOGICAL :: do_xy_bins
1687 REAL(kind=
dp) :: e_min, energy_step, energy_window
1688 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d_bins
1690 CALL timeset(routinen, handle)
1692 n_e =
SIZE(ldos_2d, 3)
1694 energy_window = bs_env%energy_window_DOS
1695 energy_step = bs_env%energy_step_DOS
1696 e_min = band_edges%VBM - 0.5_dp*energy_window
1698 bin_mesh(1:2) = bs_env%bin_mesh(1:2)
1699 do_xy_bins = (bin_mesh(1) > 0 .AND. bin_mesh(2) > 0)
1701 i_x_start = lbound(ldos_2d, 1)
1702 i_x_end = ubound(ldos_2d, 1)
1703 i_y_start = lbound(ldos_2d, 2)
1704 i_y_end = ubound(ldos_2d, 2)
1706 IF (do_xy_bins)
THEN
1708 i_x_end_bin = bin_mesh(1)
1710 i_y_end_bin = bin_mesh(2)
1712 i_x_start_bin = i_x_start
1713 i_x_end_bin = i_x_end
1714 i_y_start_bin = i_y_start
1715 i_y_end_bin = i_y_end
1718 ALLOCATE (ldos_2d_bins(i_x_start_bin:i_x_end_bin, i_y_start_bin:i_y_end_bin, n_e))
1719 ldos_2d_bins(:, :, :) = 0.0_dp
1721 IF (do_xy_bins)
THEN
1723 i_x_start_glob = i_x_start
1724 i_x_end_glob = i_x_end
1725 i_y_start_glob = i_y_start
1726 i_y_end_glob = i_y_end
1728 CALL bs_env%para_env%min(i_x_start_glob)
1729 CALL bs_env%para_env%max(i_x_end_glob)
1730 CALL bs_env%para_env%min(i_y_start_glob)
1731 CALL bs_env%para_env%max(i_y_end_glob)
1733 ALLOCATE (n_sum_for_bins(bin_mesh(1), bin_mesh(2)), source=0)
1736 DO i_y = i_y_start, i_y_end
1737 DO i_x = i_x_start, i_x_end
1738 i_x_bin = bin_mesh(1)*(i_x - i_x_start_glob)/(i_x_end_glob - i_x_start_glob + 1) + 1
1739 i_y_bin = bin_mesh(2)*(i_y - i_y_start_glob)/(i_y_end_glob - i_y_start_glob + 1) + 1
1740 ldos_2d_bins(i_x_bin, i_y_bin, :) = ldos_2d_bins(i_x_bin, i_y_bin, :) + &
1741 ldos_2d(i_x, i_y, :)
1742 n_sum_for_bins(i_x_bin, i_y_bin) = n_sum_for_bins(i_x_bin, i_y_bin) + 1
1746 CALL bs_env%para_env%sum(ldos_2d_bins)
1747 CALL bs_env%para_env%sum(n_sum_for_bins)
1750 DO i_y_bin = 1, bin_mesh(2)
1751 DO i_x_bin = 1, bin_mesh(1)
1752 ldos_2d_bins(i_x_bin, i_y_bin, :) = ldos_2d_bins(i_x_bin, i_y_bin, :)/ &
1753 REAL(n_sum_for_bins(i_x_bin, i_y_bin), kind=
dp)
1759 ldos_2d_bins(:, :, :) = ldos_2d(:, :, :)
1763 IF (bin_mesh(1)*bin_mesh(2) < bs_env%n_bins_max_for_printing)
THEN
1764 CALL print_ldos_2d_bins(ldos_2d_bins, bs_env, e_min, scf_gw_soc)
1766 cpwarn(
"The number of bins for the LDOS is too large. Decrease BIN_MESH.")
1769 CALL timestop(handle)
1771 END SUBROUTINE print_ldos_main
1780 SUBROUTINE print_ldos_2d_bins(LDOS_2d_bins, bs_env, E_min, scf_gw_soc)
1781 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d_bins
1783 REAL(kind=
dp) :: e_min
1784 CHARACTER(LEN=*) :: scf_gw_soc
1786 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_LDOS_2d_bins'
1788 CHARACTER(LEN=18) :: print_format
1789 CHARACTER(LEN=4) :: print_format_1, print_format_2
1790 CHARACTER(len=default_string_length) :: fname
1791 INTEGER :: handle, i_e, i_x, i_x_end, i_x_start, &
1792 i_y, i_y_end, i_y_start, iunit, n_e, &
1794 REAL(kind=
dp) :: energy
1795 REAL(kind=
dp),
DIMENSION(3) :: coord,
idx
1797 CALL timeset(routinen, handle)
1799 i_x_start = lbound(ldos_2d_bins, 1)
1800 i_x_end = ubound(ldos_2d_bins, 1)
1801 i_y_start = lbound(ldos_2d_bins, 2)
1802 i_y_end = ubound(ldos_2d_bins, 2)
1803 n_e =
SIZE(ldos_2d_bins, 3)
1805 n_x = i_x_end - i_x_start + 1
1806 n_y = i_y_end - i_y_start + 1
1808 IF (bs_env%para_env%is_source())
THEN
1810 DO i_y = i_y_start, i_y_end
1811 DO i_x = i_x_start, i_x_end
1813 idx(1) = (real(i_x, kind=
dp) - 0.5_dp)/real(n_x, kind=
dp)
1814 idx(2) = (real(i_y, kind=
dp) - 0.5_dp)/real(n_y, kind=
dp)
1816 coord(1:3) = matmul(bs_env%hmat,
idx)
1818 CALL get_print_format(coord(1), print_format_1)
1819 CALL get_print_format(coord(2), print_format_2)
1821 print_format =
"(3A,"//print_format_1//
",A,"//print_format_2//
",A)"
1823 WRITE (fname, print_format)
"LDOS_", scf_gw_soc, &
1826 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", &
1827 file_action=
"WRITE")
1829 WRITE (iunit,
"(2A)")
" Energy E (eV) average LDOS(x,y,E) (1/(eV*Å^2), ", &
1830 "integrated over z, averaged inside bin)"
1833 energy = e_min + i_e*bs_env%energy_step_DOS
1834 WRITE (iunit,
"(2F17.3)") energy*
evolt, &
1835 ldos_2d_bins(i_x, i_y, i_e)* &
1836 bs_env%unit_ldos_int_z_inv_Ang2_eV
1846 CALL timestop(handle)
1848 END SUBROUTINE print_ldos_2d_bins
1855 SUBROUTINE get_print_format(coord, print_format)
1856 REAL(kind=
dp) :: coord
1857 CHARACTER(LEN=4) :: print_format
1859 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_print_format'
1863 CALL timeset(routinen, handle)
1866 print_format =
"F9.2"
1867 ELSE IF (coord < -1000/
angstrom)
THEN
1868 print_format =
"F8.2"
1869 ELSE IF (coord < -100/
angstrom)
THEN
1870 print_format =
"F7.2"
1871 ELSE IF (coord < -10/
angstrom)
THEN
1872 print_format =
"F6.2"
1874 print_format =
"F5.2"
1876 print_format =
"F4.2"
1877 ELSE IF (coord < 100/
angstrom)
THEN
1878 print_format =
"F5.2"
1879 ELSE IF (coord < 1000/
angstrom)
THEN
1880 print_format =
"F6.2"
1881 ELSE IF (coord < 10000/
angstrom)
THEN
1882 print_format =
"F7.2"
1884 print_format =
"F8.2"
1887 CALL timestop(handle)
1889 END SUBROUTINE get_print_format
1905 SUBROUTINE soc_ev(bs_env, qs_env, ikp, eigenval_no_SOC, E_min, cfm_mos_ikp, &
1906 DOS, PDOS, band_edges, eigenval_spinor, cfm_spinor_wf_ikp)
1911 REAL(kind=
dp),
DIMENSION(:, :, :) :: eigenval_no_soc
1912 REAL(kind=
dp) :: e_min
1914 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos
1915 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
1917 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor
1920 CHARACTER(LEN=*),
PARAMETER :: routinen =
'SOC_ev'
1923 LOGICAL :: do_truncate
1925 CALL timeset(routinen, handle)
1928 do_truncate = (bs_env%soc_nbands_occ > 0 .AND. bs_env%soc_nbands_virt > 0)
1930 IF (do_truncate)
THEN
1931 CALL soc_ev_truncate_mos(bs_env, qs_env, ikp, eigenval_no_soc, cfm_mos_ikp, &
1932 band_edges, eigenval_spinor, cfm_spinor_wf_ikp)
1934 CALL soc_ev_all_mos(bs_env, qs_env, ikp, eigenval_no_soc, e_min, cfm_mos_ikp, &
1935 dos, pdos, band_edges, eigenval_spinor, cfm_spinor_wf_ikp)
1938 CALL timestop(handle)
1940 END SUBROUTINE soc_ev
1957 SUBROUTINE soc_ev_all_mos(bs_env, qs_env, ikp, eigenval_no_SOC, E_min, cfm_mos_ikp, &
1958 DOS, PDOS, band_edges, eigenval_spinor, cfm_spinor_wf_ikp)
1963 REAL(kind=
dp),
DIMENSION(:, :, :) :: eigenval_no_soc
1964 REAL(kind=
dp) :: e_min
1966 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos
1967 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
1969 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor
1972 CHARACTER(LEN=*),
PARAMETER :: routinen =
'SOC_ev_all_mos'
1974 INTEGER :: handle, homo_spinor, n_ao, n_e, nkind
1975 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor_no_soc
1976 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind_spinor
1978 cfm_ks_ikp_spinor, cfm_mos_ikp_spinor, &
1979 cfm_soc_ikp_spinor, cfm_work_ikp_spinor
1981 CALL timeset(routinen, handle)
1984 homo_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
1987 CALL cp_cfm_create(cfm_ks_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1988 CALL cp_cfm_create(cfm_soc_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1989 CALL cp_cfm_create(cfm_mos_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1990 CALL cp_cfm_create(cfm_work_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1991 CALL cp_cfm_create(cfm_eigenvec_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1993 ALLOCATE (eigenval_spinor_no_soc(2*n_ao))
1994 ALLOCATE (proj_mo_on_kind_spinor(2*n_ao, nkind))
1996 proj_mo_on_kind_spinor(:, :) = 0.0_dp
1999 SELECT CASE (bs_env%gw_implementation)
2003 CALL cfm_ikp_from_cfm_spinor_gamma(cfm_soc_ikp_spinor, &
2004 bs_env%cfm_SOC_spinor_ao(1), &
2005 bs_env%fm_s_Gamma%matrix_struct, &
2006 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
2011 CALL cp_cfm_to_cfm(bs_env%cfm_SOC_spinor_ao(ikp), cfm_soc_ikp_spinor)
2021 CALL add_cfm_submat(cfm_mos_ikp_spinor, cfm_mos_ikp(bs_env%n_spin), n_ao + 1, n_ao + 1)
2025 cfm_mos_ikp_spinor, cfm_soc_ikp_spinor, &
2026 z_zero, cfm_work_ikp_spinor)
2030 cfm_work_ikp_spinor, cfm_mos_ikp_spinor, &
2031 z_zero, cfm_ks_ikp_spinor)
2036 eigenval_spinor_no_soc(1:n_ao) = eigenval_no_soc(1:n_ao, ikp, 1)
2037 eigenval_spinor_no_soc(n_ao + 1:) = eigenval_no_soc(1:n_ao, ikp, bs_env%n_spin)
2038 IF (bs_env%soc_window_occ > 0.0_dp .OR. bs_env%soc_window_virt > 0.0_dp)
THEN
2040 bs_env%soc_window_virt, &
2041 bs_env%soc_window_smearing, &
2042 eigenval_spinor_no_soc, &
2051 CALL cp_cfm_heevd(cfm_ks_ikp_spinor, cfm_eigenvec_ikp_spinor, eigenval_spinor)
2054 IF (bs_env%do_dos_pdos)
THEN
2056 CALL add_to_dos_pdos(dos, pdos, eigenval_spinor, &
2057 ikp, bs_env, n_e, e_min, proj_mo_on_kind_spinor)
2061 band_edges%VBM = max(band_edges%VBM, eigenval_spinor(homo_spinor))
2062 band_edges%CBM = min(band_edges%CBM, eigenval_spinor(homo_spinor + 1))
2063 band_edges%DBG = min(band_edges%DBG, eigenval_spinor(homo_spinor + 1) &
2064 - eigenval_spinor(homo_spinor))
2069 cfm_mos_ikp_spinor, cfm_eigenvec_ikp_spinor, &
2070 z_zero, cfm_spinor_wf_ikp)
2078 CALL timestop(handle)
2080 END SUBROUTINE soc_ev_all_mos
2095 SUBROUTINE soc_ev_truncate_mos(bs_env, qs_env, ikp, eigenval_no_SOC, cfm_mos_ikp, &
2096 band_edges, eigenval_spinor, cfm_spinor_wf_ikp)
2101 REAL(kind=
dp),
DIMENSION(:, :, :) :: eigenval_no_soc
2104 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor
2107 CHARACTER(LEN=*),
PARAMETER :: routinen =
'SOC_ev_truncate_mos'
2109 INTEGER :: handle, homo_spinor, homo_used, &
2110 mo_index_start_1, mo_index_start_2, &
2111 n_ao, n_window, n_window2tot, nkind, &
2113 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eig_win_sorted, eigenval_spinor_no_soc
2114 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind_spinor
2116 cfm_ks_ikp_spinor, cfm_mos_ikp_spinor, &
2117 cfm_soc_ikp_spinor, cfm_work_ikp_spinor
2119 TYPE(
cp_fm_type) :: fm_src_im, fm_src_re, fm_tgt_im, &
2122 CALL timeset(routinen, handle)
2125 homo_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
2128 nocc = bs_env%soc_nbands_occ
2129 nvirt = bs_env%soc_nbands_virt
2130 cpassert(nocc <= bs_env%n_occ_nosmear(1))
2131 cpassert(nocc <= bs_env%n_occ_nosmear(bs_env%n_spin))
2132 cpassert(nvirt <= n_ao - bs_env%n_occ_nosmear(1))
2133 cpassert(nvirt <= n_ao - bs_env%n_occ_nosmear(bs_env%n_spin))
2134 cpassert(.NOT. bs_env%do_dos_pdos)
2135 mo_index_start_1 = bs_env%n_occ_nosmear(1) - nocc + 1
2136 mo_index_start_2 = bs_env%n_occ_nosmear(bs_env%n_spin) - nocc + 1
2137 n_window = nocc + nvirt
2138 n_window2tot = 2*n_window
2141 NULLIFY (fst_ww, fst_wa, fst_mos)
2143 template_fmstruct=bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
2145 template_fmstruct=bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
2147 template_fmstruct=bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
2151 CALL cp_cfm_create(cfm_soc_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
2154 ALLOCATE (eigenval_spinor_no_soc(2*n_ao))
2155 ALLOCATE (proj_mo_on_kind_spinor(2*n_ao, nkind))
2157 proj_mo_on_kind_spinor(:, :) = 0.0_dp
2160 SELECT CASE (bs_env%gw_implementation)
2164 CALL cfm_ikp_from_cfm_spinor_gamma(cfm_soc_ikp_spinor, &
2165 bs_env%cfm_SOC_spinor_ao(1), &
2166 bs_env%fm_s_Gamma%matrix_struct, &
2167 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
2172 CALL cp_cfm_to_cfm(bs_env%cfm_SOC_spinor_ao(ikp), cfm_soc_ikp_spinor)
2184 CALL cp_fm_create(fm_src_re, cfm_mos_ikp(1)%matrix_struct)
2185 CALL cp_fm_create(fm_src_im, cfm_mos_ikp(1)%matrix_struct)
2191 CALL cp_cfm_to_fm(cfm_mos_ikp(1), fm_src_re, fm_src_im)
2192 CALL cp_fm_to_fm_submat(msource=fm_src_re, mtarget=fm_tgt_re, nrow=n_ao, ncol=n_window, &
2193 s_firstrow=1, s_firstcol=mo_index_start_1, t_firstrow=1, t_firstcol=1)
2194 CALL cp_fm_to_fm_submat(msource=fm_src_im, mtarget=fm_tgt_im, nrow=n_ao, ncol=n_window, &
2195 s_firstrow=1, s_firstcol=mo_index_start_1, t_firstrow=1, t_firstcol=1)
2198 CALL cp_cfm_to_fm(cfm_mos_ikp(bs_env%n_spin), fm_src_re, fm_src_im)
2199 CALL cp_fm_to_fm_submat(msource=fm_src_re, mtarget=fm_tgt_re, nrow=n_ao, ncol=n_window, &
2200 s_firstrow=1, s_firstcol=mo_index_start_2, t_firstrow=n_ao + 1, t_firstcol=n_window + 1)
2201 CALL cp_fm_to_fm_submat(msource=fm_src_im, mtarget=fm_tgt_im, nrow=n_ao, ncol=n_window, &
2202 s_firstrow=1, s_firstcol=mo_index_start_2, t_firstrow=n_ao + 1, t_firstcol=n_window + 1)
2204 CALL cp_fm_to_cfm(fm_tgt_re, fm_tgt_im, cfm_mos_ikp_spinor)
2213 cfm_mos_ikp_spinor, cfm_soc_ikp_spinor, &
2214 z_zero, cfm_work_ikp_spinor)
2217 cfm_work_ikp_spinor, cfm_mos_ikp_spinor, &
2218 z_zero, cfm_ks_ikp_spinor)
2222 eigenval_spinor_no_soc(1:n_ao) = eigenval_no_soc(1:n_ao, ikp, 1)
2223 eigenval_spinor_no_soc(n_ao + 1:) = eigenval_no_soc(1:n_ao, ikp, bs_env%n_spin)
2227 [eigenval_no_soc(mo_index_start_1:mo_index_start_1 + n_window - 1, ikp, 1), &
2228 eigenval_no_soc(mo_index_start_2:mo_index_start_2 + n_window - 1, ikp, bs_env%n_spin)])
2231 ALLOCATE (eig_win_sorted(n_window2tot))
2232 CALL cp_cfm_heevd(cfm_ks_ikp_spinor, cfm_eigenvec_ikp_spinor, eig_win_sorted)
2237 band_edges%VBM = max(band_edges%VBM, eig_win_sorted(homo_used))
2238 band_edges%CBM = min(band_edges%CBM, eig_win_sorted(homo_used + 1))
2239 band_edges%DBG = min(band_edges%DBG, eig_win_sorted(homo_used + 1) - eig_win_sorted(homo_used))
2241 CALL fill_truncated_eigenval_spinor(eigenval_no_soc, eig_win_sorted, ikp, bs_env%n_spin, &
2242 n_ao, mo_index_start_1, mo_index_start_2, n_window, &
2243 n_window2tot, eigenval_spinor)
2247 cpassert(.NOT. bs_env%do_ldos)
2249 cfm_mos_ikp_spinor, cfm_eigenvec_ikp_spinor, &
2250 z_zero, cfm_spinor_wf_ikp)
2262 CALL timestop(handle)
2264 END SUBROUTINE soc_ev_truncate_mos
2278 SUBROUTINE fill_truncated_eigenval_spinor(eigenval_no_SOC, eig_win_sorted, ikp, n_spin, n_ao, &
2279 mo_index_start_1, mo_index_start_2, n_window, &
2280 n_window2tot, eigenval_spinor)
2281 REAL(kind=
dp),
DIMENSION(:, :, :) :: eigenval_no_soc
2282 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eig_win_sorted
2283 INTEGER :: ikp, n_spin, n_ao, mo_index_start_1, &
2284 mo_index_start_2, n_window, &
2286 REAL(kind=
dp),
DIMENSION(:) :: eigenval_spinor
2288 CHARACTER(LEN=*),
PARAMETER :: routinen =
'fill_truncated_eigenval_spinor'
2290 INTEGER :: handle, i, ia, ib, idx_end, idx_start, &
2291 mo_index_start_1_m1, &
2294 CALL timeset(routinen, handle)
2298 IF (mo_index_start_1 > 1)
THEN
2299 IF (eig_win_sorted(1) < eigenval_no_soc(mo_index_start_1 - 1, ikp, 1))
THEN
2300 cpabort(
"SOC_NBANDS_OCC too small.")
2303 IF (mo_index_start_2 > 1)
THEN
2304 IF (eig_win_sorted(1) < eigenval_no_soc(mo_index_start_2 - 1, ikp, n_spin))
THEN
2305 cpabort(
"SOC_NBANDS_OCC too small.")
2308 IF (mo_index_start_1 + n_window <= n_ao)
THEN
2309 IF (eig_win_sorted(n_window2tot) > eigenval_no_soc(mo_index_start_1 + n_window, ikp, 1))
THEN
2310 cpabort(
"SOC_NBANDS_VIRT too small.")
2313 IF (mo_index_start_2 + n_window <= n_ao)
THEN
2314 IF (eig_win_sorted(n_window2tot) > eigenval_no_soc(mo_index_start_2 + n_window, ikp, n_spin))
THEN
2315 cpabort(
"SOC_NBANDS_VIRT too small.")
2319 mo_index_start_1_m1 = mo_index_start_1 - 1
2320 mo_index_start_2_m1 = mo_index_start_2 - 1
2324 DO i = 1, mo_index_start_1_m1 + mo_index_start_2_m1
2325 IF (ia <= mo_index_start_1_m1 .AND. ib <= mo_index_start_2_m1)
THEN
2326 IF (eigenval_no_soc(ia, ikp, 1) <= eigenval_no_soc(ib, ikp, n_spin))
THEN
2327 eigenval_spinor(i) = eigenval_no_soc(ia, ikp, 1)
2330 eigenval_spinor(i) = eigenval_no_soc(ib, ikp, n_spin)
2333 ELSE IF (ia <= mo_index_start_1_m1)
THEN
2334 eigenval_spinor(i) = eigenval_no_soc(ia, ikp, 1)
2337 eigenval_spinor(i) = eigenval_no_soc(ib, ikp, n_spin)
2342 idx_start = mo_index_start_1_m1 + mo_index_start_2_m1 + 1
2343 idx_end = mo_index_start_1_m1 + mo_index_start_2_m1 + n_window2tot
2345 eigenval_spinor(idx_start:idx_end) = eig_win_sorted(:)
2347 ia = mo_index_start_1 + n_window
2348 ib = mo_index_start_2 + n_window
2349 DO i = mo_index_start_1_m1 + mo_index_start_2_m1 + n_window2tot + 1, 2*n_ao
2350 IF (ia <= n_ao .AND. ib <= n_ao)
THEN
2351 IF (eigenval_no_soc(ia, ikp, 1) <= eigenval_no_soc(ib, ikp, n_spin))
THEN
2352 eigenval_spinor(i) = eigenval_no_soc(ia, ikp, 1)
2355 eigenval_spinor(i) = eigenval_no_soc(ib, ikp, n_spin)
2358 ELSE IF (ia <= n_ao)
THEN
2359 eigenval_spinor(i) = eigenval_no_soc(ia, ikp, 1)
2362 eigenval_spinor(i) = eigenval_no_soc(ib, ikp, n_spin)
2367 DEALLOCATE (eig_win_sorted)
2369 CALL timestop(handle)
2371 END SUBROUTINE fill_truncated_eigenval_spinor
2383 SUBROUTINE add_to_dos_pdos(DOS, PDOS, eigenval, ikp, bs_env, n_E, E_min, proj_mo_on_kind)
2385 REAL(kind=
dp),
DIMENSION(:) :: dos
2386 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
2387 REAL(kind=
dp),
DIMENSION(:) :: eigenval
2391 REAL(kind=
dp) :: e_min
2392 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind
2394 CHARACTER(LEN=*),
PARAMETER :: routinen =
'add_to_DOS_PDOS'
2396 INTEGER :: handle, i_e, i_kind, i_mo, n_mo, nkind
2397 REAL(kind=
dp) :: broadening, energy, energy_step_dos, wkp
2399 CALL timeset(routinen, handle)
2401 energy_step_dos = bs_env%energy_step_DOS
2402 broadening = bs_env%broadening_DOS
2404 n_mo =
SIZE(eigenval)
2405 nkind =
SIZE(proj_mo_on_kind, 2)
2408 wkp = bs_env%kpoints_DOS%wkp(ikp)*bs_env%spin_degeneracy
2410 energy = e_min + i_e*energy_step_dos
2413 dos(i_e) = dos(i_e) + wkp*
gaussian(energy - eigenval(i_mo), broadening)
2416 DO i_kind = 1, nkind
2417 IF (proj_mo_on_kind(i_mo, i_kind) > 0.0_dp)
THEN
2418 pdos(i_e, i_kind) = pdos(i_e, i_kind) + &
2419 proj_mo_on_kind(i_mo, i_kind)*wkp* &
2420 gaussian(energy - eigenval(i_mo), broadening)
2426 CALL timestop(handle)
2428 END SUBROUTINE add_to_dos_pdos
2442 SUBROUTINE add_to_ldos_2d(LDOS_2d, qs_env, ikp, bs_env, cfm_mos_ikp, eigenval, &
2443 band_edges, do_spinor, cfm_non_spinor)
2444 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d
2449 REAL(kind=
dp),
DIMENSION(:) :: eigenval
2451 LOGICAL,
OPTIONAL :: do_spinor
2454 CHARACTER(LEN=*),
PARAMETER :: routinen =
'add_to_LDOS_2d'
2456 INTEGER :: handle, i_e, i_x_end, i_x_start, i_y_end, i_y_start, i_z, i_z_end, i_z_start, &
2457 j_col, j_mo, n_e, n_mo, n_z, ncol_local, nimages, z_end_global, z_start_global
2458 INTEGER,
DIMENSION(:),
POINTER :: col_indices
2459 LOGICAL :: is_any_weight_non_zero, my_do_spinor
2460 REAL(kind=
dp) :: broadening, e_max, e_min, &
2461 e_total_window, energy, energy_step, &
2462 energy_window, spin_degeneracy, weight
2463 TYPE(
cp_cfm_type) :: cfm_weighted_dm_ikp, cfm_work
2464 TYPE(
cp_fm_type) :: fm_non_spinor, fm_weighted_dm_mic
2465 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: weighted_dm_mic
2473 CALL timeset(routinen, handle)
2475 my_do_spinor = .false.
2476 IF (
PRESENT(do_spinor)) my_do_spinor = do_spinor
2478 CALL get_qs_env(qs_env, ks_env=ks_env, pw_env=pw_env, dft_control=dft_control)
2481 nimages = dft_control%nimages
2482 dft_control%nimages = bs_env%nimages_scf
2484 energy_window = bs_env%energy_window_DOS
2485 energy_step = bs_env%energy_step_DOS
2486 broadening = bs_env%broadening_DOS
2488 e_min = band_edges%VBM - 0.5_dp*energy_window
2489 e_max = band_edges%CBM + 0.5_dp*energy_window
2490 e_total_window = e_max - e_min
2492 n_e = int(e_total_window/energy_step)
2494 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
2496 CALL auxbas_pw_pool%create_pw(ldos_3d)
2497 CALL auxbas_pw_pool%create_pw(rho_g)
2499 i_x_start = lbound(ldos_3d%array, 1)
2500 i_x_end = ubound(ldos_3d%array, 1)
2501 i_y_start = lbound(ldos_3d%array, 2)
2502 i_y_end = ubound(ldos_3d%array, 2)
2503 i_z_start = lbound(ldos_3d%array, 3)
2504 i_z_end = ubound(ldos_3d%array, 3)
2506 z_start_global = i_z_start
2507 z_end_global = i_z_end
2509 CALL bs_env%para_env%min(z_start_global)
2510 CALL bs_env%para_env%max(z_end_global)
2511 n_z = z_end_global - z_start_global + 1
2513 IF (any(abs(bs_env%hmat(1:2, 3)) > 1.0e-6_dp) .OR. any(abs(bs_env%hmat(3, 1:2)) > 1.0e-6_dp))
THEN
2514 cpabort(
"Please choose a cell that has 90° angles to the z-direction.")
2517 bs_env%unit_ldos_int_z_inv_Ang2_eV = bs_env%hmat(3, 3)/real(n_z, kind=
dp)/
evolt/
angstrom**2
2520 ALLOCATE (ldos_2d(i_x_start:i_x_end, i_y_start:i_y_end, n_e))
2521 ldos_2d(:, :, :) = 0.0_dp
2525 CALL cp_cfm_create(cfm_weighted_dm_ikp, cfm_mos_ikp%matrix_struct)
2526 CALL cp_fm_create(fm_weighted_dm_mic, cfm_mos_ikp%matrix_struct)
2527 IF (my_do_spinor)
THEN
2528 CALL cp_fm_create(fm_non_spinor, cfm_non_spinor%matrix_struct)
2533 ncol_local=ncol_local, &
2534 col_indices=col_indices)
2536 NULLIFY (weighted_dm_mic)
2538 ALLOCATE (weighted_dm_mic(1)%matrix)
2539 CALL dbcsr_create(weighted_dm_mic(1)%matrix, template=bs_env%mat_ao_ao%matrix, &
2540 matrix_type=dbcsr_type_symmetric)
2544 energy = e_min + i_e*energy_step
2546 is_any_weight_non_zero = .false.
2548 DO j_col = 1, ncol_local
2550 j_mo = col_indices(j_col)
2552 IF (my_do_spinor)
THEN
2553 spin_degeneracy = 1.0_dp
2555 spin_degeneracy = bs_env%spin_degeneracy
2558 weight =
gaussian(energy - eigenval(j_mo), broadening)*spin_degeneracy
2560 cfm_work%local_data(:, j_col) = cfm_mos_ikp%local_data(:, j_col)*weight
2562 IF (weight > 1.0e-5_dp) is_any_weight_non_zero = .true.
2566 CALL bs_env%para_env%sync()
2567 CALL bs_env%para_env%sum(is_any_weight_non_zero)
2568 CALL bs_env%para_env%sync()
2571 IF (is_any_weight_non_zero)
THEN
2574 cfm_mos_ikp, cfm_work,
z_zero, cfm_weighted_dm_ikp)
2576 IF (my_do_spinor)
THEN
2582 cfm_non_spinor, ikp, bs_env%kpoints_DOS, &
2583 "ORB", bs_env%kpoints_DOS%wkp(ikp))
2586 CALL get_cfm_submat(cfm_non_spinor, cfm_weighted_dm_ikp, n_mo/2, n_mo/2)
2588 cfm_non_spinor, ikp, bs_env%kpoints_DOS, &
2589 "ORB", bs_env%kpoints_DOS%wkp(ikp))
2591 keep_sparsity=.false.)
2595 cfm_weighted_dm_ikp, ikp, bs_env%kpoints_DOS, &
2596 "ORB", bs_env%kpoints_DOS%wkp(ikp))
2598 keep_sparsity=.false.)
2601 ldos_3d%array(:, :, :) = 0.0_dp
2608 DO i_z = i_z_start, i_z_end
2609 ldos_2d(:, :, i_e) = ldos_2d(:, :, i_e) + ldos_3d%array(:, :, i_z)
2617 dft_control%nimages = nimages
2619 CALL auxbas_pw_pool%give_back_pw(ldos_3d)
2620 CALL auxbas_pw_pool%give_back_pw(rho_g)
2629 IF (my_do_spinor)
THEN
2633 CALL timestop(handle)
2635 END SUBROUTINE add_to_ldos_2d
2645 SUBROUTINE write_soc_eigenvalues(eigenval_spinor, ikp_for_file, ikp, bs_env, eigenval_spinor_G0W0)
2647 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor
2648 INTEGER :: ikp_for_file, ikp
2650 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: eigenval_spinor_g0w0
2652 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_SOC_eigenvalues'
2654 CHARACTER(len=3) :: occ_vir
2655 CHARACTER(LEN=default_string_length) :: fname
2656 INTEGER :: handle, i_mo, iunit, n_occ_spinor
2658 CALL timeset(routinen, handle)
2660 fname =
"bandstructure_SCF_and_G0W0_plus_SOC"
2662 IF (bs_env%para_env%is_source())
THEN
2664 IF (ikp_for_file == 1)
THEN
2665 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", &
2666 file_action=
"WRITE")
2668 CALL open_file(trim(fname), unit_number=iunit, file_status=
"OLD", &
2669 file_action=
"WRITE", file_position=
"APPEND")
2672 WRITE (iunit,
"(A)")
" "
2673 WRITE (iunit,
"(A10,I7,A25,3F10.4)")
"kpoint: ", ikp_for_file,
"coordinate: ", &
2674 bs_env%kpoints_DOS%xkp(:, ikp)
2675 WRITE (iunit,
"(A)")
" "
2677 IF (
PRESENT(eigenval_spinor_g0w0))
THEN
2679 WRITE (iunit,
"(A5,A12,2A22)")
"n",
"k",
"ϵ_nk^DFT+SOC (eV)",
"ϵ_nk^G0W0+SOC (eV)"
2682 WRITE (iunit,
"(A5,A12,A22)")
"n",
"k",
"ϵ_nk^DFT+SOC (eV)"
2685 n_occ_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
2687 DO i_mo = 1,
SIZE(eigenval_spinor)
2688 IF (i_mo <= n_occ_spinor) occ_vir =
'occ'
2689 IF (i_mo > n_occ_spinor) occ_vir =
'vir'
2690 IF (
PRESENT(eigenval_spinor_g0w0))
THEN
2692 WRITE (iunit,
"(I5,3A,I5,4F16.3,2F17.3)") i_mo,
' (', occ_vir,
') ', &
2693 ikp_for_file, eigenval_spinor(i_mo)*
evolt, eigenval_spinor_g0w0(i_mo)*
evolt
2696 WRITE (iunit,
"(I5,3A,I5,4F16.3,F17.3)") i_mo,
' (', occ_vir,
') ', &
2697 ikp_for_file, eigenval_spinor(i_mo)*
evolt
2705 CALL timestop(handle)
2707 END SUBROUTINE write_soc_eigenvalues
2714 PURE FUNCTION count_digits(int_number)
2716 INTEGER,
INTENT(IN) :: int_number
2717 INTEGER :: count_digits
2719 INTEGER :: digitcount, tempint
2723 tempint = int_number
2725 DO WHILE (tempint /= 0)
2726 tempint = tempint/10
2727 digitcount = digitcount + 1
2730 count_digits = digitcount
2732 END FUNCTION count_digits
2740 SUBROUTINE write_band_edges(band_edges, scf_gw_soc, bs_env)
2743 CHARACTER(LEN=*) :: scf_gw_soc
2746 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_band_edges'
2748 CHARACTER(LEN=17) :: print_format
2749 INTEGER :: handle, u
2751 CALL timeset(routinen, handle)
2754 print_format =
"(T2,2A,T61,F20.3)"
2758 WRITE (u,
'(T2,A)')
''
2759 WRITE (u, print_format) scf_gw_soc,
' valence band maximum (eV):', band_edges%VBM*
evolt
2760 WRITE (u, print_format) scf_gw_soc,
' conduction band minimum (eV):', band_edges%CBM*
evolt
2761 WRITE (u, print_format) scf_gw_soc,
' indirect band gap (eV):', band_edges%IDBG*
evolt
2762 WRITE (u, print_format) scf_gw_soc,
' direct band gap (eV):', band_edges%DBG*
evolt
2765 CALL timestop(handle)
2767 END SUBROUTINE write_band_edges
2779 SUBROUTINE write_dos_pdos(DOS, PDOS, bs_env, qs_env, scf_gw_soc, E_min, E_VBM)
2780 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos
2781 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
2784 CHARACTER(LEN=*) :: scf_gw_soc
2785 REAL(kind=
dp) :: e_min, e_vbm
2787 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_dos_pdos'
2789 CHARACTER(LEN=3),
DIMENSION(100) :: elements
2790 CHARACTER(LEN=default_string_length) :: atom_name, fname, output_string
2791 INTEGER :: handle, i_e, i_kind, iatom, iunit, n_a, &
2793 REAL(kind=
dp) :: energy
2796 CALL timeset(routinen, handle)
2798 WRITE (fname,
"(3A)")
"DOS_PDOS_", scf_gw_soc,
".out"
2801 nkind =
SIZE(pdos, 2)
2802 CALL get_qs_env(qs_env, particle_set=particle_set)
2804 IF (bs_env%para_env%is_source())
THEN
2806 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", file_action=
"WRITE")
2810 DO iatom = 1, bs_env%n_atom
2812 kind_number=i_kind, name=atom_name)
2813 elements(i_kind) = atom_name(1:3)
2816 WRITE (output_string,
"(A,I1,A)")
"(", n_a,
"A)"
2818 WRITE (iunit, trim(output_string))
"Energy-E_F (eV) DOS (1/eV) PDOS (1/eV) ", &
2819 " of atom type ", elements(1:nkind)
2821 WRITE (output_string,
"(A,I1,A)")
"(", n_a,
"F13.5)"
2825 energy = e_min + i_e*bs_env%energy_step_DOS - e_vbm
2826 WRITE (iunit, trim(output_string)) energy*
evolt, dos(i_e)/
evolt, pdos(i_e, :)/
evolt
2833 CALL timestop(handle)
2835 END SUBROUTINE write_dos_pdos
2843 PURE FUNCTION gaussian(energy, broadening)
2845 REAL(kind=
dp),
INTENT(IN) :: energy, broadening
2848 IF (abs(energy) < 5*broadening)
THEN
2849 gaussian = 1.0_dp/broadening/sqrt(
twopi)*exp(-0.5_dp*energy**2/broadening**2)
2863 SUBROUTINE compute_proj_mo_on_kind(proj_mo_on_kind, qs_env, cfm_mos, cfm_s)
2864 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind
2868 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_proj_mo_on_kind'
2870 INTEGER :: handle, i_atom, i_global, i_kind, i_row, &
2871 j_col, n_ao, n_mo, ncol_local, nkind, &
2873 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf, kind_of
2874 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2876 TYPE(
cp_cfm_type) :: cfm_proj, cfm_s_i_kind, cfm_work
2879 CALL timeset(routinen, handle)
2881 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, nkind=nkind)
2886 nrow_local=nrow_local, &
2887 ncol_local=ncol_local, &
2888 row_indices=row_indices, &
2889 col_indices=col_indices)
2891 n_ao = qs_env%bs_env%n_ao
2893 ALLOCATE (atom_from_bf(n_ao))
2896 proj_mo_on_kind(:, :) = 0.0_dp
2904 DO i_kind = 1, nkind
2909 DO j_col = 1, ncol_local
2910 DO i_row = 1, nrow_local
2912 i_global = row_indices(i_row)
2914 IF (i_global <= n_ao)
THEN
2915 i_atom = atom_from_bf(i_global)
2916 ELSE IF (i_global <= 2*n_ao)
THEN
2917 i_atom = atom_from_bf(i_global - n_ao)
2919 cpabort(
"Wrong indices.")
2922 IF (i_kind /= kind_of(i_atom))
THEN
2923 cfm_s_i_kind%local_data(i_row, j_col) =
z_zero
2930 cfm_s_i_kind, cfm_mos,
z_zero, cfm_work)
2932 cfm_mos, cfm_work,
z_zero, cfm_proj)
2947 CALL timestop(handle)
2949 END SUBROUTINE compute_proj_mo_on_kind
2961 SUBROUTINE cfm_ikp_from_cfm_spinor_gamma(cfm_spinor_ikp, cfm_spinor_Gamma, fm_struct_non_spinor, &
2962 ikp, qs_env, kpoints, basis_type)
2963 TYPE(
cp_cfm_type) :: cfm_spinor_ikp, cfm_spinor_gamma
2968 CHARACTER(LEN=*) :: basis_type
2970 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cfm_ikp_from_cfm_spinor_Gamma'
2972 INTEGER :: handle, i_block, i_offset, j_block, &
2974 TYPE(
cp_cfm_type) :: cfm_non_spinor_gamma, cfm_non_spinor_ikp
2975 TYPE(
cp_fm_type) :: fm_non_spinor_gamma_im, &
2976 fm_non_spinor_gamma_re
2978 CALL timeset(routinen, handle)
2980 CALL cp_cfm_create(cfm_non_spinor_gamma, fm_struct_non_spinor)
2981 CALL cp_cfm_create(cfm_non_spinor_ikp, fm_struct_non_spinor)
2982 CALL cp_fm_create(fm_non_spinor_gamma_re, fm_struct_non_spinor)
2983 CALL cp_fm_create(fm_non_spinor_gamma_im, fm_struct_non_spinor)
2991 i_offset = i_block*n_ao + 1
2992 j_offset = j_block*n_ao + 1
2993 CALL get_cfm_submat(cfm_non_spinor_gamma, cfm_spinor_gamma, i_offset, j_offset)
2994 CALL cp_cfm_to_fm(cfm_non_spinor_gamma, fm_non_spinor_gamma_re, fm_non_spinor_gamma_im)
2998 ikp, qs_env, kpoints, basis_type)
2999 CALL add_cfm_submat(cfm_spinor_ikp, cfm_non_spinor_ikp, i_offset, j_offset)
3003 ikp, qs_env, kpoints, basis_type)
3014 CALL timestop(handle)
3016 END SUBROUTINE cfm_ikp_from_cfm_spinor_gamma
3033 CHARACTER(LEN=*) :: basis_type
3035 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cfm_ikp_from_fm_Gamma'
3038 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf
3042 CALL timeset(routinen, handle)
3044 cpassert(basis_type ==
"ORB" .OR. basis_type ==
"RI_AUX")
3045 ALLOCATE (atom_from_bf(fm_gamma%matrix_struct%nrow_global))
3047 NULLIFY (cell, particle_set)
3048 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
3049 CALL fm_gamma_to_kp(cfm_ikp, fm_gamma, cell, particle_set, atom_from_bf, &
3050 kpoints%index_to_cell, kpoints%xkp(:, ikp))
3052 CALL timestop(handle)
3068 cfm_W_ikp_freq_j, ikp, kpoints, basis_type, wkp_ext)
3073 INTEGER,
INTENT(IN) :: ikp
3075 CHARACTER(LEN=*) :: basis_type
3076 REAL(kind=
dp),
OPTIONAL :: wkp_ext
3078 CHARACTER(LEN=*),
PARAMETER :: routinen =
'MIC_contribution_from_ikp'
3080 INTEGER :: handle, i_bf, iatom, iatom_old, irow, &
3081 j_bf, jatom, jatom_old, jcol, n_bf, &
3082 ncol_local, nrow_local, num_cells
3083 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf_index
3084 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
3085 INTEGER,
DIMENSION(:, :),
POINTER :: index_to_cell
3086 REAL(kind=
dp) :: contribution, weight_im, weight_re, &
3088 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
3089 REAL(kind=
dp),
DIMENSION(:),
POINTER :: wkp
3090 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xkp
3094 CALL timeset(routinen, handle)
3097 IF (basis_type ==
"ORB")
THEN
3098 n_bf = qs_env%bs_env%n_ao
3099 ELSE IF (basis_type ==
"RI_AUX")
THEN
3100 n_bf = qs_env%bs_env%n_RI
3102 cpabort(
"Only ORB and RI_AUX basis implemented.")
3105 ALLOCATE (atom_from_bf_index(n_bf))
3108 NULLIFY (cell, particle_set)
3109 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
3113 nrow_local=nrow_local, &
3114 ncol_local=ncol_local, &
3115 row_indices=row_indices, &
3116 col_indices=col_indices)
3119 index_to_cell => kpoints%index_to_cell
3120 num_cells =
SIZE(index_to_cell, 2)
3125 DO jcol = 1, ncol_local
3126 DO irow = 1, nrow_local
3128 i_bf = row_indices(irow)
3129 j_bf = col_indices(jcol)
3131 iatom = atom_from_bf_index(i_bf)
3132 jatom = atom_from_bf_index(j_bf)
3134 IF (
PRESENT(wkp_ext))
THEN
3135 wkp_of_ikp = wkp_ext
3137 SELECT CASE (bs_env%l_RI(i_bf) + bs_env%l_RI(j_bf))
3140 wkp_of_ikp = wkp(ikp)
3143 wkp_of_ikp = bs_env%wkp_s_p(ikp)
3146 wkp_of_ikp = bs_env%wkp_no_extra(ikp)
3150 IF (iatom /= iatom_old .OR. jatom /= jatom_old)
THEN
3153 num_cells, iatom, jatom, xkp(1:3, ikp), wkp_of_ikp, &
3154 cell, index_to_cell, hmat, particle_set)
3161 contribution = weight_re*real(cfm_w_ikp_freq_j%local_data(irow, jcol)) + &
3162 weight_im*aimag(cfm_w_ikp_freq_j%local_data(irow, jcol))
3164 fm_w_mic_freq_j%local_data(irow, jcol) = fm_w_mic_freq_j%local_data(irow, jcol) &
3170 CALL timestop(handle)
3183 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xkp
3184 INTEGER :: ikp_start, ikp_end
3185 INTEGER,
DIMENSION(3) :: grid
3187 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_xkp'
3189 INTEGER :: handle, i, ix, iy, iz
3191 CALL timeset(routinen, handle)
3198 IF (i > ikp_end) cycle
3200 xkp(1, i) = real(2*ix - grid(1) - 1, kind=
dp)/(2._dp*real(grid(1), kind=
dp))
3201 xkp(2, i) = real(2*iy - grid(2) - 1, kind=
dp)/(2._dp*real(grid(2), kind=
dp))
3202 xkp(3, i) = real(2*iz - grid(3) - 1, kind=
dp)/(2._dp*real(grid(3), kind=
dp))
3209 CALL timestop(handle)
3223 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_init_cell_index_simple'
3225 INTEGER :: handle, nimages
3230 CALL timeset(routinen, handle)
3232 NULLIFY (para_env, sab_orb)
3233 CALL get_qs_env(qs_env=qs_env, para_env=para_env, sab_orb=sab_orb)
3236 CALL timestop(handle)
3245 SUBROUTINE soc(qs_env, bs_env)
3249 CHARACTER(LEN=*),
PARAMETER :: routinen =
'soc'
3253 CALL timeset(routinen, handle)
3261 SELECT CASE (bs_env%gw_implementation)
3265 CALL h_ks_spinor_gamma(bs_env)
3270 CALL h_ks_spinor_kp(qs_env, bs_env)
3274 CALL timestop(handle)
3282 SUBROUTINE h_ks_spinor_gamma(bs_env)
3286 CHARACTER(LEN=*),
PARAMETER :: routinen =
'H_KS_spinor_Gamma'
3288 INTEGER :: handle, nao, s
3291 CALL timeset(routinen, handle)
3295 ALLOCATE (bs_env%cfm_SOC_spinor_ao(1))
3296 CALL create_cfm_double(bs_env%cfm_SOC_spinor_ao(1), fm_orig=bs_env%fm_ks_Gamma(1))
3299 str => bs_env%fm_ks_Gamma(1)%matrix_struct
3307 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(1, 1)%matrix, &
3308 str, 1, s,
z_one, .false.)
3310 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(1, 1)%matrix, &
3311 str, s, 1,
z_one, .false.)
3315 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(2, 1)%matrix, &
3316 str, 1, s,
gaussi, .false.)
3318 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(2, 1)%matrix, &
3319 str, s, 1, -
gaussi, .false.)
3323 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(3, 1)%matrix, &
3324 str, 1, 1,
z_one, .false.)
3326 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(3, 1)%matrix, &
3327 str, s, s, -
z_one, .false.)
3329 CALL timestop(handle)
3331 END SUBROUTINE h_ks_spinor_gamma
3338 SUBROUTINE h_ks_spinor_kp(qs_env, bs_env)
3342 CHARACTER(LEN=*),
PARAMETER :: routinen =
'H_KS_spinor_kp'
3344 INTEGER :: handle, i_dim, ikp, n_spin, &
3346 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index_scf
3347 REAL(kind=
dp),
DIMENSION(3) :: xkp
3354 CALL timeset(routinen, handle)
3356 nkp_bs_and_dos = bs_env%nkp_bs_and_DOS
3357 n_spin = bs_env%n_spin
3359 str => bs_env%cfm_ks_kp(1, 1)%matrix_struct
3361 CALL cp_cfm_create(cfm_v_soc_xyz_ikp, bs_env%cfm_work_mo%matrix_struct)
3363 CALL alloc_cfm_double_array_1d(bs_env%cfm_SOC_spinor_ao, bs_env%cfm_ks_kp(1, 1), nkp_bs_and_dos)
3368 CALL get_kpoint_info(kpoints_scf, sab_nl=sab_nl, cell_to_index=cell_to_index_scf)
3372 DO ikp = 1, nkp_bs_and_dos
3374 xkp(1:3) = bs_env%kpoints_DOS%xkp(1:3, ikp)
3378 CALL rsmat_to_kp(bs_env%mat_V_SOC_xyz, i_dim, xkp, cell_to_index_scf, &
3379 sab_nl, bs_env, cfm_v_soc_xyz_ikp, imag_rs_mat=.true.)
3387 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, 1, s)
3388 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, s, 1)
3392 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, 1, s)
3394 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, s, 1)
3397 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, 1, 1)
3399 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, s, s)
3408 CALL timestop(handle)
3410 END SUBROUTINE h_ks_spinor_kp
3418 SUBROUTINE alloc_cfm_double_array_1d(cfm_array, cfm_template, n)
3419 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: cfm_array
3423 CHARACTER(LEN=*),
PARAMETER :: routinen =
'alloc_cfm_double_array_1d'
3425 INTEGER :: handle, i
3427 CALL timeset(routinen, handle)
3429 ALLOCATE (cfm_array(n))
3435 CALL timestop(handle)
3437 END SUBROUTINE alloc_cfm_double_array_1d
3447 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_all_VBM_CBM_bandgaps'
3451 CALL timeset(routinen, handle)
3457 CALL check_qp_gap_sanity(bs_env)
3459 CALL check_scf_gw_level_ordering(bs_env)
3461 CALL timestop(handle)
3470 SUBROUTINE check_qp_gap_sanity(bs_env)
3474 CHARACTER(LEN=default_string_length) :: gw_label
3475 REAL(kind=
dp) :: gap, gap_scf
3477 gap = bs_env%band_edges_GW%IDBG
3478 gap_scf = bs_env%band_edges_scf%IDBG
3483 CALL cp_warn(__location__, &
3484 trim(gw_label)//
" band gap is negative ("// &
3485 trim(adjustl(
cp_to_string(gap*
evolt,
'(F12.3)')))//
" eV): the quasiparticle "// &
3486 "spectrum is inverted. Check numerical parameters.")
3488 CALL cp_warn(__location__, &
3489 trim(gw_label)//
" band gap is implausibly large ("// &
3490 trim(adjustl(
cp_to_string(gap*
evolt,
'(F12.3)')))//
" eV): the quasiparticle "// &
3491 "solve has likely diverged. Check numerical parameters.")
3494 END SUBROUTINE check_qp_gap_sanity
3505 SUBROUTINE check_scf_gw_level_ordering(bs_env)
3509 CHARACTER(LEN=*),
PARAMETER :: routinen =
'check_scf_gw_level_ordering'
3510 REAL(kind=
dp),
PARAMETER :: eps_degeneracy = 1.0e-05_dp
3512 CHARACTER(LEN=default_string_length) :: gw_label, level_gw, level_scf, &
3514 CHARACTER(LEN=max_line_length) :: msg
3515 INTEGER :: handle, homo, ispin, n_mo
3516 INTEGER,
DIMENSION(2) :: loc_gw, loc_scf
3518 CALL timeset(routinen, handle)
3523 DO ispin = 1, bs_env%n_spin
3525 homo = bs_env%n_occ(ispin)
3527 IF (bs_env%n_spin == 2)
THEN
3528 WRITE (spin_string,
'(A,I0,A)')
" (spin ", ispin,
")"
3534 loc_scf(:) = maxloc(bs_env%eigenval_scf(1:homo, :, ispin))
3535 loc_gw(:) = maxloc(bs_env%eigenval_GW(1:homo, :, ispin))
3538 IF (bs_env%eigenval_scf(loc_scf(1), loc_scf(2), ispin) - &
3539 bs_env%eigenval_scf(loc_gw(1), loc_gw(2), ispin) > eps_degeneracy)
THEN
3541 CALL level_string(level_scf, loc_scf, bs_env)
3542 CALL level_string(level_gw, loc_gw, bs_env)
3544 msg = trim(gw_label)//
" reorders the occupied levels"//trim(spin_string)// &
3545 ": the SCF valence band maximum (SCF HOMO) is "//trim(level_scf)// &
3546 ", whereas the "//trim(gw_label)//
" valence band maximum ("// &
3547 trim(gw_label)//
" HOMO) is "//trim(level_gw)//
". The SCF and "// &
3548 trim(gw_label)//
" band edges printed below therefore belong to different "// &
3549 "orbitals; see the eigenvalues in the file bandstructure_SCF_and_G0W0."
3555 loc_scf(:) = minloc(bs_env%eigenval_scf(homo + 1:n_mo, :, ispin))
3556 loc_gw(:) = minloc(bs_env%eigenval_GW(homo + 1:n_mo, :, ispin))
3557 loc_scf(1) = loc_scf(1) + homo
3558 loc_gw(1) = loc_gw(1) + homo
3560 IF (bs_env%eigenval_scf(loc_gw(1), loc_gw(2), ispin) - &
3561 bs_env%eigenval_scf(loc_scf(1), loc_scf(2), ispin) > eps_degeneracy)
THEN
3563 CALL level_string(level_scf, loc_scf, bs_env)
3564 CALL level_string(level_gw, loc_gw, bs_env)
3566 msg = trim(gw_label)//
" reorders the empty levels"//trim(spin_string)// &
3567 ": the SCF conduction band minimum (SCF LUMO) is "//trim(level_scf)// &
3568 ", whereas the "//trim(gw_label)//
" conduction band minimum ("// &
3569 trim(gw_label)//
" LUMO) is "//trim(level_gw)//
". The SCF and "// &
3570 trim(gw_label)//
" band edges printed below therefore belong to different "// &
3571 "orbitals; see the eigenvalues in the file bandstructure_SCF_and_G0W0."
3578 CALL timestop(handle)
3580 END SUBROUTINE check_scf_gw_level_ordering
3588 SUBROUTINE level_string(string, loc, bs_env)
3590 CHARACTER(LEN=*),
INTENT(OUT) :: string
3591 INTEGER,
DIMENSION(2),
INTENT(IN) :: loc
3594 IF (bs_env%nkp_bs_and_DOS > 1)
THEN
3595 WRITE (string,
'(A,I0,A,I0)')
"level ", loc(1),
" at k-point ", loc(2)
3597 WRITE (string,
'(A,I0)')
"level ", loc(1)
3600 END SUBROUTINE level_string
3610 REAL(kind=
dp),
DIMENSION(:, :, :) :: ev
3613 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_VBM_CBM_bandgaps'
3615 INTEGER :: handle, homo, homo_1, homo_2, ikp, &
3616 ispin, lumo, lumo_1, lumo_2, n_mo
3617 REAL(kind=
dp) :: e_dbg_at_ikp
3619 CALL timeset(routinen, handle)
3623 band_edges%DBG = 1000.0_dp
3625 SELECT CASE (bs_env%n_spin)
3627 homo = bs_env%n_occ(1)
3629 band_edges%VBM = maxval(ev(1:homo, :, 1))
3630 band_edges%CBM = minval(ev(homo + 1:n_mo, :, 1))
3632 homo_1 = bs_env%n_occ(1)
3634 homo_2 = bs_env%n_occ(2)
3636 band_edges%VBM = max(maxval(ev(1:homo_1, :, 1)), maxval(ev(1:homo_2, :, 2)))
3637 band_edges%CBM = min(minval(ev(homo_1 + 1:n_mo, :, 1)), minval(ev(homo_2 + 1:n_mo, :, 2)))
3639 cpabort(
"Error with number of spins.")
3642 band_edges%IDBG = band_edges%CBM - band_edges%VBM
3644 DO ispin = 1, bs_env%n_spin
3646 homo = bs_env%n_occ(ispin)
3648 DO ikp = 1, bs_env%nkp_bs_and_DOS
3650 e_dbg_at_ikp = -maxval(ev(1:homo, ikp, ispin)) + minval(ev(homo + 1:n_mo, ikp, ispin))
3652 IF (e_dbg_at_ikp < band_edges%DBG) band_edges%DBG = e_dbg_at_ikp
3657 SELECT CASE (bs_env%n_spin)
3659 CALL get_fermi_level_1c(bs_env, ev(:, :, 1), &
3660 REAL(bs_env%n_electron(1), kind=
dp), &
3661 bs_env%spin_degeneracy, band_edges%VBM, band_edges%CBM, band_edges%E_fermi)
3663 CALL get_fermi_level_2c(bs_env, ev(:, :, 1:2), &
3664 REAL(bs_env%n_electron(1) + bs_env%n_electron(2), kind=
dp), &
3665 band_edges%VBM, band_edges%CBM, band_edges%E_fermi)
3668 CALL timestop(handle)
3694 SUBROUTINE get_fermi_level_1c(bs_env, eigenval, n_el, maxocc, VBM, CBM, e_fermi)
3696 REAL(kind=
dp),
DIMENSION(:, :) :: eigenval
3697 REAL(kind=
dp) :: n_el, maxocc, vbm, cbm, e_fermi
3699 REAL(kind=
dp),
PARAMETER :: gap_smear_ratio = 20.0_dp
3701 REAL(kind=
dp) :: kts
3702 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: f_occ
3704 IF (bs_env%do_smear .AND. .NOT. (cbm > vbm .AND. &
3705 cbm - vbm > gap_smear_ratio*bs_env%smear_width))
THEN
3706 ALLOCATE (f_occ(
SIZE(eigenval, 1),
SIZE(eigenval, 2)))
3707 CALL smearkp(f_occ, e_fermi, kts, eigenval, n_el, &
3708 bs_env%kpoints_DOS%wkp(1:
SIZE(eigenval, 2)), &
3709 bs_env%smear_width, maxocc, bs_env%smear_method)
3715 END SUBROUTINE get_fermi_level_1c
3729 SUBROUTINE get_fermi_level_2c(bs_env, eigenval, n_el, VBM, CBM, e_fermi)
3731 REAL(kind=
dp),
DIMENSION(:, :, :) :: eigenval
3732 REAL(kind=
dp) :: n_el, vbm, cbm, e_fermi
3734 REAL(kind=
dp),
PARAMETER :: gap_smear_ratio = 20.0_dp
3736 REAL(kind=
dp) :: kts
3737 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: f_occ
3739 IF (bs_env%do_smear .AND. .NOT. (cbm > vbm .AND. &
3740 cbm - vbm > gap_smear_ratio*bs_env%smear_width))
THEN
3741 ALLOCATE (f_occ(
SIZE(eigenval, 1),
SIZE(eigenval, 2), 2))
3742 CALL smearkp2(f_occ, e_fermi, kts, eigenval, n_el, &
3743 bs_env%kpoints_DOS%wkp(1:
SIZE(eigenval, 2)), &
3744 bs_env%smear_width, bs_env%smear_method)
3750 END SUBROUTINE get_fermi_level_2c
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
static GRID_HOST_DEVICE int idx(const orbital a)
Return coset index of given orbital angular momentum.
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Main routines for GW + Bethe-Salpeter for computing electronic excitations: a GW path prepares the BS...
subroutine, public bse_fulldiag_memory_check(bse_env, window, homo, para_env, unit_nr)
Early memory check for the full diagonalization, before any GW work: the window on the DFT axis gives...
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 bse_window_from_dft(eigenval_scf, n_mo, homo, cutoff_occ, cutoff_empty, window, warn)
The active MO window on the DFT axis: one absolute MO range for every spin; when the spin windows dif...
Handles all functions related to the CELL.
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
methods related to the blacs parallel environment
Basic linear algebra operations for complex full matrices.
various cholesky decomposition related routines
subroutine, public cp_cfm_cholesky_decompose(matrix, n, info_out)
Used to replace a symmetric positive definite matrix M with its Cholesky decomposition U: M = U^T * U...
used for collecting diagonalization schemes available for cp_cfm_type
subroutine, public cp_cfm_geeig_canon(amatrix, bmatrix, eigenvectors, eigenvalues, work, epseig, nmo_retained)
General Eigenvalue Problem AX = BXE Use canonical orthogonalization.
subroutine, public cp_cfm_heevd(matrix, eigenvectors, eigenvalues)
Perform a diagonalisation of a complex matrix.
subroutine, public cp_cfm_geeig(amatrix, bmatrix, eigenvectors, eigenvalues, work, lowest_subset)
General Eigenvalue Problem AX = BXE Single option version: Cholesky decomposition of B.
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_fm_to_cfm(msourcer, msourcei, mtarget)
Construct a complex full matrix by taking its real and imaginary parts from two separate real-value f...
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
subroutine, public cp_cfm_set_all(matrix, alpha, beta)
Set all elements of the full matrix to alpha. Besides, set all diagonal matrix elements to beta (if g...
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_deallocate_matrix(matrix)
...
subroutine, public dbcsr_desymmetrize(matrix_a, matrix_b)
...
subroutine, public dbcsr_set(matrix, alpha)
...
Routines that link DBCSR and CP2K concepts together.
subroutine, public cp_dbcsr_alloc_block_from_nbl(matrix, sab_orb, desymmetrize)
allocate the blocks of a dbcsr based on the neighbor list
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm, plan, check_plan)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
Utility routines to open and close files.
subroutine, public open_file(file_name, unit_number, file_status, file_form, file_action, file_position, file_pad, file_access, debug)
Opens a file and returns its logical unit number.
subroutine, public close_file(unit_number, file_status)
Closes an open file given by its logical unit number.
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
subroutine, public cp_fm_geeig_canon(amatrix, bmatrix, eigenvectors, eigenvalues, work, epseig, nmo_retained)
General Eigenvalue Problem AX = BXE Use canonical diagonalization : U*s**(-1/2).
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_get_diag(matrix, diag, n_active)
returns the diagonal elements of a fm
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
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
Utility routines to read data from files. Kept as close as possible to the old parser because.
elemental subroutine, public read_float_object(string, object, error_message)
Returns a floating point number read from a string including fraction like z1/z2.
Add the DFT+U contribution to the Hamiltonian matrix.
subroutine, public lowdin_kp_prepare(kp, orbitals, use_real_wfn, smat)
Prepare selected Lowdin projectors and their reusable product workspace.
subroutine, public lowdin_kp_apply(kp, v, rmat, cmat)
Add B diag(v) B**H before any solver, DIIS residual, or history storage uses H(k).
Defines the basic variable types.
integer, parameter, public max_line_length
integer, parameter, public dp
integer, parameter, public default_string_length
Implements simple k-space/R-space transformations and Gamma-point MIC reconstruction.
subroutine, public fm_gamma_to_kp(cfm_kp, fm_gamma, cell, particle_set, atom_from_bf, index_to_cell, xkp)
Reconstruct a complex k-point matrix from a real Gamma matrix using one MIC phase....
Routines needed for kpoint calculation.
subroutine, public rskp_transform(rmatrix, cmatrix, rsmat, ispin, xkp, cell_to_index, sab_nl, is_complex, rs_sign)
Transformation of real space matrices to a kpoint.
subroutine, public kpoint_init_cell_index(kpoint, sab_nl, para_env, nimages)
Generates the mapping of cell indices and linear RS index CELL (0,0,0) is always mapped to index 1.
Types and basic routines needed for a kpoint calculation.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym, inversion_symmetry_only, symmetry_backend, symmetry_reduction_method, gamma_centered, lattice_fft)
Retrieve information from a kpoint environment.
subroutine, public kpoint_create(kpoint)
Create a kpoint environment.
Machine interface based on Fortran 2003 and POSIX.
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public gaussi
real(kind=dp), parameter, public twopi
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
Common selection and union operations for contiguous molecular-orbital windows.
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
real(kind=dp), parameter, public angstrom
real(kind=dp), parameter, public max_qp_gap
real(kind=dp), parameter, public eps_qp_gap
subroutine, public eval_bandstructure_properties(qs_env, bs_env)
...
subroutine, public rsmat_to_kp(mat_rs, ispin, xkp, cell_to_index_scf, sab_nl, bs_env, cfm_kp, imag_rs_mat)
...
subroutine, public kpoint_init_cell_index_simple(kpoints, qs_env)
...
subroutine, public allocate_gw_eigenvalues(bs_env)
Allocate the arrays holding the GW quasiparticle energies.
character(len=default_string_length) function, public gw_flavour_label(bs_env)
Name of the GW flavour that was requested, for printing.
subroutine, public cfm_ikp_from_fm_gamma(cfm_ikp, fm_gamma, ikp, qs_env, kpoints, basis_type)
Reconstruct a k-point operator from a real Gamma matrix using one MIC phase.
subroutine, public get_all_vbm_cbm_bandgaps(bs_env)
...
subroutine, public soc(qs_env, bs_env)
...
subroutine, public mic_contribution_from_ikp(bs_env, qs_env, fm_w_mic_freq_j, cfm_w_ikp_freq_j, ikp, kpoints, basis_type, wkp_ext)
...
subroutine, public compute_xkp(xkp, ikp_start, ikp_end, grid)
...
subroutine, public create_and_init_bs_env(qs_env, bs_env, post_scf_bandstructure_section)
...
subroutine, public get_vbm_cbm_bandgaps(band_edges, ev, bs_env)
...
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Calculate the plane wave density by collocating the primitive Gaussian functions (pgf).
subroutine, public calculate_rho_elec(matrix_p, matrix_p_kp, rho, rho_gspace, total_rho, ks_env, soft_valid, compute_tau, compute_grad, basis_type, der_type, idir, task_list_external, pw_env_external)
computes the density corresponding to a given density matrix on the grid
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Definition and initialisation of the mo data type.
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count, cmo_coeff)
Get the components of a MO set data structure.
Define the neighbor list data types and the corresponding functionality.
Utility routines for GW with imaginary time.
subroutine, public compute_weight_re_im(weight_re, weight_im, num_cells, iatom, jatom, xkp, wkp_w, cell, index_to_cell, hmat, particle_set)
...
subroutine, public get_atom_index_from_basis_function_index(qs_env, atom_from_basis_index, basis_size, basis_type, first_bf_from_atom)
...
parameters that control an scf iteration
Unified smearing module supporting four methods: smear_fermi_dirac — Fermi-Dirac distribution smear_g...
subroutine, public smearkp(f, mu, kts, e, nel, wk, sigma, maxocc, method)
Bisection search for mu given a target electron count (k-point case, single spin channel or spin-dege...
subroutine, public smearkp2(f, mu, kts, e, nel, wk, sigma, method)
Bisection search for mu (k-point, spin-polarised with a shared chemical potential across both spin ch...
subroutine, public v_soc_xyz_from_pseudopotential(qs_env, mat_v_soc_xyz)
V^SOC_µν^(α),R = ħ/2 < ϕ_µ cell O | sum_ℓ ΔV_ℓ^SO(r,r') L^(α) | ϕ_ν cell R>, α = x,...
subroutine, public remove_soc_outside_energy_window_mo(cfm_ks_spinor, e_win_cbm, temp_smear, eigenval, e_fermi)
...
subroutine, public create_cfm_double(cfm_double, fm_orig, cfm_orig)
...
subroutine, public add_dbcsr_submat(cfm_mat_target, mat_source, fm_struct_source, nstart_row, nstart_col, factor, add_also_herm_conj)
...
subroutine, public add_cfm_submat(cfm_mat_target, cfm_mat_source, nstart_row, nstart_col, factor)
...
subroutine, public get_cfm_submat(cfm_mat_target, cfm_mat_source, nstart_row, nstart_col)
...
subroutine, public cfm_add_on_diag(cfm, alpha)
...
Utilities for string manipulations.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
Provides all information about an atomic kind.
Settings of the &BSE section (read_bse_section, re-read before every BSE run, normalised in place by ...
Type defining parameters related to the simulation cell.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
Represent a complex full matrix.
keeps the information about the structure of a full matrix
Keeps information about a specific k-point.
Contains information about kpoints.
stores all the informations relevant to an mpi environment
contained for different pw related things
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...