37 dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, dbcsr_type_symmetric
110#include "base/base_uses.f90"
121 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'post_scf_bandstructure_utils'
136 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_and_init_bs_env'
140 CALL timeset(routinen, handle)
144 CALL print_header(bs_env)
146 CALL read_bandstructure_input_parameters(bs_env, post_scf_bandstructure_section, qs_env)
148 CALL get_parameters_from_qs_env(qs_env, bs_env)
150 CALL set_heuristic_parameters(bs_env)
152 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
155 CALL setup_kpoints_dos_large_cell_gamma(qs_env, bs_env, bs_env%kpoints_DOS)
157 CALL allocate_and_fill_fm_ks_fm_s(qs_env, bs_env)
159 CALL diagonalize_ks_matrix(bs_env)
161 CALL check_positive_definite_overlap_mat(bs_env, qs_env)
165 CALL setup_kpoints_scf_desymm(qs_env, bs_env, bs_env%kpoints_scf_desymm, .true.)
166 CALL setup_kpoints_scf_desymm(qs_env, bs_env, bs_env%kpoints_scf_desymm_2, .false.)
168 CALL setup_kpoints_dos_small_cell_full_kp(bs_env, bs_env%kpoints_DOS)
170 CALL allocate_and_fill_fm_ks_fm_s(qs_env, bs_env)
172 CALL compute_cfm_mo_coeff_kp_and_eigenval_scf_kp(qs_env, bs_env)
176 CALL timestop(handle)
186 SUBROUTINE read_bandstructure_input_parameters(bs_env, bs_sec, qs_env)
191 CHARACTER(LEN=*),
PARAMETER :: routinen =
'read_bandstructure_input_parameters'
193 CHARACTER(LEN=default_string_length) :: ustr
194 CHARACTER(LEN=default_string_length), &
195 DIMENSION(:),
POINTER :: string_ptr
196 CHARACTER(LEN=max_line_length) :: error_msg
197 INTEGER :: handle, i, ikp
198 REAL(kind=
dp),
DIMENSION(3) :: kpptr
199 REAL(kind=
dp),
DIMENSION(3, 3) :: cart_hmat
202 kp_bs_sec, ldos_sec, soc_sec
204 CALL timeset(routinen, handle)
207 cart_hmat(:, :) = cell%hmat(:, :)
208 IF (cell%input_cell_canonicalized) cart_hmat(:, :) = cell%input_hmat(:, :)
223 NULLIFY (dos_pdos_sec)
246 NULLIFY (floquet_sec)
259 CALL section_vals_val_get(floquet_sec,
"QUASI_ENERGIES_FILE_NAME", c_val=bs_env%floquet_qe_file)
262 ALLOCATE (bs_env%xkp_special(3, bs_env%input_kp_bs_n_sp_pts))
263 DO ikp = 1, bs_env%input_kp_bs_n_sp_pts
265 cpassert(
SIZE(string_ptr(:), 1) == 4)
268 IF (len_trim(error_msg) > 0) cpabort(trim(error_msg))
272 bs_env%xkp_special(1:3, ikp) = kpptr(1:3)
273 CASE (
"CART_ANGSTROM")
274 bs_env%xkp_special(1:3, ikp) = (kpptr(1)*cart_hmat(1, 1:3) + &
275 kpptr(2)*cart_hmat(2, 1:3) + &
278 bs_env%xkp_special(1:3, ikp) = (kpptr(1)*cart_hmat(1, 1:3) + &
279 kpptr(2)*cart_hmat(2, 1:3) + &
280 kpptr(3)*cart_hmat(3, 1:3))/
twopi
282 cpabort(
"Unknown unit <"//trim(ustr)//
"> specified for k-point definition")
286 CALL timestop(handle)
288 END SUBROUTINE read_bandstructure_input_parameters
294 SUBROUTINE print_header(bs_env)
298 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_header'
302 CALL timeset(routinen, handle)
309 WRITE (u,
'(T2,A)')
' '
310 WRITE (u,
'(T2,A)') repeat(
'-', 79)
311 WRITE (u,
'(T2,A,A78)')
'-',
'-'
312 WRITE (u,
'(T2,A,A51,A27)')
'-',
'BANDSTRUCTURE CALCULATION',
'-'
313 WRITE (u,
'(T2,A,A78)')
'-',
'-'
314 WRITE (u,
'(T2,A)') repeat(
'-', 79)
315 WRITE (u,
'(T2,A)')
' '
318 CALL timestop(handle)
320 END SUBROUTINE print_header
328 SUBROUTINE setup_kpoints_dos_large_cell_gamma(qs_env, bs_env, kpoints)
334 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_DOS_large_cell_Gamma'
336 INTEGER :: handle, i_dim, i_kp_in_line, &
337 i_special_kp, ikk, n_kp_in_line, &
338 n_special_kp, nkp, nkp_only_bs, &
340 INTEGER,
DIMENSION(3) :: nkp_grid, periodic
342 CALL timeset(routinen, handle)
348 kpoints%kp_scheme =
"GENERAL"
350 n_special_kp = bs_env%input_kp_bs_n_sp_pts
351 n_kp_in_line = bs_env%input_kp_bs_npoints
353 periodic(1:3) = bs_env%periodic(1:3)
357 cpassert(periodic(i_dim) == 0 .OR. periodic(i_dim) == 1)
359 IF (bs_env%nkp_grid_DOS_input(i_dim) < 0)
THEN
360 IF (periodic(i_dim) == 1) nkp_grid(i_dim) = 2
361 IF (periodic(i_dim) == 0) nkp_grid(i_dim) = 1
363 nkp_grid(i_dim) = bs_env%nkp_grid_DOS_input(i_dim)
369 IF (nkp_grid(1) > 1)
THEN
370 nkp_only_dos = (nkp_grid(1) + 1)/2*nkp_grid(2)*nkp_grid(3)
371 ELSE IF (nkp_grid(2) > 1)
THEN
372 nkp_only_dos = nkp_grid(1)*(nkp_grid(2) + 1)/2*nkp_grid(3)
373 ELSE IF (nkp_grid(3) > 1)
THEN
374 nkp_only_dos = nkp_grid(1)*nkp_grid(2)*(nkp_grid(3) + 1)/2
381 IF (n_special_kp > 0)
THEN
382 nkp_only_bs = n_kp_in_line*(n_special_kp - 1) + 1
387 nkp = nkp_only_dos + nkp_only_bs
389 kpoints%nkp_grid(1:3) = nkp_grid(1:3)
392 bs_env%nkp_bs_and_DOS = nkp
393 bs_env%nkp_only_bs = nkp_only_bs
394 bs_env%nkp_only_DOS = nkp_only_dos
396 ALLOCATE (kpoints%xkp(3, nkp), kpoints%wkp(nkp))
397 kpoints%wkp(1:nkp_only_dos) = 1.0_dp/real(nkp_only_dos, kind=
dp)
399 CALL compute_xkp(kpoints%xkp, 1, nkp_only_dos, nkp_grid)
401 IF (n_special_kp > 0)
THEN
402 kpoints%xkp(1:3, nkp_only_dos + 1) = bs_env%xkp_special(1:3, 1)
403 ikk = nkp_only_dos + 1
404 DO i_special_kp = 2, n_special_kp
405 DO i_kp_in_line = 1, n_kp_in_line
407 kpoints%xkp(1:3, ikk) = bs_env%xkp_special(1:3, i_special_kp - 1) + &
408 REAL(i_kp_in_line, kind=
dp)/real(n_kp_in_line, kind=
dp)* &
409 (bs_env%xkp_special(1:3, i_special_kp) - &
410 bs_env%xkp_special(1:3, i_special_kp - 1))
411 kpoints%wkp(ikk) = 0.0_dp
421 IF (nkp_only_bs > 0)
THEN
422 WRITE (u, fmt=
"(T2,1A,T77,I4)") &
423 "Number of special k-points for the bandstructure", n_special_kp
424 WRITE (u, fmt=
"(T2,1A,T77,I4)")
"Number of k-points for the bandstructure", nkp
425 WRITE (u, fmt=
"(T2,1A,T69,3I4)") &
426 "K-point mesh for the density of states (DOS)", nkp_grid(1:3)
428 WRITE (u, fmt=
"(T2,1A,T69,3I4)") &
429 "K-point mesh for the density of states (DOS) and the self-energy", nkp_grid(1:3)
433 CALL timestop(handle)
435 END SUBROUTINE setup_kpoints_dos_large_cell_gamma
444 SUBROUTINE setup_kpoints_scf_desymm(qs_env, bs_env, kpoints, do_print)
449 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_scf_desymm'
451 INTEGER :: handle, i_cell_x, i_dim, img, j_cell_y, &
452 k_cell_z, nimages, nkp, u
453 INTEGER,
DIMENSION(3) :: cell_grid, cixd, nkp_grid
458 CALL timeset(routinen, handle)
463 CALL get_qs_env(qs_env=qs_env, kpoints=kpoints_scf)
465 nkp_grid(1:3) = kpoints_scf%nkp_grid(1:3)
466 nkp = nkp_grid(1)*nkp_grid(2)*nkp_grid(3)
470 IF (bs_env%periodic(i_dim) == 1)
THEN
471 cpassert(nkp_grid(i_dim) >= 4)
475 kpoints%kp_scheme =
"GENERAL"
476 kpoints%nkp_grid(1:3) = nkp_grid(1:3)
478 bs_env%nkp_scf_desymm = nkp
480 ALLOCATE (kpoints%xkp(1:3, nkp))
483 ALLOCATE (kpoints%wkp(nkp))
484 kpoints%wkp(:) = 1.0_dp/real(nkp, kind=
dp)
488 cell_grid(1:3) = nkp_grid(1:3) -
modulo(nkp_grid(1:3) + 1, 2)
491 cixd(1:3) = cell_grid(1:3)/2
493 nimages = cell_grid(1)*cell_grid(2)*cell_grid(3)
495 bs_env%nimages_scf_desymm = nimages
496 bs_env%cell_grid_scf_desymm(1:3) = cell_grid(1:3)
498 IF (
ASSOCIATED(kpoints%index_to_cell))
DEALLOCATE (kpoints%index_to_cell)
499 IF (
ASSOCIATED(kpoints%cell_to_index))
DEALLOCATE (kpoints%cell_to_index)
501 ALLOCATE (kpoints%cell_to_index(-cixd(1):cixd(1), -cixd(2):cixd(2), -cixd(3):cixd(3)))
502 ALLOCATE (kpoints%index_to_cell(3, nimages))
505 DO i_cell_x = -cixd(1), cixd(1)
506 DO j_cell_y = -cixd(2), cixd(2)
507 DO k_cell_z = -cixd(3), cixd(3)
509 kpoints%cell_to_index(i_cell_x, j_cell_y, k_cell_z) = img
510 kpoints%index_to_cell(1:3, img) = [i_cell_x, j_cell_y, k_cell_z]
516 IF (u > 0 .AND. do_print)
THEN
517 WRITE (u, fmt=
"(T2,A,I49)") χΣ
"Number of cells for G, , W, ", nimages
520 CALL timestop(handle)
522 END SUBROUTINE setup_kpoints_scf_desymm
529 SUBROUTINE setup_kpoints_dos_small_cell_full_kp(bs_env, kpoints)
534 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_DOS_small_cell_full_kp'
536 INTEGER :: handle, i_kp_in_line, i_special_kp, ikk, &
537 n_kp_in_line, n_special_kp, nkp, &
538 nkp_only_bs, nkp_scf_desymm, u
540 CALL timeset(routinen, handle)
546 n_special_kp = bs_env%input_kp_bs_n_sp_pts
547 n_kp_in_line = bs_env%input_kp_bs_npoints
548 nkp_scf_desymm = bs_env%nkp_scf_desymm
552 IF (n_special_kp > 0)
THEN
553 nkp_only_bs = n_kp_in_line*(n_special_kp - 1) + 1
557 nkp = nkp_only_bs + nkp_scf_desymm
559 ALLOCATE (kpoints%xkp(3, nkp))
560 ALLOCATE (kpoints%wkp(nkp))
564 bs_env%nkp_bs_and_DOS = nkp
565 bs_env%nkp_only_bs = nkp_only_bs
566 bs_env%nkp_only_DOS = nkp_scf_desymm
568 kpoints%xkp(1:3, 1:nkp_scf_desymm) = bs_env%kpoints_scf_desymm%xkp(1:3, 1:nkp_scf_desymm)
569 kpoints%wkp(1:nkp_scf_desymm) = 1.0_dp/real(nkp_scf_desymm, kind=
dp)
571 IF (n_special_kp > 0)
THEN
572 kpoints%xkp(1:3, nkp_scf_desymm + 1) = bs_env%xkp_special(1:3, 1)
573 ikk = nkp_scf_desymm + 1
574 DO i_special_kp = 2, n_special_kp
575 DO i_kp_in_line = 1, n_kp_in_line
577 kpoints%xkp(1:3, ikk) = bs_env%xkp_special(1:3, i_special_kp - 1) + &
578 REAL(i_kp_in_line, kind=
dp)/real(n_kp_in_line, kind=
dp)* &
579 (bs_env%xkp_special(1:3, i_special_kp) - &
580 bs_env%xkp_special(1:3, i_special_kp - 1))
581 kpoints%wkp(ikk) = 0.0_dp
586 IF (
ASSOCIATED(kpoints%index_to_cell))
DEALLOCATE (kpoints%index_to_cell)
588 ALLOCATE (kpoints%index_to_cell(3, bs_env%nimages_scf_desymm))
589 kpoints%index_to_cell(:, :) = bs_env%kpoints_scf_desymm%index_to_cell(:, :)
594 WRITE (u, fmt=
"(T2,1A,T77,I4)")
"Number of special k-points for the bandstructure", &
596 WRITE (u, fmt=
"(T2,1A,T77,I4)")
"Number of k-points for the bandstructure", nkp
599 CALL timestop(handle)
601 END SUBROUTINE setup_kpoints_dos_small_cell_full_kp
608 SUBROUTINE compute_cfm_mo_coeff_kp_and_eigenval_scf_kp(qs_env, bs_env)
612 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_cfm_mo_coeff_kp_and_eigenval_scf_kp'
614 INTEGER :: handle, ikp, ispin, nkp_bs_and_dos
615 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index_scf
616 REAL(kind=
dp) :: cbm, vbm
617 REAL(kind=
dp),
DIMENSION(3) :: xkp
619 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks, matrix_s
624 CALL timeset(routinen, handle)
627 matrix_ks_kp=matrix_ks, &
628 matrix_s_kp=matrix_s, &
632 CALL get_kpoint_info(kpoints_scf, sab_nl=sab_nl, cell_to_index=cell_to_index_scf)
636 CALL cp_cfm_create(cfm_mos, bs_env%cfm_work_mo%matrix_struct)
639 nkp_bs_and_dos = bs_env%nkp_bs_and_DOS
641 ALLOCATE (bs_env%eigenval_G0W0(bs_env%n_ao, nkp_bs_and_dos, bs_env%n_spin))
642 ALLOCATE (bs_env%eigenval_HF(bs_env%n_ao, nkp_bs_and_dos, bs_env%n_spin))
643 ALLOCATE (bs_env%cfm_mo_coeff_kp(nkp_bs_and_dos, bs_env%n_spin))
644 ALLOCATE (bs_env%cfm_ks_kp(nkp_bs_and_dos, bs_env%n_spin))
645 ALLOCATE (bs_env%cfm_s_kp(nkp_bs_and_dos))
646 DO ikp = 1, nkp_bs_and_dos
647 DO ispin = 1, bs_env%n_spin
648 CALL cp_cfm_create(bs_env%cfm_mo_coeff_kp(ikp, ispin), bs_env%cfm_work_mo%matrix_struct)
649 CALL cp_cfm_create(bs_env%cfm_ks_kp(ikp, ispin), bs_env%cfm_work_mo%matrix_struct)
651 CALL cp_cfm_create(bs_env%cfm_s_kp(ikp), bs_env%cfm_work_mo%matrix_struct)
654 DO ispin = 1, bs_env%n_spin
655 DO ikp = 1, nkp_bs_and_dos
657 xkp(1:3) = bs_env%kpoints_DOS%xkp(1:3, ikp)
660 CALL rsmat_to_kp(matrix_ks, ispin, xkp, cell_to_index_scf, sab_nl, bs_env, cfm_ks)
663 CALL rsmat_to_kp(matrix_s, 1, xkp, cell_to_index_scf, sab_nl, bs_env, cfm_s)
673 bs_env%eigenval_scf(:, ikp, ispin), &
674 bs_env%cfm_work_mo, bs_env%eps_eigval_mat_s)
678 CALL cp_cfm_to_cfm(cfm_mos, bs_env%cfm_mo_coeff_kp(ikp, ispin))
682 vbm = maxval(bs_env%eigenval_scf(bs_env%n_occ(ispin), :, ispin))
683 cbm = minval(bs_env%eigenval_scf(bs_env%n_occ(ispin) + 1, :, ispin))
685 bs_env%e_fermi(ispin) = 0.5_dp*(vbm + cbm)
695 CALL timestop(handle)
697 END SUBROUTINE compute_cfm_mo_coeff_kp_and_eigenval_scf_kp
710 SUBROUTINE rsmat_to_kp(mat_rs, ispin, xkp, cell_to_index_scf, sab_nl, bs_env, cfm_kp, imag_rs_mat)
713 REAL(kind=
dp),
DIMENSION(3) :: xkp
714 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index_scf
719 LOGICAL,
OPTIONAL :: imag_rs_mat
721 CHARACTER(LEN=*),
PARAMETER :: routinen =
'rsmat_to_kp'
724 LOGICAL :: imag_rs_mat_private
725 TYPE(
dbcsr_type),
POINTER :: cmat, nsmat, rmat
727 CALL timeset(routinen, handle)
729 ALLOCATE (rmat, cmat, nsmat)
731 imag_rs_mat_private = .false.
732 IF (
PRESENT(imag_rs_mat)) imag_rs_mat_private = imag_rs_mat
734 IF (imag_rs_mat_private)
THEN
735 CALL dbcsr_create(rmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_antisymmetric)
736 CALL dbcsr_create(cmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
738 CALL dbcsr_create(rmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
739 CALL dbcsr_create(cmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_antisymmetric)
741 CALL dbcsr_create(nsmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_no_symmetry)
747 CALL rskp_transform(rmatrix=rmat, cmatrix=cmat, rsmat=mat_rs, ispin=ispin, &
748 xkp=xkp, cell_to_index=cell_to_index_scf, sab_nl=sab_nl)
754 CALL cp_fm_to_cfm(bs_env%fm_work_mo(1), bs_env%fm_work_mo(2), cfm_kp)
760 CALL timestop(handle)
768 SUBROUTINE diagonalize_ks_matrix(bs_env)
771 CHARACTER(LEN=*),
PARAMETER :: routinen =
'diagonalize_ks_matrix'
773 INTEGER :: handle, ikp, ispin
774 REAL(kind=
dp) :: cbm, vbm
776 CALL timeset(routinen, handle)
778 ALLOCATE (bs_env%eigenval_scf_Gamma(bs_env%n_ao, bs_env%n_spin))
780 DO ispin = 1, bs_env%n_spin
783 CALL cp_fm_to_fm(bs_env%fm_ks_Gamma(ispin), bs_env%fm_work_mo(1))
784 CALL cp_fm_to_fm(bs_env%fm_s_Gamma, bs_env%fm_work_mo(2))
789 bs_env%fm_work_mo(2), &
790 bs_env%fm_mo_coeff_Gamma(ispin), &
791 bs_env%eigenval_scf_Gamma(:, ispin), &
792 bs_env%fm_work_mo(3), &
793 bs_env%eps_eigval_mat_s)
795 vbm = bs_env%eigenval_scf_Gamma(bs_env%n_occ(ispin), ispin)
796 cbm = bs_env%eigenval_scf_Gamma(bs_env%n_occ(ispin) + 1, ispin)
798 bs_env%band_edges_scf_Gamma(ispin)%VBM = vbm
799 bs_env%band_edges_scf_Gamma(ispin)%CBM = cbm
800 bs_env%e_fermi(ispin) = 0.5_dp*(vbm + cbm)
804 CALL timestop(handle)
807 DO ispin = 1, bs_env%n_spin
808 DO ikp = 1, bs_env%nkp_bs_and_DOS
809 bs_env%eigenval_scf(:, ikp, ispin) = bs_env%eigenval_scf_Gamma(:, ispin)
813 END SUBROUTINE diagonalize_ks_matrix
820 SUBROUTINE check_positive_definite_overlap_mat(bs_env, qs_env)
824 CHARACTER(LEN=*),
PARAMETER :: routinen =
'check_positive_definite_overlap_mat'
826 INTEGER :: handle, ikp, info, u
829 CALL timeset(routinen, handle)
831 DO ikp = 1, bs_env%kpoints_DOS%nkp
835 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
846 WRITE (u, fmt=
"(T2,A)")
""
847 WRITE (u, fmt=
"(T2,A)")
"ERROR: The Cholesky decomposition "// &
848 "of the k-point overlap matrix failed. This is"
849 WRITE (u, fmt=
"(T2,A)")
"because the algorithm is "// &
850 "only correct in the limit of large cells. The cell of "
851 WRITE (u, fmt=
"(T2,A)")
"the calculation is too small. "// &
852 "Use MULTIPLE_UNIT_CELL to create a larger cell "
853 WRITE (u, fmt=
"(T2,A)")
"and to prevent this error."
856 CALL bs_env%para_env%sync()
857 cpabort(
"Please see information on the error above.")
865 CALL timestop(handle)
867 END SUBROUTINE check_positive_definite_overlap_mat
874 SUBROUTINE get_parameters_from_qs_env(qs_env, bs_env)
878 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_parameters_from_qs_env'
880 INTEGER :: color_sub, handle, homo, n_ao, n_atom, u
881 INTEGER,
DIMENSION(3) :: periodic
882 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
891 CALL timeset(routinen, handle)
894 dft_control=dft_control, &
895 scf_control=scf_control, &
898 bs_env%n_spin = dft_control%nspins
899 IF (bs_env%n_spin == 1) bs_env%spin_degeneracy = 2.0_dp
900 IF (bs_env%n_spin == 2) bs_env%spin_degeneracy = 1.0_dp
902 CALL get_mo_set(mo_set=mos(1), nao=n_ao, homo=homo)
904 bs_env%n_occ(1:2) = homo
905 bs_env%n_vir(1:2) = n_ao - homo
907 IF (bs_env%n_spin == 2)
THEN
909 bs_env%n_occ(2) = homo
910 bs_env%n_vir(2) = n_ao - homo
913 bs_env%eps_eigval_mat_s = scf_control%eps_eigval
918 ALLOCATE (bs_env%para_env)
919 CALL bs_env%para_env%from_split(para_env, color_sub)
921 CALL get_qs_env(qs_env, particle_set=particle_set)
923 n_atom =
SIZE(particle_set)
924 bs_env%n_atom = n_atom
927 CALL get_cell(cell=cell, periodic=periodic, h=hmat)
928 bs_env%periodic(1:3) = periodic(1:3)
929 bs_env%hmat(1:3, 1:3) = hmat
930 bs_env%nimages_scf = dft_control%nimages
931 IF (dft_control%nimages == 1)
THEN
932 IF (bs_env%do_gw_ri_rs)
THEN
933 IF (any(periodic /= 0))
THEN
941 ELSE IF (dft_control%nimages > 1)
THEN
942 IF (bs_env%do_gw_ri_rs)
THEN
943 cpabort(
"RI-RS Not Implemented for K-point Calculations")
948 cpabort(
"Wrong number of cells from DFT calculation.")
955 CALL section_vals_val_get(input,
"DFT%REAL_TIME_PROPAGATION%RTBSE%_SECTION_PARAMETERS_", i_val=bs_env%rtp_method)
958 WRITE (u, fmt=
"(T2,2A,T73,I8)")
"Number of occupied molecular orbitals (MOs) ", &
959 "= Number of occupied bands", homo
960 WRITE (u, fmt=
"(T2,2A,T73,I8)")
"Number of unoccupied (= virtual) MOs ", &
961 "= Number of unoccupied bands", n_ao - homo
962 WRITE (u, fmt=
"(T2,A,T73,I8)")
"Number of Gaussian basis functions for MOs", n_ao
964 WRITE (u, fmt=
"(T2,2A,T73,I8)")
"Number of cells considered in the DFT ", &
965 "calculation", bs_env%nimages_scf
969 CALL timestop(handle)
971 END SUBROUTINE get_parameters_from_qs_env
977 SUBROUTINE set_heuristic_parameters(bs_env)
980 CHARACTER(LEN=*),
PARAMETER :: routinen =
'set_heuristic_parameters'
984 CALL timeset(routinen, handle)
986 bs_env%n_bins_max_for_printing = 5000
988 CALL timestop(handle)
990 END SUBROUTINE set_heuristic_parameters
997 SUBROUTINE allocate_and_fill_fm_ks_fm_s(qs_env, bs_env)
1001 CHARACTER(LEN=*),
PARAMETER :: routinen =
'allocate_and_fill_fm_ks_fm_s'
1003 INTEGER :: handle, i_work, ispin
1006 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks, matrix_s
1009 CALL timeset(routinen, handle)
1012 para_env=para_env, &
1013 blacs_env=blacs_env, &
1014 matrix_ks_kp=matrix_ks, &
1015 matrix_s_kp=matrix_s)
1019 ncol_global=bs_env%n_ao, para_env=para_env)
1021 DO i_work = 1,
SIZE(bs_env%fm_work_mo)
1022 CALL cp_fm_create(bs_env%fm_work_mo(i_work), fm_struct)
1031 DO ispin = 1, bs_env%n_spin
1032 CALL cp_fm_create(bs_env%fm_ks_Gamma(ispin), fm_struct)
1033 CALL copy_dbcsr_to_fm(matrix_ks(ispin, 1)%matrix, bs_env%fm_ks_Gamma(ispin))
1034 CALL cp_fm_create(bs_env%fm_mo_coeff_Gamma(ispin), fm_struct)
1039 NULLIFY (bs_env%mat_ao_ao%matrix)
1040 ALLOCATE (bs_env%mat_ao_ao%matrix)
1041 CALL dbcsr_create(bs_env%mat_ao_ao%matrix, template=matrix_s(1, 1)%matrix, &
1042 matrix_type=dbcsr_type_no_symmetry)
1044 ALLOCATE (bs_env%eigenval_scf(bs_env%n_ao, bs_env%nkp_bs_and_DOS, bs_env%n_spin))
1046 CALL timestop(handle)
1048 END SUBROUTINE allocate_and_fill_fm_ks_fm_s
1059 CHARACTER(LEN=*),
PARAMETER :: routinen =
'eval_bandstructure_properties'
1061 INTEGER :: handle, homo, homo_1, homo_2, &
1062 homo_spinor, ikp, ikp_for_file, ispin, &
1063 n_ao, n_e, nkind, nkp
1064 LOGICAL :: is_bandstruc_kpoint, print_dos_kpoints, &
1066 REAL(kind=
dp) :: broadening, e_max, e_max_g0w0, e_min, &
1067 e_min_g0w0, e_total_window, &
1068 energy_step_dos, energy_window_dos, t1
1069 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos_g0w0, dos_g0w0_soc, dos_scf, dos_scf_soc, &
1070 eigenval, eigenval_spinor, eigenval_spinor_g0w0, eigenval_spinor_no_soc
1071 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos_g0w0, pdos_g0w0_soc, pdos_scf, &
1072 pdos_scf_soc, proj_mo_on_kind
1073 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_g0w0_2d, ldos_scf_2d, &
1076 band_edges_scf, band_edges_scf_guess, &
1078 TYPE(
cp_cfm_type) :: cfm_ks_ikp, cfm_ks_ikp_spinor, cfm_mos_ikp_spinor, cfm_s_ikp, &
1079 cfm_s_ikp_copy, cfm_s_ikp_spinor, cfm_s_ikp_spinor_copy, cfm_soc_ikp_spinor, &
1080 cfm_spinor_wf_ikp, cfm_work_ikp, cfm_work_ikp_spinor
1083 CALL timeset(routinen, handle)
1087 energy_window_dos = bs_env%energy_window_DOS
1088 energy_step_dos = bs_env%energy_step_DOS
1089 broadening = bs_env%broadening_DOS
1092 IF (bs_env%do_gw .OR. &
1094 band_edges_scf = bs_env%band_edges_scf
1095 band_edges_scf_guess = band_edges_scf
1098 IF (bs_env%n_spin == 1)
THEN
1099 homo = bs_env%n_occ(1)
1100 band_edges_scf_guess%VBM = bs_env%eigenval_scf_Gamma(homo, 1)
1101 band_edges_scf_guess%CBM = bs_env%eigenval_scf_Gamma(homo + 1, 1)
1103 homo_1 = bs_env%n_occ(1)
1104 homo_2 = bs_env%n_occ(2)
1105 band_edges_scf_guess%VBM = max(bs_env%eigenval_scf_Gamma(homo_1, 1), &
1106 bs_env%eigenval_scf_Gamma(homo_2, 2))
1107 band_edges_scf_guess%CBM = min(bs_env%eigenval_scf_Gamma(homo_1 + 1, 1), &
1108 bs_env%eigenval_scf_Gamma(homo_2 + 1, 2))
1112 band_edges_scf%VBM = -1000.0_dp
1113 band_edges_scf%CBM = 1000.0_dp
1114 band_edges_scf%DBG = 1000.0_dp
1117 e_min = band_edges_scf_guess%VBM - 0.5_dp*energy_window_dos
1118 e_max = band_edges_scf_guess%CBM + 0.5_dp*energy_window_dos
1120 IF (bs_env%do_gw)
THEN
1121 band_edges_g0w0 = bs_env%band_edges_G0W0
1122 e_min_g0w0 = band_edges_g0w0%VBM - 0.5_dp*energy_window_dos
1123 e_max_g0w0 = band_edges_g0w0%CBM + 0.5_dp*energy_window_dos
1124 e_min = min(e_min, e_min_g0w0)
1125 e_max = max(e_max, e_max_g0w0)
1128 e_total_window = e_max - e_min
1130 n_e = int(e_total_window/energy_step_dos)
1134 ALLOCATE (proj_mo_on_kind(n_ao, nkind))
1135 proj_mo_on_kind(:, :) = 0.0_dp
1137 ALLOCATE (eigenval(n_ao))
1138 ALLOCATE (eigenval_spinor(2*n_ao))
1139 ALLOCATE (eigenval_spinor_no_soc(2*n_ao))
1140 ALLOCATE (eigenval_spinor_g0w0(2*n_ao))
1142 IF (bs_env%do_dos_pdos)
THEN
1144 ALLOCATE (dos_scf(n_e))
1146 ALLOCATE (pdos_scf(n_e, nkind))
1147 pdos_scf(:, :) = 0.0_dp
1149 IF (bs_env%do_soc)
THEN
1151 ALLOCATE (dos_scf_soc(n_e))
1152 dos_scf_soc(:) = 0.0_dp
1153 ALLOCATE (pdos_scf_soc(n_e, nkind))
1154 pdos_scf_soc(:, :) = 0.0_dp
1158 IF (bs_env%do_gw)
THEN
1160 ALLOCATE (dos_g0w0(n_e))
1161 dos_g0w0(:) = 0.0_dp
1162 ALLOCATE (pdos_g0w0(n_e, nkind))
1163 pdos_g0w0(:, :) = 0.0_dp
1165 IF (bs_env%do_soc)
THEN
1167 ALLOCATE (dos_g0w0_soc(n_e))
1168 dos_g0w0_soc(:) = 0.0_dp
1169 ALLOCATE (pdos_g0w0_soc(n_e, nkind))
1170 pdos_g0w0_soc(:, :) = 0.0_dp
1176 CALL cp_cfm_create(cfm_mos_ikp(1), bs_env%fm_ks_Gamma(1)%matrix_struct)
1177 CALL cp_cfm_create(cfm_mos_ikp(2), bs_env%fm_ks_Gamma(1)%matrix_struct)
1178 CALL cp_cfm_create(cfm_work_ikp, bs_env%fm_ks_Gamma(1)%matrix_struct)
1179 CALL cp_cfm_create(cfm_s_ikp_copy, bs_env%fm_ks_Gamma(1)%matrix_struct)
1181 IF (bs_env%do_soc)
THEN
1183 CALL cp_cfm_create(cfm_mos_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1184 CALL cp_cfm_create(cfm_work_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1185 CALL cp_cfm_create(cfm_s_ikp_spinor_copy, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1186 CALL cp_cfm_create(cfm_ks_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1187 CALL cp_cfm_create(cfm_soc_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1188 CALL cp_cfm_create(cfm_s_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1189 CALL cp_cfm_create(cfm_spinor_wf_ikp, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1191 homo_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
1193 band_edges_scf_soc%VBM = -1000.0_dp
1194 band_edges_scf_soc%CBM = 1000.0_dp
1195 band_edges_scf_soc%DBG = 1000.0_dp
1197 IF (bs_env%do_gw)
THEN
1198 band_edges_g0w0_soc%VBM = -1000.0_dp
1199 band_edges_g0w0_soc%CBM = 1000.0_dp
1200 band_edges_g0w0_soc%DBG = 1000.0_dp
1203 IF (bs_env%unit_nr > 0)
THEN
1204 WRITE (bs_env%unit_nr,
'(A)')
''
1205 IF (bs_env%soc_window_occ > 0.0_dp)
THEN
1206 WRITE (bs_env%unit_nr,
'(T2,A,T71,F10.2)')
'SOC requested, SOC energy window occ (eV):', &
1207 bs_env%soc_window_occ*
evolt
1209 WRITE (bs_env%unit_nr,
'(T2,A,T71,A10)')
'SOC requested, SOC energy window occ (eV):', &
1212 IF (bs_env%soc_window_virt > 0.0_dp)
THEN
1213 WRITE (bs_env%unit_nr,
'(T2,A,T71,F10.2)')
'SOC requested, SOC energy window virt (eV):', &
1214 bs_env%soc_window_virt*
evolt
1216 WRITE (bs_env%unit_nr,
'(T2,A,T71,A10)')
'SOC requested, SOC energy window virt (eV):', &
1219 IF (bs_env%soc_window_occ > 0.0_dp .OR. bs_env%soc_window_virt > 0.0_dp)
THEN
1220 WRITE (bs_env%unit_nr,
'(T2,A,T71,F10.2)')
'SOC requested, SOC window smearing (eV):', &
1221 bs_env%soc_window_smearing*
evolt
1226 IF (bs_env%do_ldos)
THEN
1230 IF (bs_env%unit_nr > 0)
THEN
1231 WRITE (bs_env%unit_nr,
'(A)')
''
1235 CALL cp_cfm_create(cfm_ks_ikp, bs_env%cfm_ks_kp(1, 1)%matrix_struct)
1236 CALL cp_cfm_create(cfm_s_ikp, bs_env%cfm_ks_kp(1, 1)%matrix_struct)
1239 DO ikp = 1, bs_env%nkp_bs_and_DOS
1243 DO ispin = 1, bs_env%n_spin
1245 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
1250 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
1254 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
1258 CALL cp_cfm_geeig(cfm_ks_ikp, cfm_s_ikp_copy, cfm_mos_ikp(ispin), &
1259 eigenval, cfm_work_ikp)
1264 CALL cp_cfm_to_cfm(bs_env%cfm_ks_kp(ikp, ispin), cfm_ks_ikp)
1270 CALL cp_cfm_to_cfm(bs_env%cfm_mo_coeff_kp(ikp, ispin), cfm_mos_ikp(ispin))
1271 eigenval(:) = bs_env%eigenval_scf(:, ikp, ispin)
1277 CALL compute_proj_mo_on_kind(proj_mo_on_kind, qs_env, cfm_mos_ikp(ispin), cfm_s_ikp)
1280 IF (bs_env%do_dos_pdos)
THEN
1281 CALL add_to_dos_pdos(dos_scf, pdos_scf, eigenval, ikp, bs_env, n_e, e_min, &
1284 IF (bs_env%do_gw)
THEN
1285 CALL add_to_dos_pdos(dos_g0w0, pdos_g0w0, bs_env%eigenval_G0W0(:, ikp, ispin), &
1286 ikp, bs_env, n_e, e_min, proj_mo_on_kind)
1290 IF (bs_env%do_ldos)
THEN
1291 CALL add_to_ldos_2d(ldos_scf_2d, qs_env, ikp, bs_env, cfm_mos_ikp(ispin), &
1292 eigenval(:), band_edges_scf_guess)
1294 IF (bs_env%do_gw)
THEN
1295 CALL add_to_ldos_2d(ldos_g0w0_2d, qs_env, ikp, bs_env, cfm_mos_ikp(ispin), &
1296 bs_env%eigenval_G0W0(:, ikp, 1), band_edges_g0w0)
1301 homo = bs_env%n_occ(ispin)
1303 band_edges_scf%VBM = max(band_edges_scf%VBM, eigenval(homo))
1304 band_edges_scf%CBM = min(band_edges_scf%CBM, eigenval(homo + 1))
1305 band_edges_scf%DBG = min(band_edges_scf%DBG, eigenval(homo + 1) - eigenval(homo))
1310 IF (bs_env%do_soc)
THEN
1313 print_dos_kpoints = (bs_env%nkp_only_bs <= 0)
1315 is_bandstruc_kpoint = (ikp > bs_env%nkp_only_DOS)
1316 print_ikp = print_dos_kpoints .OR. is_bandstruc_kpoint
1318 IF (print_dos_kpoints)
THEN
1319 nkp = bs_env%nkp_only_DOS
1322 nkp = bs_env%nkp_only_bs
1323 ikp_for_file = ikp - bs_env%nkp_only_DOS
1327 CALL soc_ev(bs_env, qs_env, ikp, bs_env%eigenval_scf, &
1328 e_min, cfm_mos_ikp, dos_scf_soc, pdos_scf_soc, &
1329 band_edges_scf_soc, eigenval_spinor, cfm_spinor_wf_ikp)
1331 IF (.NOT. bs_env%do_gw .AND. print_ikp)
THEN
1332 CALL write_soc_eigenvalues(eigenval_spinor, ikp_for_file, ikp, bs_env)
1335 IF (bs_env%do_ldos)
THEN
1336 CALL add_to_ldos_2d(ldos_scf_2d_soc, qs_env, ikp, bs_env, cfm_spinor_wf_ikp, &
1337 eigenval_spinor, band_edges_scf_guess, .true., cfm_work_ikp)
1340 IF (bs_env%do_gw)
THEN
1343 CALL soc_ev(bs_env, qs_env, ikp, bs_env%eigenval_G0W0, &
1344 e_min, cfm_mos_ikp, dos_g0w0_soc, pdos_g0w0_soc, &
1345 band_edges_g0w0_soc, eigenval_spinor_g0w0, cfm_spinor_wf_ikp)
1350 CALL write_soc_eigenvalues(eigenval_spinor, ikp_for_file, ikp, bs_env, &
1351 eigenval_spinor_g0w0)
1358 IF (bs_env%unit_nr > 0 .AND.
m_walltime() - t1 > 20.0_dp)
THEN
1359 WRITE (bs_env%unit_nr,
'(T2,A,T43,I5,A,I3,A,F7.1,A)') &
1360 'Compute DOS, LDOS for k-point ', ikp,
' /', bs_env%nkp_bs_and_DOS, &
1366 band_edges_scf%IDBG = band_edges_scf%CBM - band_edges_scf%VBM
1367 IF (bs_env%do_soc)
THEN
1368 band_edges_scf_soc%IDBG = band_edges_scf_soc%CBM - band_edges_scf_soc%VBM
1369 IF (bs_env%do_gw)
THEN
1370 band_edges_g0w0_soc%IDBG = band_edges_g0w0_soc%CBM - band_edges_g0w0_soc%VBM
1374 CALL write_band_edges(band_edges_scf,
"SCF", bs_env)
1375 IF (bs_env%do_dos_pdos)
THEN
1376 CALL write_dos_pdos(dos_scf, pdos_scf, bs_env, qs_env,
"SCF", e_min, band_edges_scf%VBM)
1378 IF (bs_env%do_ldos)
THEN
1379 CALL print_ldos_main(ldos_scf_2d, bs_env, band_edges_scf,
"SCF")
1382 IF (bs_env%do_soc)
THEN
1383 CALL write_band_edges(band_edges_scf_soc,
"SCF+SOC", bs_env)
1384 IF (bs_env%do_dos_pdos)
THEN
1385 CALL write_dos_pdos(dos_scf_soc, pdos_scf_soc, bs_env, qs_env,
"SCF_SOC", &
1386 e_min, band_edges_scf_soc%VBM)
1388 IF (bs_env%do_ldos)
THEN
1391 CALL print_ldos_main(ldos_scf_2d_soc, bs_env, band_edges_scf, &
1396 IF (bs_env%do_gw)
THEN
1397 CALL write_band_edges(band_edges_g0w0,
"G0W0", bs_env)
1398 CALL write_band_edges(bs_env%band_edges_HF,
"Hartree-Fock with SCF orbitals", bs_env)
1399 IF (bs_env%do_dos_pdos)
THEN
1400 CALL write_dos_pdos(dos_g0w0, pdos_g0w0, bs_env, qs_env,
"G0W0", e_min, &
1401 band_edges_g0w0%VBM)
1403 IF (bs_env%do_ldos)
THEN
1404 CALL print_ldos_main(ldos_g0w0_2d, bs_env, band_edges_g0w0,
"G0W0")
1408 IF (bs_env%do_soc .AND. bs_env%do_gw)
THEN
1409 CALL write_band_edges(band_edges_g0w0_soc,
"G0W0+SOC", bs_env)
1410 IF (bs_env%do_dos_pdos)
THEN
1411 CALL write_dos_pdos(dos_g0w0_soc, pdos_g0w0_soc, bs_env, qs_env,
"G0W0_SOC", e_min, &
1412 band_edges_g0w0_soc%VBM)
1431 CALL timestop(handle)
1442 SUBROUTINE print_ldos_main(LDOS_2d, bs_env, band_edges, scf_gw_soc)
1443 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d
1446 CHARACTER(LEN=*) :: scf_gw_soc
1448 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_LDOS_main'
1450 INTEGER :: handle, i_x, i_x_bin, i_x_end, i_x_end_bin, i_x_end_glob, i_x_start, &
1451 i_x_start_bin, i_x_start_glob, i_y, i_y_bin, i_y_end, i_y_end_bin, i_y_end_glob, &
1452 i_y_start, i_y_start_bin, i_y_start_glob, n_e
1453 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: n_sum_for_bins
1454 INTEGER,
DIMENSION(2) :: bin_mesh
1455 LOGICAL :: do_xy_bins
1456 REAL(kind=
dp) :: e_min, energy_step, energy_window
1457 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d_bins
1459 CALL timeset(routinen, handle)
1461 n_e =
SIZE(ldos_2d, 3)
1463 energy_window = bs_env%energy_window_DOS
1464 energy_step = bs_env%energy_step_DOS
1465 e_min = band_edges%VBM - 0.5_dp*energy_window
1467 bin_mesh(1:2) = bs_env%bin_mesh(1:2)
1468 do_xy_bins = (bin_mesh(1) > 0 .AND. bin_mesh(2) > 0)
1470 i_x_start = lbound(ldos_2d, 1)
1471 i_x_end = ubound(ldos_2d, 1)
1472 i_y_start = lbound(ldos_2d, 2)
1473 i_y_end = ubound(ldos_2d, 2)
1475 IF (do_xy_bins)
THEN
1477 i_x_end_bin = bin_mesh(1)
1479 i_y_end_bin = bin_mesh(2)
1481 i_x_start_bin = i_x_start
1482 i_x_end_bin = i_x_end
1483 i_y_start_bin = i_y_start
1484 i_y_end_bin = i_y_end
1487 ALLOCATE (ldos_2d_bins(i_x_start_bin:i_x_end_bin, i_y_start_bin:i_y_end_bin, n_e))
1488 ldos_2d_bins(:, :, :) = 0.0_dp
1490 IF (do_xy_bins)
THEN
1492 i_x_start_glob = i_x_start
1493 i_x_end_glob = i_x_end
1494 i_y_start_glob = i_y_start
1495 i_y_end_glob = i_y_end
1497 CALL bs_env%para_env%min(i_x_start_glob)
1498 CALL bs_env%para_env%max(i_x_end_glob)
1499 CALL bs_env%para_env%min(i_y_start_glob)
1500 CALL bs_env%para_env%max(i_y_end_glob)
1502 ALLOCATE (n_sum_for_bins(bin_mesh(1), bin_mesh(2)), source=0)
1505 DO i_y = i_y_start, i_y_end
1506 DO i_x = i_x_start, i_x_end
1507 i_x_bin = bin_mesh(1)*(i_x - i_x_start_glob)/(i_x_end_glob - i_x_start_glob + 1) + 1
1508 i_y_bin = bin_mesh(2)*(i_y - i_y_start_glob)/(i_y_end_glob - i_y_start_glob + 1) + 1
1509 ldos_2d_bins(i_x_bin, i_y_bin, :) = ldos_2d_bins(i_x_bin, i_y_bin, :) + &
1510 ldos_2d(i_x, i_y, :)
1511 n_sum_for_bins(i_x_bin, i_y_bin) = n_sum_for_bins(i_x_bin, i_y_bin) + 1
1515 CALL bs_env%para_env%sum(ldos_2d_bins)
1516 CALL bs_env%para_env%sum(n_sum_for_bins)
1519 DO i_y_bin = 1, bin_mesh(2)
1520 DO i_x_bin = 1, bin_mesh(1)
1521 ldos_2d_bins(i_x_bin, i_y_bin, :) = ldos_2d_bins(i_x_bin, i_y_bin, :)/ &
1522 REAL(n_sum_for_bins(i_x_bin, i_y_bin), kind=
dp)
1528 ldos_2d_bins(:, :, :) = ldos_2d(:, :, :)
1532 IF (bin_mesh(1)*bin_mesh(2) < bs_env%n_bins_max_for_printing)
THEN
1533 CALL print_ldos_2d_bins(ldos_2d_bins, bs_env, e_min, scf_gw_soc)
1535 cpwarn(
"The number of bins for the LDOS is too large. Decrease BIN_MESH.")
1538 CALL timestop(handle)
1540 END SUBROUTINE print_ldos_main
1549 SUBROUTINE print_ldos_2d_bins(LDOS_2d_bins, bs_env, E_min, scf_gw_soc)
1550 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d_bins
1552 REAL(kind=
dp) :: e_min
1553 CHARACTER(LEN=*) :: scf_gw_soc
1555 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_LDOS_2d_bins'
1557 CHARACTER(LEN=18) :: print_format
1558 CHARACTER(LEN=4) :: print_format_1, print_format_2
1559 CHARACTER(len=default_string_length) :: fname
1560 INTEGER :: handle, i_e, i_x, i_x_end, i_x_start, &
1561 i_y, i_y_end, i_y_start, iunit, n_e, &
1563 REAL(kind=
dp) :: energy
1564 REAL(kind=
dp),
DIMENSION(3) :: coord,
idx
1566 CALL timeset(routinen, handle)
1568 i_x_start = lbound(ldos_2d_bins, 1)
1569 i_x_end = ubound(ldos_2d_bins, 1)
1570 i_y_start = lbound(ldos_2d_bins, 2)
1571 i_y_end = ubound(ldos_2d_bins, 2)
1572 n_e =
SIZE(ldos_2d_bins, 3)
1574 n_x = i_x_end - i_x_start + 1
1575 n_y = i_y_end - i_y_start + 1
1577 IF (bs_env%para_env%is_source())
THEN
1579 DO i_y = i_y_start, i_y_end
1580 DO i_x = i_x_start, i_x_end
1582 idx(1) = (real(i_x, kind=
dp) - 0.5_dp)/real(n_x, kind=
dp)
1583 idx(2) = (real(i_y, kind=
dp) - 0.5_dp)/real(n_y, kind=
dp)
1585 coord(1:3) = matmul(bs_env%hmat,
idx)
1587 CALL get_print_format(coord(1), print_format_1)
1588 CALL get_print_format(coord(2), print_format_2)
1590 print_format =
"(3A,"//print_format_1//
",A,"//print_format_2//
",A)"
1592 WRITE (fname, print_format)
"LDOS_", scf_gw_soc, &
1595 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", &
1596 file_action=
"WRITE")
1598 WRITE (iunit,
"(2A)") Å
" Energy E (eV) average LDOS(x,y,E) (1/(eV*^2), ", &
1599 "integrated over z, averaged inside bin)"
1602 energy = e_min + i_e*bs_env%energy_step_DOS
1603 WRITE (iunit,
"(2F17.3)") energy*
evolt, &
1604 ldos_2d_bins(i_x, i_y, i_e)* &
1605 bs_env%unit_ldos_int_z_inv_Ang2_eV
1615 CALL timestop(handle)
1617 END SUBROUTINE print_ldos_2d_bins
1624 SUBROUTINE get_print_format(coord, print_format)
1625 REAL(kind=
dp) :: coord
1626 CHARACTER(LEN=4) :: print_format
1628 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_print_format'
1632 CALL timeset(routinen, handle)
1635 print_format =
"F9.2"
1636 ELSE IF (coord < -1000/
angstrom)
THEN
1637 print_format =
"F8.2"
1638 ELSE IF (coord < -100/
angstrom)
THEN
1639 print_format =
"F7.2"
1640 ELSE IF (coord < -10/
angstrom)
THEN
1641 print_format =
"F6.2"
1643 print_format =
"F5.2"
1645 print_format =
"F4.2"
1646 ELSE IF (coord < 100/
angstrom)
THEN
1647 print_format =
"F5.2"
1648 ELSE IF (coord < 1000/
angstrom)
THEN
1649 print_format =
"F6.2"
1650 ELSE IF (coord < 10000/
angstrom)
THEN
1651 print_format =
"F7.2"
1653 print_format =
"F8.2"
1656 CALL timestop(handle)
1658 END SUBROUTINE get_print_format
1674 SUBROUTINE soc_ev(bs_env, qs_env, ikp, eigenval_no_SOC, E_min, cfm_mos_ikp, &
1675 DOS, PDOS, band_edges, eigenval_spinor, cfm_spinor_wf_ikp)
1680 REAL(kind=
dp),
DIMENSION(:, :, :) :: eigenval_no_soc
1681 REAL(kind=
dp) :: e_min
1683 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos
1684 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
1686 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor
1689 CHARACTER(LEN=*),
PARAMETER :: routinen =
'SOC_ev'
1691 INTEGER :: handle, homo_spinor, n_ao, n_e, nkind
1692 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor_no_soc
1693 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind_spinor
1695 cfm_ks_ikp_spinor, cfm_mos_ikp_spinor, &
1696 cfm_soc_ikp_spinor, cfm_work_ikp_spinor
1700 CALL timeset(routinen, handle)
1703 homo_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
1706 CALL cp_cfm_create(cfm_ks_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1707 CALL cp_cfm_create(cfm_soc_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1708 CALL cp_cfm_create(cfm_mos_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1709 CALL cp_cfm_create(cfm_work_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1710 CALL cp_cfm_create(cfm_eigenvec_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1712 ALLOCATE (eigenval_spinor_no_soc(2*n_ao))
1713 ALLOCATE (proj_mo_on_kind_spinor(2*n_ao, nkind))
1715 proj_mo_on_kind_spinor(:, :) = 0.0_dp
1718 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
1722 CALL cfm_ikp_from_cfm_spinor_gamma(cfm_soc_ikp_spinor, &
1723 bs_env%cfm_SOC_spinor_ao(1), &
1724 bs_env%fm_s_Gamma%matrix_struct, &
1725 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
1730 CALL cp_cfm_to_cfm(bs_env%cfm_SOC_spinor_ao(ikp), cfm_soc_ikp_spinor)
1740 CALL add_cfm_submat(cfm_mos_ikp_spinor, cfm_mos_ikp(bs_env%n_spin), n_ao + 1, n_ao + 1)
1744 cfm_mos_ikp_spinor, cfm_soc_ikp_spinor, &
1745 z_zero, cfm_work_ikp_spinor)
1749 cfm_work_ikp_spinor, cfm_mos_ikp_spinor, &
1750 z_zero, cfm_ks_ikp_spinor)
1755 eigenval_spinor_no_soc(1:n_ao) = eigenval_no_soc(1:n_ao, ikp, 1)
1756 eigenval_spinor_no_soc(n_ao + 1:) = eigenval_no_soc(1:n_ao, ikp, bs_env%n_spin)
1757 IF (bs_env%soc_window_occ > 0.0_dp .OR. bs_env%soc_window_virt > 0.0_dp)
THEN
1759 bs_env%soc_window_virt, &
1760 bs_env%soc_window_smearing, &
1761 eigenval_spinor_no_soc, &
1770 CALL cp_cfm_heevd(cfm_ks_ikp_spinor, cfm_eigenvec_ikp_spinor, eigenval_spinor)
1773 IF (bs_env%do_dos_pdos)
THEN
1775 CALL add_to_dos_pdos(dos, pdos, eigenval_spinor, &
1776 ikp, bs_env, n_e, e_min, proj_mo_on_kind_spinor)
1780 band_edges%VBM = max(band_edges%VBM, eigenval_spinor(homo_spinor))
1781 band_edges%CBM = min(band_edges%CBM, eigenval_spinor(homo_spinor + 1))
1782 band_edges%DBG = min(band_edges%DBG, eigenval_spinor(homo_spinor + 1) &
1783 - eigenval_spinor(homo_spinor))
1787 cfm_mos_ikp_spinor, cfm_eigenvec_ikp_spinor, &
1788 z_zero, cfm_spinor_wf_ikp)
1796 CALL timestop(handle)
1798 END SUBROUTINE soc_ev
1811 SUBROUTINE add_to_dos_pdos(DOS, PDOS, eigenval, ikp, bs_env, n_E, E_min, proj_mo_on_kind)
1813 REAL(kind=
dp),
DIMENSION(:) :: dos
1814 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
1815 REAL(kind=
dp),
DIMENSION(:) :: eigenval
1819 REAL(kind=
dp) :: e_min
1820 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind
1822 CHARACTER(LEN=*),
PARAMETER :: routinen =
'add_to_DOS_PDOS'
1824 INTEGER :: handle, i_e, i_kind, i_mo, n_mo, nkind
1825 REAL(kind=
dp) :: broadening, energy, energy_step_dos, wkp
1827 CALL timeset(routinen, handle)
1829 energy_step_dos = bs_env%energy_step_DOS
1830 broadening = bs_env%broadening_DOS
1832 n_mo =
SIZE(eigenval)
1833 nkind =
SIZE(proj_mo_on_kind, 2)
1836 wkp = bs_env%kpoints_DOS%wkp(ikp)*bs_env%spin_degeneracy
1838 energy = e_min + i_e*energy_step_dos
1841 dos(i_e) = dos(i_e) + wkp*
gaussian(energy - eigenval(i_mo), broadening)
1844 DO i_kind = 1, nkind
1845 IF (proj_mo_on_kind(i_mo, i_kind) > 0.0_dp)
THEN
1846 pdos(i_e, i_kind) = pdos(i_e, i_kind) + &
1847 proj_mo_on_kind(i_mo, i_kind)*wkp* &
1848 gaussian(energy - eigenval(i_mo), broadening)
1854 CALL timestop(handle)
1856 END SUBROUTINE add_to_dos_pdos
1870 SUBROUTINE add_to_ldos_2d(LDOS_2d, qs_env, ikp, bs_env, cfm_mos_ikp, eigenval, &
1871 band_edges, do_spinor, cfm_non_spinor)
1872 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d
1877 REAL(kind=
dp),
DIMENSION(:) :: eigenval
1879 LOGICAL,
OPTIONAL :: do_spinor
1882 CHARACTER(LEN=*),
PARAMETER :: routinen =
'add_to_LDOS_2d'
1884 INTEGER :: handle, i_e, i_x_end, i_x_start, i_y_end, i_y_start, i_z, i_z_end, i_z_start, &
1885 j_col, j_mo, n_e, n_mo, n_z, ncol_local, nimages, z_end_global, z_start_global
1886 INTEGER,
DIMENSION(:),
POINTER :: col_indices
1887 LOGICAL :: is_any_weight_non_zero, my_do_spinor
1888 REAL(kind=
dp) :: broadening, e_max, e_min, &
1889 e_total_window, energy, energy_step, &
1890 energy_window, spin_degeneracy, weight
1891 TYPE(
cp_cfm_type) :: cfm_weighted_dm_ikp, cfm_work
1892 TYPE(
cp_fm_type) :: fm_non_spinor, fm_weighted_dm_mic
1893 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: weighted_dm_mic
1901 CALL timeset(routinen, handle)
1903 my_do_spinor = .false.
1904 IF (
PRESENT(do_spinor)) my_do_spinor = do_spinor
1906 CALL get_qs_env(qs_env, ks_env=ks_env, pw_env=pw_env, dft_control=dft_control)
1909 nimages = dft_control%nimages
1910 dft_control%nimages = bs_env%nimages_scf
1912 energy_window = bs_env%energy_window_DOS
1913 energy_step = bs_env%energy_step_DOS
1914 broadening = bs_env%broadening_DOS
1916 e_min = band_edges%VBM - 0.5_dp*energy_window
1917 e_max = band_edges%CBM + 0.5_dp*energy_window
1918 e_total_window = e_max - e_min
1920 n_e = int(e_total_window/energy_step)
1922 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1924 CALL auxbas_pw_pool%create_pw(ldos_3d)
1925 CALL auxbas_pw_pool%create_pw(rho_g)
1927 i_x_start = lbound(ldos_3d%array, 1)
1928 i_x_end = ubound(ldos_3d%array, 1)
1929 i_y_start = lbound(ldos_3d%array, 2)
1930 i_y_end = ubound(ldos_3d%array, 2)
1931 i_z_start = lbound(ldos_3d%array, 3)
1932 i_z_end = ubound(ldos_3d%array, 3)
1934 z_start_global = i_z_start
1935 z_end_global = i_z_end
1937 CALL bs_env%para_env%min(z_start_global)
1938 CALL bs_env%para_env%max(z_end_global)
1939 n_z = z_end_global - z_start_global + 1
1941 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)) &
1942 cpabort(°
"Please choose a cell that has 90 angles to the z-direction.")
1944 bs_env%unit_ldos_int_z_inv_Ang2_eV = bs_env%hmat(3, 3)/real(n_z, kind=
dp)/
evolt/
angstrom**2
1947 ALLOCATE (ldos_2d(i_x_start:i_x_end, i_y_start:i_y_end, n_e))
1948 ldos_2d(:, :, :) = 0.0_dp
1952 CALL cp_cfm_create(cfm_weighted_dm_ikp, cfm_mos_ikp%matrix_struct)
1953 CALL cp_fm_create(fm_weighted_dm_mic, cfm_mos_ikp%matrix_struct)
1954 IF (my_do_spinor)
THEN
1955 CALL cp_fm_create(fm_non_spinor, cfm_non_spinor%matrix_struct)
1960 ncol_local=ncol_local, &
1961 col_indices=col_indices)
1963 NULLIFY (weighted_dm_mic)
1965 ALLOCATE (weighted_dm_mic(1)%matrix)
1966 CALL dbcsr_create(weighted_dm_mic(1)%matrix, template=bs_env%mat_ao_ao%matrix, &
1967 matrix_type=dbcsr_type_symmetric)
1971 energy = e_min + i_e*energy_step
1973 is_any_weight_non_zero = .false.
1975 DO j_col = 1, ncol_local
1977 j_mo = col_indices(j_col)
1979 IF (my_do_spinor)
THEN
1980 spin_degeneracy = 1.0_dp
1982 spin_degeneracy = bs_env%spin_degeneracy
1985 weight =
gaussian(energy - eigenval(j_mo), broadening)*spin_degeneracy
1987 cfm_work%local_data(:, j_col) = cfm_mos_ikp%local_data(:, j_col)*weight
1989 IF (weight > 1.0e-5_dp) is_any_weight_non_zero = .true.
1993 CALL bs_env%para_env%sync()
1994 CALL bs_env%para_env%sum(is_any_weight_non_zero)
1995 CALL bs_env%para_env%sync()
1998 IF (is_any_weight_non_zero)
THEN
2001 cfm_mos_ikp, cfm_work,
z_zero, cfm_weighted_dm_ikp)
2003 IF (my_do_spinor)
THEN
2009 cfm_non_spinor, ikp, bs_env%kpoints_DOS, &
2010 "ORB", bs_env%kpoints_DOS%wkp(ikp))
2013 CALL get_cfm_submat(cfm_non_spinor, cfm_weighted_dm_ikp, n_mo/2, n_mo/2)
2015 cfm_non_spinor, ikp, bs_env%kpoints_DOS, &
2016 "ORB", bs_env%kpoints_DOS%wkp(ikp))
2018 keep_sparsity=.false.)
2022 cfm_weighted_dm_ikp, ikp, bs_env%kpoints_DOS, &
2023 "ORB", bs_env%kpoints_DOS%wkp(ikp))
2025 keep_sparsity=.false.)
2028 ldos_3d%array(:, :, :) = 0.0_dp
2035 DO i_z = i_z_start, i_z_end
2036 ldos_2d(:, :, i_e) = ldos_2d(:, :, i_e) + ldos_3d%array(:, :, i_z)
2044 dft_control%nimages = nimages
2046 CALL auxbas_pw_pool%give_back_pw(ldos_3d)
2047 CALL auxbas_pw_pool%give_back_pw(rho_g)
2056 IF (my_do_spinor)
THEN
2060 CALL timestop(handle)
2062 END SUBROUTINE add_to_ldos_2d
2072 SUBROUTINE write_soc_eigenvalues(eigenval_spinor, ikp_for_file, ikp, bs_env, eigenval_spinor_G0W0)
2074 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor
2075 INTEGER :: ikp_for_file, ikp
2077 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: eigenval_spinor_g0w0
2079 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_SOC_eigenvalues'
2081 CHARACTER(len=3) :: occ_vir
2082 CHARACTER(LEN=default_string_length) :: fname
2083 INTEGER :: handle, i_mo, iunit, n_occ_spinor
2085 CALL timeset(routinen, handle)
2087 fname =
"bandstructure_SCF_and_G0W0_plus_SOC"
2089 IF (bs_env%para_env%is_source())
THEN
2091 IF (ikp_for_file == 1)
THEN
2092 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", &
2093 file_action=
"WRITE")
2095 CALL open_file(trim(fname), unit_number=iunit, file_status=
"OLD", &
2096 file_action=
"WRITE", file_position=
"APPEND")
2099 WRITE (iunit,
"(A)")
" "
2100 WRITE (iunit,
"(A10,I7,A25,3F10.4)")
"kpoint: ", ikp_for_file,
"coordinate: ", &
2101 bs_env%kpoints_DOS%xkp(:, ikp)
2102 WRITE (iunit,
"(A)")
" "
2104 IF (
PRESENT(eigenval_spinor_g0w0))
THEN
2106 WRITE (iunit,
"(A5,A12,2A22)")
"n",
"k", ϵ
"_nk^DFT+SOC (eV)", ϵ
"_nk^G0W0+SOC (eV)"
2109 WRITE (iunit,
"(A5,A12,A22)")
"n",
"k", ϵ
"_nk^DFT+SOC (eV)"
2112 n_occ_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
2114 DO i_mo = 1,
SIZE(eigenval_spinor)
2115 IF (i_mo <= n_occ_spinor) occ_vir =
'occ'
2116 IF (i_mo > n_occ_spinor) occ_vir =
'vir'
2117 IF (
PRESENT(eigenval_spinor_g0w0))
THEN
2119 WRITE (iunit,
"(I5,3A,I5,4F16.3,2F17.3)") i_mo,
' (', occ_vir,
') ', &
2120 ikp_for_file, eigenval_spinor(i_mo)*
evolt, eigenval_spinor_g0w0(i_mo)*
evolt
2123 WRITE (iunit,
"(I5,3A,I5,4F16.3,F17.3)") i_mo,
' (', occ_vir,
') ', &
2124 ikp_for_file, eigenval_spinor(i_mo)*
evolt
2132 CALL timestop(handle)
2134 END SUBROUTINE write_soc_eigenvalues
2141 PURE FUNCTION count_digits(int_number)
2143 INTEGER,
INTENT(IN) :: int_number
2144 INTEGER :: count_digits
2146 INTEGER :: digitcount, tempint
2150 tempint = int_number
2152 DO WHILE (tempint /= 0)
2153 tempint = tempint/10
2154 digitcount = digitcount + 1
2157 count_digits = digitcount
2159 END FUNCTION count_digits
2167 SUBROUTINE write_band_edges(band_edges, scf_gw_soc, bs_env)
2170 CHARACTER(LEN=*) :: scf_gw_soc
2173 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_band_edges'
2175 CHARACTER(LEN=17) :: print_format
2176 INTEGER :: handle, u
2178 CALL timeset(routinen, handle)
2181 print_format =
"(T2,2A,T61,F20.3)"
2185 WRITE (u,
'(T2,A)')
''
2186 WRITE (u, print_format) scf_gw_soc,
' valence band maximum (eV):', band_edges%VBM*
evolt
2187 WRITE (u, print_format) scf_gw_soc,
' conduction band minimum (eV):', band_edges%CBM*
evolt
2188 WRITE (u, print_format) scf_gw_soc,
' indirect band gap (eV):', band_edges%IDBG*
evolt
2189 WRITE (u, print_format) scf_gw_soc,
' direct band gap (eV):', band_edges%DBG*
evolt
2192 CALL timestop(handle)
2194 END SUBROUTINE write_band_edges
2206 SUBROUTINE write_dos_pdos(DOS, PDOS, bs_env, qs_env, scf_gw_soc, E_min, E_VBM)
2207 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos
2208 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
2211 CHARACTER(LEN=*) :: scf_gw_soc
2212 REAL(kind=
dp) :: e_min, e_vbm
2214 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_dos_pdos'
2216 CHARACTER(LEN=3),
DIMENSION(100) :: elements
2217 CHARACTER(LEN=default_string_length) :: atom_name, fname, output_string
2218 INTEGER :: handle, i_e, i_kind, iatom, iunit, n_a, &
2220 REAL(kind=
dp) :: energy
2223 CALL timeset(routinen, handle)
2225 WRITE (fname,
"(3A)")
"DOS_PDOS_", scf_gw_soc,
".out"
2228 nkind =
SIZE(pdos, 2)
2229 CALL get_qs_env(qs_env, particle_set=particle_set)
2231 IF (bs_env%para_env%is_source())
THEN
2233 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", file_action=
"WRITE")
2237 DO iatom = 1, bs_env%n_atom
2239 kind_number=i_kind, name=atom_name)
2240 elements(i_kind) = atom_name(1:3)
2243 WRITE (output_string,
"(A,I1,A)")
"(", n_a,
"A)"
2245 WRITE (iunit, trim(output_string))
"Energy-E_F (eV) DOS (1/eV) PDOS (1/eV) ", &
2246 " of atom type ", elements(1:nkind)
2248 WRITE (output_string,
"(A,I1,A)")
"(", n_a,
"F13.5)"
2252 energy = e_min + i_e*bs_env%energy_step_DOS - e_vbm
2253 WRITE (iunit, trim(output_string)) energy*
evolt, dos(i_e)/
evolt, pdos(i_e, :)/
evolt
2260 CALL timestop(handle)
2262 END SUBROUTINE write_dos_pdos
2270 PURE FUNCTION gaussian(energy, broadening)
2272 REAL(kind=
dp),
INTENT(IN) :: energy, broadening
2275 IF (abs(energy) < 5*broadening)
THEN
2276 gaussian = 1.0_dp/broadening/sqrt(
twopi)*exp(-0.5_dp*energy**2/broadening**2)
2290 SUBROUTINE compute_proj_mo_on_kind(proj_mo_on_kind, qs_env, cfm_mos, cfm_s)
2291 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind
2295 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_proj_mo_on_kind'
2297 INTEGER :: handle, i_atom, i_global, i_kind, i_row, &
2298 j_col, n_ao, n_mo, ncol_local, nkind, &
2300 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf, kind_of
2301 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2303 TYPE(
cp_cfm_type) :: cfm_proj, cfm_s_i_kind, cfm_work
2306 CALL timeset(routinen, handle)
2308 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, nkind=nkind)
2313 nrow_local=nrow_local, &
2314 ncol_local=ncol_local, &
2315 row_indices=row_indices, &
2316 col_indices=col_indices)
2318 n_ao = qs_env%bs_env%n_ao
2320 ALLOCATE (atom_from_bf(n_ao))
2323 proj_mo_on_kind(:, :) = 0.0_dp
2331 DO i_kind = 1, nkind
2336 DO j_col = 1, ncol_local
2337 DO i_row = 1, nrow_local
2339 i_global = row_indices(i_row)
2341 IF (i_global <= n_ao)
THEN
2342 i_atom = atom_from_bf(i_global)
2343 ELSE IF (i_global <= 2*n_ao)
THEN
2344 i_atom = atom_from_bf(i_global - n_ao)
2346 cpabort(
"Wrong indices.")
2349 IF (i_kind /= kind_of(i_atom))
THEN
2350 cfm_s_i_kind%local_data(i_row, j_col) =
z_zero
2357 cfm_s_i_kind, cfm_mos,
z_zero, cfm_work)
2359 cfm_mos, cfm_work,
z_zero, cfm_proj)
2374 CALL timestop(handle)
2376 END SUBROUTINE compute_proj_mo_on_kind
2388 SUBROUTINE cfm_ikp_from_cfm_spinor_gamma(cfm_spinor_ikp, cfm_spinor_Gamma, fm_struct_non_spinor, &
2389 ikp, qs_env, kpoints, basis_type)
2390 TYPE(
cp_cfm_type) :: cfm_spinor_ikp, cfm_spinor_gamma
2395 CHARACTER(LEN=*) :: basis_type
2397 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cfm_ikp_from_cfm_spinor_Gamma'
2399 INTEGER :: handle, i_block, i_offset, j_block, &
2401 TYPE(
cp_cfm_type) :: cfm_non_spinor_gamma, cfm_non_spinor_ikp
2402 TYPE(
cp_fm_type) :: fm_non_spinor_gamma_im, &
2403 fm_non_spinor_gamma_re
2405 CALL timeset(routinen, handle)
2407 CALL cp_cfm_create(cfm_non_spinor_gamma, fm_struct_non_spinor)
2408 CALL cp_cfm_create(cfm_non_spinor_ikp, fm_struct_non_spinor)
2409 CALL cp_fm_create(fm_non_spinor_gamma_re, fm_struct_non_spinor)
2410 CALL cp_fm_create(fm_non_spinor_gamma_im, fm_struct_non_spinor)
2418 i_offset = i_block*n_ao + 1
2419 j_offset = j_block*n_ao + 1
2420 CALL get_cfm_submat(cfm_non_spinor_gamma, cfm_spinor_gamma, i_offset, j_offset)
2421 CALL cp_cfm_to_fm(cfm_non_spinor_gamma, fm_non_spinor_gamma_re, fm_non_spinor_gamma_im)
2425 ikp, qs_env, kpoints, basis_type)
2426 CALL add_cfm_submat(cfm_spinor_ikp, cfm_non_spinor_ikp, i_offset, j_offset)
2430 ikp, qs_env, kpoints, basis_type)
2441 CALL timestop(handle)
2443 END SUBROUTINE cfm_ikp_from_cfm_spinor_gamma
2460 CHARACTER(LEN=*) :: basis_type
2462 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cfm_ikp_from_fm_Gamma'
2464 INTEGER :: col_global, handle, i_atom, i_atom_old, i_cell, i_mic_cell, i_row, j_atom, &
2465 j_atom_old, j_cell, j_col, n_bf, ncol_local, nrow_local, num_cells, row_global
2466 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf
2467 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2468 INTEGER,
DIMENSION(:, :),
POINTER :: index_to_cell
2469 LOGICAL :: i_cell_is_the_minimum_image_cell
2470 REAL(kind=
dp) :: abs_rab_cell_i, abs_rab_cell_j, arg
2471 REAL(kind=
dp),
DIMENSION(3) :: cell_vector, cell_vector_j, rab_cell_i, &
2473 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
2477 CALL timeset(routinen, handle)
2479 IF (.NOT.
ASSOCIATED(cfm_ikp%local_data))
THEN
2485 nrow_local=nrow_local, &
2486 ncol_local=ncol_local, &
2487 row_indices=row_indices, &
2488 col_indices=col_indices)
2491 IF (basis_type ==
"ORB")
THEN
2492 n_bf = qs_env%bs_env%n_ao
2493 ELSE IF (basis_type ==
"RI_AUX")
THEN
2494 n_bf = qs_env%bs_env%n_RI
2496 cpabort(
"Only ORB and RI_AUX basis implemented.")
2499 ALLOCATE (atom_from_bf(n_bf))
2502 NULLIFY (cell, particle_set)
2503 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
2506 index_to_cell => kpoints%index_to_cell
2508 num_cells =
SIZE(index_to_cell, 2)
2512 DO j_col = 1, ncol_local
2513 DO i_row = 1, nrow_local
2515 row_global = row_indices(i_row)
2516 col_global = col_indices(j_col)
2518 i_atom = atom_from_bf(row_global)
2519 j_atom = atom_from_bf(col_global)
2522 IF (i_atom /= i_atom_old .OR. j_atom /= j_atom_old)
THEN
2523 DO i_cell = 1, num_cells
2526 IF (any(abs(index_to_cell(1:3, i_cell)) > 1)) cycle
2528 cell_vector(1:3) = matmul(hmat, real(index_to_cell(1:3, i_cell),
dp))
2530 rab_cell_i(1:3) =
pbc(particle_set(i_atom)%r(1:3), cell) - &
2531 (
pbc(particle_set(j_atom)%r(1:3), cell) + cell_vector(1:3))
2532 abs_rab_cell_i = sqrt(rab_cell_i(1)**2 + rab_cell_i(2)**2 + rab_cell_i(3)**2)
2535 i_cell_is_the_minimum_image_cell = .true.
2536 DO j_cell = 1, num_cells
2537 cell_vector_j(1:3) = matmul(hmat, real(index_to_cell(1:3, j_cell),
dp))
2538 rab_cell_j(1:3) =
pbc(particle_set(i_atom)%r(1:3), cell) - &
2539 (
pbc(particle_set(j_atom)%r(1:3), cell) + cell_vector_j(1:3))
2540 abs_rab_cell_j = sqrt(rab_cell_j(1)**2 + rab_cell_j(2)**2 + rab_cell_j(3)**2)
2542 IF (abs_rab_cell_i > abs_rab_cell_j + 1.0e-6_dp)
THEN
2543 i_cell_is_the_minimum_image_cell = .false.
2547 IF (i_cell_is_the_minimum_image_cell)
THEN
2554 arg = real(index_to_cell(1, i_mic_cell),
dp)*kpoints%xkp(1, ikp) + &
2555 REAL(index_to_cell(2, i_mic_cell),
dp)*kpoints%xkp(2, ikp) + &
2556 REAL(index_to_cell(3, i_mic_cell),
dp)*kpoints%xkp(3, ikp)
2558 cfm_ikp%local_data(i_row, j_col) = cos(
twopi*arg)*fm_gamma%local_data(i_row, j_col)*
z_one + &
2559 sin(
twopi*arg)*fm_gamma%local_data(i_row, j_col)*
gaussi
2567 CALL timestop(handle)
2583 cfm_W_ikp_freq_j, ikp, kpoints, basis_type, wkp_ext)
2588 INTEGER,
INTENT(IN) :: ikp
2590 CHARACTER(LEN=*) :: basis_type
2591 REAL(kind=
dp),
OPTIONAL :: wkp_ext
2593 CHARACTER(LEN=*),
PARAMETER :: routinen =
'MIC_contribution_from_ikp'
2595 INTEGER :: handle, i_bf, iatom, iatom_old, irow, &
2596 j_bf, jatom, jatom_old, jcol, n_bf, &
2597 ncol_local, nrow_local, num_cells
2598 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf_index
2599 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2600 INTEGER,
DIMENSION(:, :),
POINTER :: index_to_cell
2601 REAL(kind=
dp) :: contribution, weight_im, weight_re, &
2603 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
2604 REAL(kind=
dp),
DIMENSION(:),
POINTER :: wkp
2605 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xkp
2609 CALL timeset(routinen, handle)
2612 IF (basis_type ==
"ORB")
THEN
2613 n_bf = qs_env%bs_env%n_ao
2614 ELSE IF (basis_type ==
"RI_AUX")
THEN
2615 n_bf = qs_env%bs_env%n_RI
2617 cpabort(
"Only ORB and RI_AUX basis implemented.")
2620 ALLOCATE (atom_from_bf_index(n_bf))
2623 NULLIFY (cell, particle_set)
2624 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
2628 nrow_local=nrow_local, &
2629 ncol_local=ncol_local, &
2630 row_indices=row_indices, &
2631 col_indices=col_indices)
2634 index_to_cell => kpoints%index_to_cell
2635 num_cells =
SIZE(index_to_cell, 2)
2640 DO jcol = 1, ncol_local
2641 DO irow = 1, nrow_local
2643 i_bf = row_indices(irow)
2644 j_bf = col_indices(jcol)
2646 iatom = atom_from_bf_index(i_bf)
2647 jatom = atom_from_bf_index(j_bf)
2649 IF (
PRESENT(wkp_ext))
THEN
2650 wkp_of_ikp = wkp_ext
2652 SELECT CASE (bs_env%l_RI(i_bf) + bs_env%l_RI(j_bf))
2655 wkp_of_ikp = wkp(ikp)
2658 wkp_of_ikp = bs_env%wkp_s_p(ikp)
2661 wkp_of_ikp = bs_env%wkp_no_extra(ikp)
2665 IF (iatom /= iatom_old .OR. jatom /= jatom_old)
THEN
2668 num_cells, iatom, jatom, xkp(1:3, ikp), wkp_of_ikp, &
2669 cell, index_to_cell, hmat, particle_set)
2676 contribution = weight_re*real(cfm_w_ikp_freq_j%local_data(irow, jcol)) + &
2677 weight_im*aimag(cfm_w_ikp_freq_j%local_data(irow, jcol))
2679 fm_w_mic_freq_j%local_data(irow, jcol) = fm_w_mic_freq_j%local_data(irow, jcol) &
2685 CALL timestop(handle)
2698 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xkp
2699 INTEGER :: ikp_start, ikp_end
2700 INTEGER,
DIMENSION(3) :: grid
2702 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_xkp'
2704 INTEGER :: handle, i, ix, iy, iz
2706 CALL timeset(routinen, handle)
2713 IF (i > ikp_end) cycle
2715 xkp(1, i) = real(2*ix - grid(1) - 1, kind=
dp)/(2._dp*real(grid(1), kind=
dp))
2716 xkp(2, i) = real(2*iy - grid(2) - 1, kind=
dp)/(2._dp*real(grid(2), kind=
dp))
2717 xkp(3, i) = real(2*iz - grid(3) - 1, kind=
dp)/(2._dp*real(grid(3), kind=
dp))
2724 CALL timestop(handle)
2738 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_init_cell_index_simple'
2740 INTEGER :: handle, nimages
2745 CALL timeset(routinen, handle)
2747 NULLIFY (para_env, sab_orb)
2748 CALL get_qs_env(qs_env=qs_env, para_env=para_env, sab_orb=sab_orb)
2751 CALL timestop(handle)
2760 SUBROUTINE soc(qs_env, bs_env)
2764 CHARACTER(LEN=*),
PARAMETER :: routinen =
'soc'
2768 CALL timeset(routinen, handle)
2776 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
2780 CALL h_ks_spinor_gamma(bs_env)
2785 CALL h_ks_spinor_kp(qs_env, bs_env)
2789 CALL timestop(handle)
2797 SUBROUTINE h_ks_spinor_gamma(bs_env)
2801 CHARACTER(LEN=*),
PARAMETER :: routinen =
'H_KS_spinor_Gamma'
2803 INTEGER :: handle, nao, s
2806 CALL timeset(routinen, handle)
2810 ALLOCATE (bs_env%cfm_SOC_spinor_ao(1))
2811 CALL create_cfm_double(bs_env%cfm_SOC_spinor_ao(1), fm_orig=bs_env%fm_ks_Gamma(1))
2814 str => bs_env%fm_ks_Gamma(1)%matrix_struct
2822 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(1, 1)%matrix, &
2823 str, 1, s,
z_one, .false.)
2825 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(1, 1)%matrix, &
2826 str, s, 1,
z_one, .false.)
2830 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(2, 1)%matrix, &
2831 str, 1, s,
gaussi, .false.)
2833 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(2, 1)%matrix, &
2834 str, s, 1, -
gaussi, .false.)
2838 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(3, 1)%matrix, &
2839 str, 1, 1,
z_one, .false.)
2841 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(3, 1)%matrix, &
2842 str, s, s, -
z_one, .false.)
2844 CALL timestop(handle)
2846 END SUBROUTINE h_ks_spinor_gamma
2853 SUBROUTINE h_ks_spinor_kp(qs_env, bs_env)
2857 CHARACTER(LEN=*),
PARAMETER :: routinen =
'H_KS_spinor_kp'
2859 INTEGER :: handle, i_dim, ikp, n_spin, &
2861 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index_scf
2862 REAL(kind=
dp),
DIMENSION(3) :: xkp
2869 CALL timeset(routinen, handle)
2871 nkp_bs_and_dos = bs_env%nkp_bs_and_DOS
2872 n_spin = bs_env%n_spin
2874 str => bs_env%cfm_ks_kp(1, 1)%matrix_struct
2876 CALL cp_cfm_create(cfm_v_soc_xyz_ikp, bs_env%cfm_work_mo%matrix_struct)
2878 CALL alloc_cfm_double_array_1d(bs_env%cfm_SOC_spinor_ao, bs_env%cfm_ks_kp(1, 1), nkp_bs_and_dos)
2883 CALL get_kpoint_info(kpoints_scf, sab_nl=sab_nl, cell_to_index=cell_to_index_scf)
2887 DO ikp = 1, nkp_bs_and_dos
2889 xkp(1:3) = bs_env%kpoints_DOS%xkp(1:3, ikp)
2893 CALL rsmat_to_kp(bs_env%mat_V_SOC_xyz, i_dim, xkp, cell_to_index_scf, &
2894 sab_nl, bs_env, cfm_v_soc_xyz_ikp, imag_rs_mat=.true.)
2902 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, 1, s)
2903 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, s, 1)
2907 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, 1, s)
2909 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, s, 1)
2912 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, 1, 1)
2914 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, s, s)
2923 CALL timestop(handle)
2925 END SUBROUTINE h_ks_spinor_kp
2933 SUBROUTINE alloc_cfm_double_array_1d(cfm_array, cfm_template, n)
2934 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: cfm_array
2938 CHARACTER(LEN=*),
PARAMETER :: routinen =
'alloc_cfm_double_array_1d'
2940 INTEGER :: handle, i
2942 CALL timeset(routinen, handle)
2944 ALLOCATE (cfm_array(n))
2950 CALL timestop(handle)
2952 END SUBROUTINE alloc_cfm_double_array_1d
2962 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_all_VBM_CBM_bandgaps'
2966 CALL timeset(routinen, handle)
2972 CALL timestop(handle)
2984 REAL(kind=
dp),
DIMENSION(:, :, :) :: ev
2987 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_VBM_CBM_bandgaps'
2989 INTEGER :: handle, homo, homo_1, homo_2, ikp, &
2990 ispin, lumo, lumo_1, lumo_2, n_mo
2991 REAL(kind=
dp) :: e_dbg_at_ikp
2993 CALL timeset(routinen, handle)
2997 band_edges%DBG = 1000.0_dp
2999 SELECT CASE (bs_env%n_spin)
3001 homo = bs_env%n_occ(1)
3003 band_edges%VBM = maxval(ev(1:homo, :, 1))
3004 band_edges%CBM = minval(ev(homo + 1:n_mo, :, 1))
3006 homo_1 = bs_env%n_occ(1)
3008 homo_2 = bs_env%n_occ(2)
3010 band_edges%VBM = max(maxval(ev(1:homo_1, :, 1)), maxval(ev(1:homo_2, :, 2)))
3011 band_edges%CBM = min(minval(ev(homo_1 + 1:n_mo, :, 1)), minval(ev(homo_2 + 1:n_mo, :, 2)))
3013 cpabort(
"Error with number of spins.")
3016 band_edges%IDBG = band_edges%CBM - band_edges%VBM
3018 DO ispin = 1, bs_env%n_spin
3020 homo = bs_env%n_occ(ispin)
3022 DO ikp = 1, bs_env%nkp_bs_and_DOS
3024 e_dbg_at_ikp = -maxval(ev(1:homo, ikp, ispin)) + minval(ev(homo + 1:n_mo, ikp, ispin))
3026 IF (e_dbg_at_ikp < band_edges%DBG) band_edges%DBG = e_dbg_at_ikp
3032 CALL timestop(handle)
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.
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(amatrix, bmatrix, eigenvectors, eigenvalues, work)
General Eigenvalue Problem AX = BXE Single option version: Cholesky decomposition of B.
subroutine, public cp_cfm_heevd(matrix, eigenvectors, eigenvalues)
Perform a diagonalisation of a complex matrix.
subroutine, public cp_cfm_geeig_canon(amatrix, bmatrix, eigenvectors, eigenvalues, work, epseig)
General Eigenvalue Problem AX = BXE Use canonical orthogonalization.
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)
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. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
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)
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_diag(matrix, diag)
returns the diagonal elements of a fm
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_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.
Defines the basic variable types.
integer, parameter, public max_line_length
integer, parameter, public dp
integer, parameter, public default_string_length
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)
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.
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
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 cfm_ikp_from_fm_gamma(cfm_ikp, fm_gamma, ikp, qs_env, kpoints, basis_type)
...
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, 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)
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
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.
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
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 ...