37 dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, dbcsr_type_symmetric
107#include "base/base_uses.f90"
118 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'post_scf_bandstructure_utils'
133 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_and_init_bs_env'
137 CALL timeset(routinen, handle)
141 CALL print_header(bs_env)
143 CALL read_bandstructure_input_parameters(bs_env, post_scf_bandstructure_section)
145 CALL get_parameters_from_qs_env(qs_env, bs_env)
147 CALL set_heuristic_parameters(bs_env)
149 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
152 CALL setup_kpoints_dos_large_cell_gamma(qs_env, bs_env, bs_env%kpoints_DOS)
154 CALL allocate_and_fill_fm_ks_fm_s(qs_env, bs_env)
156 CALL diagonalize_ks_matrix(bs_env)
158 CALL check_positive_definite_overlap_mat(bs_env, qs_env)
162 CALL setup_kpoints_scf_desymm(qs_env, bs_env, bs_env%kpoints_scf_desymm, .true.)
163 CALL setup_kpoints_scf_desymm(qs_env, bs_env, bs_env%kpoints_scf_desymm_2, .false.)
165 CALL setup_kpoints_dos_small_cell_full_kp(bs_env, bs_env%kpoints_DOS)
167 CALL allocate_and_fill_fm_ks_fm_s(qs_env, bs_env)
169 CALL compute_cfm_mo_coeff_kp_and_eigenval_scf_kp(qs_env, bs_env)
173 CALL timestop(handle)
182 SUBROUTINE read_bandstructure_input_parameters(bs_env, bs_sec)
186 CHARACTER(LEN=*),
PARAMETER :: routinen =
'read_bandstructure_input_parameters'
188 CHARACTER(LEN=default_string_length), &
189 DIMENSION(:),
POINTER :: string_ptr
190 CHARACTER(LEN=max_line_length) :: error_msg
191 INTEGER :: handle, i, ikp
194 CALL timeset(routinen, handle)
224 ALLOCATE (bs_env%xkp_special(3, bs_env%input_kp_bs_n_sp_pts))
225 DO ikp = 1, bs_env%input_kp_bs_n_sp_pts
227 cpassert(
SIZE(string_ptr(:), 1) == 4)
230 IF (len_trim(error_msg) > 0) cpabort(trim(error_msg))
234 CALL timestop(handle)
236 END SUBROUTINE read_bandstructure_input_parameters
242 SUBROUTINE print_header(bs_env)
246 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_header'
250 CALL timeset(routinen, handle)
257 WRITE (u,
'(T2,A)')
' '
258 WRITE (u,
'(T2,A)') repeat(
'-', 79)
259 WRITE (u,
'(T2,A,A78)')
'-',
'-'
260 WRITE (u,
'(T2,A,A51,A27)')
'-',
'BANDSTRUCTURE CALCULATION',
'-'
261 WRITE (u,
'(T2,A,A78)')
'-',
'-'
262 WRITE (u,
'(T2,A)') repeat(
'-', 79)
263 WRITE (u,
'(T2,A)')
' '
266 CALL timestop(handle)
268 END SUBROUTINE print_header
276 SUBROUTINE setup_kpoints_dos_large_cell_gamma(qs_env, bs_env, kpoints)
282 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_DOS_large_cell_Gamma'
284 INTEGER :: handle, i_dim, i_kp_in_line, &
285 i_special_kp, ikk, n_kp_in_line, &
286 n_special_kp, nkp, nkp_only_bs, &
288 INTEGER,
DIMENSION(3) :: nkp_grid, periodic
290 CALL timeset(routinen, handle)
296 kpoints%kp_scheme =
"GENERAL"
298 n_special_kp = bs_env%input_kp_bs_n_sp_pts
299 n_kp_in_line = bs_env%input_kp_bs_npoints
301 periodic(1:3) = bs_env%periodic(1:3)
305 cpassert(periodic(i_dim) == 0 .OR. periodic(i_dim) == 1)
307 IF (bs_env%nkp_grid_DOS_input(i_dim) < 0)
THEN
308 IF (periodic(i_dim) == 1) nkp_grid(i_dim) = 2
309 IF (periodic(i_dim) == 0) nkp_grid(i_dim) = 1
311 nkp_grid(i_dim) = bs_env%nkp_grid_DOS_input(i_dim)
317 IF (nkp_grid(1) > 1)
THEN
318 nkp_only_dos = (nkp_grid(1) + 1)/2*nkp_grid(2)*nkp_grid(3)
319 ELSE IF (nkp_grid(2) > 1)
THEN
320 nkp_only_dos = nkp_grid(1)*(nkp_grid(2) + 1)/2*nkp_grid(3)
321 ELSE IF (nkp_grid(3) > 1)
THEN
322 nkp_only_dos = nkp_grid(1)*nkp_grid(2)*(nkp_grid(3) + 1)/2
329 IF (n_special_kp > 0)
THEN
330 nkp_only_bs = n_kp_in_line*(n_special_kp - 1) + 1
335 nkp = nkp_only_dos + nkp_only_bs
337 kpoints%nkp_grid(1:3) = nkp_grid(1:3)
340 bs_env%nkp_bs_and_DOS = nkp
341 bs_env%nkp_only_bs = nkp_only_bs
342 bs_env%nkp_only_DOS = nkp_only_dos
344 ALLOCATE (kpoints%xkp(3, nkp), kpoints%wkp(nkp))
345 kpoints%wkp(1:nkp_only_dos) = 1.0_dp/real(nkp_only_dos, kind=
dp)
347 CALL compute_xkp(kpoints%xkp, 1, nkp_only_dos, nkp_grid)
349 IF (n_special_kp > 0)
THEN
350 kpoints%xkp(1:3, nkp_only_dos + 1) = bs_env%xkp_special(1:3, 1)
351 ikk = nkp_only_dos + 1
352 DO i_special_kp = 2, n_special_kp
353 DO i_kp_in_line = 1, n_kp_in_line
355 kpoints%xkp(1:3, ikk) = bs_env%xkp_special(1:3, i_special_kp - 1) + &
356 REAL(i_kp_in_line, kind=
dp)/real(n_kp_in_line, kind=
dp)* &
357 (bs_env%xkp_special(1:3, i_special_kp) - &
358 bs_env%xkp_special(1:3, i_special_kp - 1))
359 kpoints%wkp(ikk) = 0.0_dp
369 IF (nkp_only_bs > 0)
THEN
370 WRITE (u, fmt=
"(T2,1A,T77,I4)") &
371 "Number of special k-points for the bandstructure", n_special_kp
372 WRITE (u, fmt=
"(T2,1A,T77,I4)")
"Number of k-points for the bandstructure", nkp
373 WRITE (u, fmt=
"(T2,1A,T69,3I4)") &
374 "K-point mesh for the density of states (DOS)", nkp_grid(1:3)
376 WRITE (u, fmt=
"(T2,1A,T69,3I4)") &
377 "K-point mesh for the density of states (DOS) and the self-energy", nkp_grid(1:3)
381 CALL timestop(handle)
383 END SUBROUTINE setup_kpoints_dos_large_cell_gamma
392 SUBROUTINE setup_kpoints_scf_desymm(qs_env, bs_env, kpoints, do_print)
397 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_scf_desymm'
399 INTEGER :: handle, i_cell_x, i_dim, img, j_cell_y, &
400 k_cell_z, nimages, nkp, u
401 INTEGER,
DIMENSION(3) :: cell_grid, cixd, nkp_grid
406 CALL timeset(routinen, handle)
411 CALL get_qs_env(qs_env=qs_env, kpoints=kpoints_scf)
413 nkp_grid(1:3) = kpoints_scf%nkp_grid(1:3)
414 nkp = nkp_grid(1)*nkp_grid(2)*nkp_grid(3)
418 IF (bs_env%periodic(i_dim) == 1)
THEN
419 cpassert(nkp_grid(i_dim) .GE. 4)
423 kpoints%kp_scheme =
"GENERAL"
424 kpoints%nkp_grid(1:3) = nkp_grid(1:3)
426 bs_env%nkp_scf_desymm = nkp
428 ALLOCATE (kpoints%xkp(1:3, nkp))
431 ALLOCATE (kpoints%wkp(nkp))
432 kpoints%wkp(:) = 1.0_dp/real(nkp, kind=
dp)
436 cell_grid(1:3) = nkp_grid(1:3) -
modulo(nkp_grid(1:3) + 1, 2)
439 cixd(1:3) = cell_grid(1:3)/2
441 nimages = cell_grid(1)*cell_grid(2)*cell_grid(3)
443 bs_env%nimages_scf_desymm = nimages
444 bs_env%cell_grid_scf_desymm(1:3) = cell_grid(1:3)
446 IF (
ASSOCIATED(kpoints%index_to_cell))
DEALLOCATE (kpoints%index_to_cell)
447 IF (
ASSOCIATED(kpoints%cell_to_index))
DEALLOCATE (kpoints%cell_to_index)
449 ALLOCATE (kpoints%cell_to_index(-cixd(1):cixd(1), -cixd(2):cixd(2), -cixd(3):cixd(3)))
450 ALLOCATE (kpoints%index_to_cell(nimages, 3))
453 DO i_cell_x = -cixd(1), cixd(1)
454 DO j_cell_y = -cixd(2), cixd(2)
455 DO k_cell_z = -cixd(3), cixd(3)
457 kpoints%cell_to_index(i_cell_x, j_cell_y, k_cell_z) = img
458 kpoints%index_to_cell(img, 1:3) = (/i_cell_x, j_cell_y, k_cell_z/)
464 IF (u > 0 .AND. do_print)
THEN
465 WRITE (u, fmt=
"(T2,A,I49)") χΣ
"Number of cells for G, , W, ", nimages
468 CALL timestop(handle)
470 END SUBROUTINE setup_kpoints_scf_desymm
477 SUBROUTINE setup_kpoints_dos_small_cell_full_kp(bs_env, kpoints)
482 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_DOS_small_cell_full_kp'
484 INTEGER :: handle, i_kp_in_line, i_special_kp, ikk, &
485 n_kp_in_line, n_special_kp, nkp, &
486 nkp_only_bs, nkp_scf_desymm, u
488 CALL timeset(routinen, handle)
494 n_special_kp = bs_env%input_kp_bs_n_sp_pts
495 n_kp_in_line = bs_env%input_kp_bs_npoints
496 nkp_scf_desymm = bs_env%nkp_scf_desymm
500 IF (n_special_kp > 0)
THEN
501 nkp_only_bs = n_kp_in_line*(n_special_kp - 1) + 1
505 nkp = nkp_only_bs + nkp_scf_desymm
507 ALLOCATE (kpoints%xkp(3, nkp))
508 ALLOCATE (kpoints%wkp(nkp))
512 bs_env%nkp_bs_and_DOS = nkp
513 bs_env%nkp_only_bs = nkp_only_bs
514 bs_env%nkp_only_DOS = nkp_scf_desymm
516 kpoints%xkp(1:3, 1:nkp_scf_desymm) = bs_env%kpoints_scf_desymm%xkp(1:3, 1:nkp_scf_desymm)
517 kpoints%wkp(1:nkp_scf_desymm) = 1.0_dp/real(nkp_scf_desymm, kind=
dp)
519 IF (n_special_kp > 0)
THEN
520 kpoints%xkp(1:3, nkp_scf_desymm + 1) = bs_env%xkp_special(1:3, 1)
521 ikk = nkp_scf_desymm + 1
522 DO i_special_kp = 2, n_special_kp
523 DO i_kp_in_line = 1, n_kp_in_line
525 kpoints%xkp(1:3, ikk) = bs_env%xkp_special(1:3, i_special_kp - 1) + &
526 REAL(i_kp_in_line, kind=
dp)/real(n_kp_in_line, kind=
dp)* &
527 (bs_env%xkp_special(1:3, i_special_kp) - &
528 bs_env%xkp_special(1:3, i_special_kp - 1))
529 kpoints%wkp(ikk) = 0.0_dp
534 IF (
ASSOCIATED(kpoints%index_to_cell))
DEALLOCATE (kpoints%index_to_cell)
536 ALLOCATE (kpoints%index_to_cell(bs_env%nimages_scf_desymm, 3))
537 kpoints%index_to_cell(:, :) = bs_env%kpoints_scf_desymm%index_to_cell(:, :)
542 WRITE (u, fmt=
"(T2,1A,T77,I4)")
"Number of special k-points for the bandstructure", &
544 WRITE (u, fmt=
"(T2,1A,T77,I4)")
"Number of k-points for the bandstructure", nkp
547 CALL timestop(handle)
549 END SUBROUTINE setup_kpoints_dos_small_cell_full_kp
556 SUBROUTINE compute_cfm_mo_coeff_kp_and_eigenval_scf_kp(qs_env, bs_env)
560 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_cfm_mo_coeff_kp_and_eigenval_scf_kp'
562 INTEGER :: handle, ikp, ispin, nkp_bs_and_dos
563 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index_scf
564 REAL(kind=
dp) :: cbm, vbm
565 REAL(kind=
dp),
DIMENSION(3) :: xkp
567 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks, matrix_s
572 CALL timeset(routinen, handle)
575 matrix_ks_kp=matrix_ks, &
576 matrix_s_kp=matrix_s, &
580 CALL get_kpoint_info(kpoints_scf, sab_nl=sab_nl, cell_to_index=cell_to_index_scf)
584 CALL cp_cfm_create(cfm_mos, bs_env%cfm_work_mo%matrix_struct)
587 nkp_bs_and_dos = bs_env%nkp_bs_and_DOS
589 ALLOCATE (bs_env%eigenval_G0W0(bs_env%n_ao, nkp_bs_and_dos, bs_env%n_spin))
590 ALLOCATE (bs_env%eigenval_HF(bs_env%n_ao, nkp_bs_and_dos, bs_env%n_spin))
591 ALLOCATE (bs_env%cfm_mo_coeff_kp(nkp_bs_and_dos, bs_env%n_spin))
592 ALLOCATE (bs_env%cfm_ks_kp(nkp_bs_and_dos, bs_env%n_spin))
593 ALLOCATE (bs_env%cfm_s_kp(nkp_bs_and_dos))
594 DO ikp = 1, nkp_bs_and_dos
595 DO ispin = 1, bs_env%n_spin
596 CALL cp_cfm_create(bs_env%cfm_mo_coeff_kp(ikp, ispin), bs_env%cfm_work_mo%matrix_struct)
597 CALL cp_cfm_create(bs_env%cfm_ks_kp(ikp, ispin), bs_env%cfm_work_mo%matrix_struct)
599 CALL cp_cfm_create(bs_env%cfm_s_kp(ikp), bs_env%cfm_work_mo%matrix_struct)
602 DO ispin = 1, bs_env%n_spin
603 DO ikp = 1, nkp_bs_and_dos
605 xkp(1:3) = bs_env%kpoints_DOS%xkp(1:3, ikp)
608 CALL rsmat_to_kp(matrix_ks, ispin, xkp, cell_to_index_scf, sab_nl, bs_env, cfm_ks)
611 CALL rsmat_to_kp(matrix_s, 1, xkp, cell_to_index_scf, sab_nl, bs_env, cfm_s)
621 bs_env%eigenval_scf(:, ikp, ispin), &
622 bs_env%cfm_work_mo, bs_env%eps_eigval_mat_s)
626 CALL cp_cfm_to_cfm(cfm_mos, bs_env%cfm_mo_coeff_kp(ikp, ispin))
630 vbm = maxval(bs_env%eigenval_scf(bs_env%n_occ(ispin), :, ispin))
631 cbm = minval(bs_env%eigenval_scf(bs_env%n_occ(ispin) + 1, :, ispin))
633 bs_env%e_fermi(ispin) = 0.5_dp*(vbm + cbm)
643 CALL timestop(handle)
645 END SUBROUTINE compute_cfm_mo_coeff_kp_and_eigenval_scf_kp
658 SUBROUTINE rsmat_to_kp(mat_rs, ispin, xkp, cell_to_index_scf, sab_nl, bs_env, cfm_kp, imag_rs_mat)
661 REAL(kind=
dp),
DIMENSION(3) :: xkp
662 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index_scf
667 LOGICAL,
OPTIONAL :: imag_rs_mat
669 CHARACTER(LEN=*),
PARAMETER :: routinen =
'rsmat_to_kp'
672 LOGICAL :: imag_rs_mat_private
673 TYPE(
dbcsr_type),
POINTER :: cmat, nsmat, rmat
675 CALL timeset(routinen, handle)
677 ALLOCATE (rmat, cmat, nsmat)
679 imag_rs_mat_private = .false.
680 IF (
PRESENT(imag_rs_mat)) imag_rs_mat_private = imag_rs_mat
682 IF (imag_rs_mat_private)
THEN
683 CALL dbcsr_create(rmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_antisymmetric)
684 CALL dbcsr_create(cmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
686 CALL dbcsr_create(rmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
687 CALL dbcsr_create(cmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_antisymmetric)
689 CALL dbcsr_create(nsmat, template=mat_rs(1, 1)%matrix, matrix_type=dbcsr_type_no_symmetry)
695 CALL rskp_transform(rmatrix=rmat, cmatrix=cmat, rsmat=mat_rs, ispin=ispin, &
696 xkp=xkp, cell_to_index=cell_to_index_scf, sab_nl=sab_nl)
702 CALL cp_fm_to_cfm(bs_env%fm_work_mo(1), bs_env%fm_work_mo(2), cfm_kp)
708 CALL timestop(handle)
716 SUBROUTINE diagonalize_ks_matrix(bs_env)
719 CHARACTER(LEN=*),
PARAMETER :: routinen =
'diagonalize_ks_matrix'
721 INTEGER :: handle, ispin
722 REAL(kind=
dp) :: cbm, vbm
724 CALL timeset(routinen, handle)
726 ALLOCATE (bs_env%eigenval_scf_Gamma(bs_env%n_ao, bs_env%n_spin))
728 DO ispin = 1, bs_env%n_spin
731 CALL cp_fm_to_fm(bs_env%fm_ks_Gamma(ispin), bs_env%fm_work_mo(1))
732 CALL cp_fm_to_fm(bs_env%fm_s_Gamma, bs_env%fm_work_mo(2))
737 bs_env%fm_work_mo(2), &
738 bs_env%fm_mo_coeff_Gamma(ispin), &
739 bs_env%eigenval_scf_Gamma(:, ispin), &
740 bs_env%fm_work_mo(3), &
741 bs_env%eps_eigval_mat_s)
743 vbm = bs_env%eigenval_scf_Gamma(bs_env%n_occ(ispin), ispin)
744 cbm = bs_env%eigenval_scf_Gamma(bs_env%n_occ(ispin) + 1, ispin)
746 bs_env%band_edges_scf_Gamma(ispin)%VBM = vbm
747 bs_env%band_edges_scf_Gamma(ispin)%CBM = cbm
748 bs_env%e_fermi(ispin) = 0.5_dp*(vbm + cbm)
752 CALL timestop(handle)
754 END SUBROUTINE diagonalize_ks_matrix
761 SUBROUTINE check_positive_definite_overlap_mat(bs_env, qs_env)
765 CHARACTER(LEN=*),
PARAMETER :: routinen =
'check_positive_definite_overlap_mat'
767 INTEGER :: handle, ikp, info, u
770 CALL timeset(routinen, handle)
772 DO ikp = 1, bs_env%kpoints_DOS%nkp
776 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
783 IF (info .NE. 0)
THEN
787 WRITE (u, fmt=
"(T2,A)")
""
788 WRITE (u, fmt=
"(T2,A)")
"ERROR: The Cholesky decomposition "// &
789 "of the k-point overlap matrix failed. This is"
790 WRITE (u, fmt=
"(T2,A)")
"because the algorithm is "// &
791 "only correct in the limit of large cells. The cell of "
792 WRITE (u, fmt=
"(T2,A)")
"the calculation is too small. "// &
793 "Use MULTIPLE_UNIT_CELL to create a larger cell "
794 WRITE (u, fmt=
"(T2,A)")
"and to prevent this error."
797 CALL bs_env%para_env%sync()
798 cpabort(
"Please see information on the error above.")
806 CALL timestop(handle)
808 END SUBROUTINE check_positive_definite_overlap_mat
815 SUBROUTINE get_parameters_from_qs_env(qs_env, bs_env)
819 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_parameters_from_qs_env'
821 INTEGER :: color_sub, handle, homo, n_ao, n_atom, u
822 INTEGER,
DIMENSION(3) :: periodic
823 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
832 CALL timeset(routinen, handle)
835 dft_control=dft_control, &
836 scf_control=scf_control, &
839 bs_env%n_spin = dft_control%nspins
840 IF (bs_env%n_spin == 1) bs_env%spin_degeneracy = 2.0_dp
841 IF (bs_env%n_spin == 2) bs_env%spin_degeneracy = 1.0_dp
843 CALL get_mo_set(mo_set=mos(1), nao=n_ao, homo=homo)
845 bs_env%n_occ(1:2) = homo
846 bs_env%n_vir(1:2) = n_ao - homo
848 IF (bs_env%n_spin == 2)
THEN
850 bs_env%n_occ(2) = homo
851 bs_env%n_vir(2) = n_ao - homo
854 bs_env%eps_eigval_mat_s = scf_control%eps_eigval
859 ALLOCATE (bs_env%para_env)
860 CALL bs_env%para_env%from_split(para_env, color_sub)
862 CALL get_qs_env(qs_env, particle_set=particle_set)
864 n_atom =
SIZE(particle_set)
865 bs_env%n_atom = n_atom
868 CALL get_cell(cell=cell, periodic=periodic, h=hmat)
869 bs_env%periodic(1:3) = periodic(1:3)
870 bs_env%hmat(1:3, 1:3) = hmat
871 bs_env%nimages_scf = dft_control%nimages
872 IF (dft_control%nimages == 1)
THEN
874 ELSE IF (dft_control%nimages > 1)
THEN
877 cpabort(
"Wrong number of cells from DFT calculation.")
884 CALL section_vals_val_get(input,
"DFT%REAL_TIME_PROPAGATION%RTBSE%_SECTION_PARAMETERS_", i_val=bs_env%rtp_method)
887 WRITE (u, fmt=
"(T2,2A,T73,I8)")
"Number of occupied molecular orbitals (MOs) ", &
888 "= Number of occupied bands", homo
889 WRITE (u, fmt=
"(T2,2A,T73,I8)")
"Number of unoccupied (= virtual) MOs ", &
890 "= Number of unoccupied bands", n_ao - homo
891 WRITE (u, fmt=
"(T2,A,T73,I8)")
"Number of Gaussian basis functions for MOs", n_ao
893 WRITE (u, fmt=
"(T2,2A,T73,I8)")
"Number of cells considered in the DFT ", &
894 "calculation", bs_env%nimages_scf
898 CALL timestop(handle)
900 END SUBROUTINE get_parameters_from_qs_env
906 SUBROUTINE set_heuristic_parameters(bs_env)
909 CHARACTER(LEN=*),
PARAMETER :: routinen =
'set_heuristic_parameters'
913 CALL timeset(routinen, handle)
915 bs_env%n_bins_max_for_printing = 5000
917 CALL timestop(handle)
919 END SUBROUTINE set_heuristic_parameters
926 SUBROUTINE allocate_and_fill_fm_ks_fm_s(qs_env, bs_env)
930 CHARACTER(LEN=*),
PARAMETER :: routinen =
'allocate_and_fill_fm_ks_fm_s'
932 INTEGER :: handle, i_work, ispin
935 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks, matrix_s
938 CALL timeset(routinen, handle)
942 blacs_env=blacs_env, &
943 matrix_ks_kp=matrix_ks, &
944 matrix_s_kp=matrix_s)
948 ncol_global=bs_env%n_ao, para_env=para_env)
950 DO i_work = 1,
SIZE(bs_env%fm_work_mo)
960 DO ispin = 1, bs_env%n_spin
962 CALL copy_dbcsr_to_fm(matrix_ks(ispin, 1)%matrix, bs_env%fm_ks_Gamma(ispin))
963 CALL cp_fm_create(bs_env%fm_mo_coeff_Gamma(ispin), fm_struct)
968 NULLIFY (bs_env%mat_ao_ao%matrix)
969 ALLOCATE (bs_env%mat_ao_ao%matrix)
970 CALL dbcsr_create(bs_env%mat_ao_ao%matrix, template=matrix_s(1, 1)%matrix, &
971 matrix_type=dbcsr_type_no_symmetry)
973 ALLOCATE (bs_env%eigenval_scf(bs_env%n_ao, bs_env%nkp_bs_and_DOS, bs_env%n_spin))
975 CALL timestop(handle)
977 END SUBROUTINE allocate_and_fill_fm_ks_fm_s
988 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dos_pdos_ldos'
990 INTEGER :: handle, homo, homo_1, homo_2, &
991 homo_spinor, ikp, ikp_for_file, ispin, &
992 n_ao, n_e, nkind, nkp
993 LOGICAL :: is_bandstruc_kpoint, print_dos_kpoints, &
995 REAL(kind=
dp) :: broadening, e_max, e_max_g0w0, e_min, &
996 e_min_g0w0, e_total_window, &
997 energy_step_dos, energy_window_dos, t1
998 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos_g0w0, dos_g0w0_soc, dos_scf, dos_scf_soc, &
999 eigenval, eigenval_spinor, eigenval_spinor_g0w0, eigenval_spinor_no_soc
1000 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos_g0w0, pdos_g0w0_soc, pdos_scf, &
1001 pdos_scf_soc, proj_mo_on_kind
1002 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_g0w0_2d, ldos_scf_2d, &
1005 band_edges_scf, band_edges_scf_guess, &
1007 TYPE(
cp_cfm_type) :: cfm_ks_ikp, cfm_ks_ikp_spinor, cfm_mos_ikp_spinor, cfm_s_ikp, &
1008 cfm_s_ikp_copy, cfm_s_ikp_spinor, cfm_s_ikp_spinor_copy, cfm_soc_ikp_spinor, &
1009 cfm_spinor_wf_ikp, cfm_work_ikp, cfm_work_ikp_spinor
1012 CALL timeset(routinen, handle)
1016 energy_window_dos = bs_env%energy_window_DOS
1017 energy_step_dos = bs_env%energy_step_DOS
1018 broadening = bs_env%broadening_DOS
1021 IF (bs_env%do_gw .OR. &
1023 band_edges_scf = bs_env%band_edges_scf
1024 band_edges_scf_guess = band_edges_scf
1027 IF (bs_env%n_spin == 1)
THEN
1028 homo = bs_env%n_occ(1)
1029 band_edges_scf_guess%VBM = bs_env%eigenval_scf_Gamma(homo, 1)
1030 band_edges_scf_guess%CBM = bs_env%eigenval_scf_Gamma(homo + 1, 1)
1032 homo_1 = bs_env%n_occ(1)
1033 homo_2 = bs_env%n_occ(2)
1034 band_edges_scf_guess%VBM = max(bs_env%eigenval_scf_Gamma(homo_1, 1), &
1035 bs_env%eigenval_scf_Gamma(homo_2, 2))
1036 band_edges_scf_guess%CBM = min(bs_env%eigenval_scf_Gamma(homo_1 + 1, 1), &
1037 bs_env%eigenval_scf_Gamma(homo_2 + 1, 2))
1041 band_edges_scf%VBM = -1000.0_dp
1042 band_edges_scf%CBM = 1000.0_dp
1043 band_edges_scf%DBG = 1000.0_dp
1046 e_min = band_edges_scf_guess%VBM - 0.5_dp*energy_window_dos
1047 e_max = band_edges_scf_guess%CBM + 0.5_dp*energy_window_dos
1049 IF (bs_env%do_gw)
THEN
1050 band_edges_g0w0 = bs_env%band_edges_G0W0
1051 e_min_g0w0 = band_edges_g0w0%VBM - 0.5_dp*energy_window_dos
1052 e_max_g0w0 = band_edges_g0w0%CBM + 0.5_dp*energy_window_dos
1053 e_min = min(e_min, e_min_g0w0)
1054 e_max = max(e_max, e_max_g0w0)
1057 e_total_window = e_max - e_min
1059 n_e = int(e_total_window/energy_step_dos)
1061 ALLOCATE (dos_scf(n_e))
1063 ALLOCATE (dos_scf_soc(n_e))
1064 dos_scf_soc(:) = 0.0_dp
1068 ALLOCATE (pdos_scf(n_e, nkind))
1069 pdos_scf(:, :) = 0.0_dp
1070 ALLOCATE (pdos_scf_soc(n_e, nkind))
1071 pdos_scf_soc(:, :) = 0.0_dp
1073 ALLOCATE (proj_mo_on_kind(n_ao, nkind))
1074 proj_mo_on_kind(:, :) = 0.0_dp
1076 ALLOCATE (eigenval(n_ao))
1077 ALLOCATE (eigenval_spinor(2*n_ao))
1078 ALLOCATE (eigenval_spinor_no_soc(2*n_ao))
1079 ALLOCATE (eigenval_spinor_g0w0(2*n_ao))
1081 IF (bs_env%do_gw)
THEN
1083 ALLOCATE (dos_g0w0(n_e))
1084 dos_g0w0(:) = 0.0_dp
1085 ALLOCATE (dos_g0w0_soc(n_e))
1086 dos_g0w0_soc(:) = 0.0_dp
1088 ALLOCATE (pdos_g0w0(n_e, nkind))
1089 pdos_g0w0(:, :) = 0.0_dp
1090 ALLOCATE (pdos_g0w0_soc(n_e, nkind))
1091 pdos_g0w0_soc(:, :) = 0.0_dp
1095 CALL cp_cfm_create(cfm_mos_ikp(1), bs_env%fm_ks_Gamma(1)%matrix_struct)
1096 CALL cp_cfm_create(cfm_mos_ikp(2), bs_env%fm_ks_Gamma(1)%matrix_struct)
1097 CALL cp_cfm_create(cfm_work_ikp, bs_env%fm_ks_Gamma(1)%matrix_struct)
1098 CALL cp_cfm_create(cfm_s_ikp_copy, bs_env%fm_ks_Gamma(1)%matrix_struct)
1100 IF (bs_env%do_soc)
THEN
1102 CALL cp_cfm_create(cfm_mos_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1103 CALL cp_cfm_create(cfm_work_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1104 CALL cp_cfm_create(cfm_s_ikp_spinor_copy, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1105 CALL cp_cfm_create(cfm_ks_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1106 CALL cp_cfm_create(cfm_soc_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1107 CALL cp_cfm_create(cfm_s_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1108 CALL cp_cfm_create(cfm_spinor_wf_ikp, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1110 homo_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
1112 band_edges_scf_soc%VBM = -1000.0_dp
1113 band_edges_scf_soc%CBM = 1000.0_dp
1114 band_edges_scf_soc%DBG = 1000.0_dp
1116 IF (bs_env%do_gw)
THEN
1117 band_edges_g0w0_soc%VBM = -1000.0_dp
1118 band_edges_g0w0_soc%CBM = 1000.0_dp
1119 band_edges_g0w0_soc%DBG = 1000.0_dp
1122 IF (bs_env%unit_nr > 0)
THEN
1123 WRITE (bs_env%unit_nr,
'(A)')
''
1124 WRITE (bs_env%unit_nr,
'(T2,A,F43.1,A)')
'SOC requested, SOC energy window:', &
1125 bs_env%energy_window_soc*
evolt,
' eV'
1130 IF (bs_env%do_ldos)
THEN
1134 IF (bs_env%unit_nr > 0)
THEN
1135 WRITE (bs_env%unit_nr,
'(A)')
''
1139 CALL cp_cfm_create(cfm_ks_ikp, bs_env%cfm_ks_kp(1, 1)%matrix_struct)
1140 CALL cp_cfm_create(cfm_s_ikp, bs_env%cfm_ks_kp(1, 1)%matrix_struct)
1143 DO ikp = 1, bs_env%nkp_bs_and_DOS
1147 DO ispin = 1, bs_env%n_spin
1149 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
1154 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
1158 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
1162 CALL cp_cfm_geeig(cfm_ks_ikp, cfm_s_ikp_copy, cfm_mos_ikp(ispin), &
1163 eigenval, cfm_work_ikp)
1168 CALL cp_cfm_to_cfm(bs_env%cfm_ks_kp(ikp, ispin), cfm_ks_ikp)
1174 CALL cp_cfm_to_cfm(bs_env%cfm_mo_coeff_kp(ikp, ispin), cfm_mos_ikp(ispin))
1175 eigenval(:) = bs_env%eigenval_scf(:, ikp, ispin)
1181 CALL compute_proj_mo_on_kind(proj_mo_on_kind, qs_env, cfm_mos_ikp(ispin), cfm_s_ikp)
1184 CALL add_to_dos_pdos(dos_scf, pdos_scf, eigenval, ikp, bs_env, n_e, e_min, &
1186 IF (bs_env%do_gw)
THEN
1187 CALL add_to_dos_pdos(dos_g0w0, pdos_g0w0, bs_env%eigenval_G0W0(:, ikp, ispin), &
1188 ikp, bs_env, n_e, e_min, proj_mo_on_kind)
1191 IF (bs_env%do_ldos)
THEN
1192 CALL add_to_ldos_2d(ldos_scf_2d, qs_env, ikp, bs_env, cfm_mos_ikp(ispin), &
1193 eigenval(:), band_edges_scf_guess)
1195 IF (bs_env%do_gw)
THEN
1196 CALL add_to_ldos_2d(ldos_g0w0_2d, qs_env, ikp, bs_env, cfm_mos_ikp(ispin), &
1197 bs_env%eigenval_G0W0(:, ikp, 1), band_edges_g0w0)
1202 homo = bs_env%n_occ(ispin)
1204 band_edges_scf%VBM = max(band_edges_scf%VBM, eigenval(homo))
1205 band_edges_scf%CBM = min(band_edges_scf%CBM, eigenval(homo + 1))
1206 band_edges_scf%DBG = min(band_edges_scf%DBG, eigenval(homo + 1) - eigenval(homo))
1211 IF (bs_env%do_soc)
THEN
1214 print_dos_kpoints = (bs_env%nkp_only_bs .LE. 0)
1216 is_bandstruc_kpoint = (ikp > bs_env%nkp_only_DOS)
1217 print_ikp = print_dos_kpoints .OR. is_bandstruc_kpoint
1219 IF (print_dos_kpoints)
THEN
1220 nkp = bs_env%nkp_only_DOS
1223 nkp = bs_env%nkp_only_bs
1224 ikp_for_file = ikp - bs_env%nkp_only_DOS
1228 CALL soc_ev(bs_env, qs_env, ikp, bs_env%eigenval_scf, band_edges_scf, &
1229 e_min, cfm_mos_ikp, dos_scf_soc, pdos_scf_soc, &
1230 band_edges_scf_soc, eigenval_spinor, cfm_spinor_wf_ikp)
1232 IF (.NOT. bs_env%do_gw .AND. print_ikp)
THEN
1233 CALL write_soc_eigenvalues(eigenval_spinor, ikp_for_file, ikp, bs_env)
1236 IF (bs_env%do_ldos)
THEN
1237 CALL add_to_ldos_2d(ldos_scf_2d_soc, qs_env, ikp, bs_env, cfm_spinor_wf_ikp, &
1238 eigenval_spinor, band_edges_scf_guess, .true., cfm_work_ikp)
1241 IF (bs_env%do_gw)
THEN
1244 CALL soc_ev(bs_env, qs_env, ikp, bs_env%eigenval_G0W0, band_edges_g0w0, &
1245 e_min, cfm_mos_ikp, dos_g0w0_soc, pdos_g0w0_soc, &
1246 band_edges_g0w0_soc, eigenval_spinor_g0w0, cfm_spinor_wf_ikp)
1251 CALL write_soc_eigenvalues(eigenval_spinor, ikp_for_file, ikp, bs_env, &
1252 eigenval_spinor_g0w0)
1259 IF (bs_env%unit_nr > 0 .AND.
m_walltime() - t1 > 20.0_dp)
THEN
1260 WRITE (bs_env%unit_nr,
'(T2,A,T43,I5,A,I3,A,F7.1,A)') &
1261 'Compute DOS, LDOS for k-point ', ikp,
' /', bs_env%nkp_bs_and_DOS, &
1267 band_edges_scf%IDBG = band_edges_scf%CBM - band_edges_scf%VBM
1268 IF (bs_env%do_soc)
THEN
1269 band_edges_scf_soc%IDBG = band_edges_scf_soc%CBM - band_edges_scf_soc%VBM
1270 IF (bs_env%do_gw)
THEN
1271 band_edges_g0w0_soc%IDBG = band_edges_g0w0_soc%CBM - band_edges_g0w0_soc%VBM
1275 CALL write_band_edges(band_edges_scf,
"SCF", bs_env)
1276 CALL write_dos_pdos(dos_scf, pdos_scf, bs_env, qs_env,
"SCF", e_min, band_edges_scf%VBM)
1277 IF (bs_env%do_ldos)
THEN
1278 CALL print_ldos_main(ldos_scf_2d, bs_env, band_edges_scf,
"SCF")
1281 IF (bs_env%do_soc)
THEN
1282 CALL write_band_edges(band_edges_scf_soc,
"SCF+SOC", bs_env)
1283 CALL write_dos_pdos(dos_scf_soc, pdos_scf_soc, bs_env, qs_env,
"SCF_SOC", &
1284 e_min, band_edges_scf_soc%VBM)
1285 IF (bs_env%do_ldos)
THEN
1288 CALL print_ldos_main(ldos_scf_2d_soc, bs_env, band_edges_scf, &
1293 IF (bs_env%do_gw)
THEN
1294 CALL write_band_edges(band_edges_g0w0,
"G0W0", bs_env)
1295 CALL write_band_edges(bs_env%band_edges_HF,
"Hartree-Fock with SCF orbitals", bs_env)
1296 CALL write_dos_pdos(dos_g0w0, pdos_g0w0, bs_env, qs_env,
"G0W0", e_min, &
1297 band_edges_g0w0%VBM)
1298 IF (bs_env%do_ldos)
THEN
1299 CALL print_ldos_main(ldos_g0w0_2d, bs_env, band_edges_g0w0,
"G0W0")
1303 IF (bs_env%do_soc .AND. bs_env%do_gw)
THEN
1304 CALL write_band_edges(band_edges_g0w0_soc,
"G0W0+SOC", bs_env)
1305 CALL write_dos_pdos(dos_g0w0_soc, pdos_g0w0_soc, bs_env, qs_env,
"G0W0_SOC", e_min, &
1306 band_edges_g0w0_soc%VBM)
1324 CALL timestop(handle)
1335 SUBROUTINE print_ldos_main(LDOS_2d, bs_env, band_edges, scf_gw_soc)
1336 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d
1339 CHARACTER(LEN=*) :: scf_gw_soc
1341 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_LDOS_main'
1343 INTEGER :: handle, i_x, i_x_bin, i_x_end, i_x_end_bin, i_x_end_glob, i_x_start, &
1344 i_x_start_bin, i_x_start_glob, i_y, i_y_bin, i_y_end, i_y_end_bin, i_y_end_glob, &
1345 i_y_start, i_y_start_bin, i_y_start_glob, n_e
1346 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: n_sum_for_bins
1347 INTEGER,
DIMENSION(2) :: bin_mesh
1348 LOGICAL :: do_xy_bins
1349 REAL(kind=
dp) :: e_min, energy_step, energy_window
1350 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d_bins
1352 CALL timeset(routinen, handle)
1354 n_e =
SIZE(ldos_2d, 3)
1356 energy_window = bs_env%energy_window_DOS
1357 energy_step = bs_env%energy_step_DOS
1358 e_min = band_edges%VBM - 0.5_dp*energy_window
1360 bin_mesh(1:2) = bs_env%bin_mesh(1:2)
1361 do_xy_bins = (bin_mesh(1) > 0 .AND. bin_mesh(2) > 0)
1363 i_x_start = lbound(ldos_2d, 1)
1364 i_x_end = ubound(ldos_2d, 1)
1365 i_y_start = lbound(ldos_2d, 2)
1366 i_y_end = ubound(ldos_2d, 2)
1368 IF (do_xy_bins)
THEN
1370 i_x_end_bin = bin_mesh(1)
1372 i_y_end_bin = bin_mesh(2)
1374 i_x_start_bin = i_x_start
1375 i_x_end_bin = i_x_end
1376 i_y_start_bin = i_y_start
1377 i_y_end_bin = i_y_end
1380 ALLOCATE (ldos_2d_bins(i_x_start_bin:i_x_end_bin, i_y_start_bin:i_y_end_bin, n_e))
1381 ldos_2d_bins(:, :, :) = 0.0_dp
1383 IF (do_xy_bins)
THEN
1385 i_x_start_glob = i_x_start
1386 i_x_end_glob = i_x_end
1387 i_y_start_glob = i_y_start
1388 i_y_end_glob = i_y_end
1390 CALL bs_env%para_env%min(i_x_start_glob)
1391 CALL bs_env%para_env%max(i_x_end_glob)
1392 CALL bs_env%para_env%min(i_y_start_glob)
1393 CALL bs_env%para_env%max(i_y_end_glob)
1395 ALLOCATE (n_sum_for_bins(bin_mesh(1), bin_mesh(2)), source=0)
1398 DO i_y = i_y_start, i_y_end
1399 DO i_x = i_x_start, i_x_end
1400 i_x_bin = bin_mesh(1)*(i_x - i_x_start_glob)/(i_x_end_glob - i_x_start_glob + 1) + 1
1401 i_y_bin = bin_mesh(2)*(i_y - i_y_start_glob)/(i_y_end_glob - i_y_start_glob + 1) + 1
1402 ldos_2d_bins(i_x_bin, i_y_bin, :) = ldos_2d_bins(i_x_bin, i_y_bin, :) + &
1403 ldos_2d(i_x, i_y, :)
1404 n_sum_for_bins(i_x_bin, i_y_bin) = n_sum_for_bins(i_x_bin, i_y_bin) + 1
1408 CALL bs_env%para_env%sum(ldos_2d_bins)
1409 CALL bs_env%para_env%sum(n_sum_for_bins)
1412 DO i_y_bin = 1, bin_mesh(2)
1413 DO i_x_bin = 1, bin_mesh(1)
1414 ldos_2d_bins(i_x_bin, i_y_bin, :) = ldos_2d_bins(i_x_bin, i_y_bin, :)/ &
1415 REAL(n_sum_for_bins(i_x_bin, i_y_bin), kind=
dp)
1421 ldos_2d_bins(:, :, :) = ldos_2d(:, :, :)
1425 IF (bin_mesh(1)*bin_mesh(2) < bs_env%n_bins_max_for_printing)
THEN
1426 CALL print_ldos_2d_bins(ldos_2d_bins, bs_env, e_min, scf_gw_soc)
1428 cpwarn(
"The number of bins for the LDOS is too large. Decrease BIN_MESH.")
1431 CALL timestop(handle)
1433 END SUBROUTINE print_ldos_main
1442 SUBROUTINE print_ldos_2d_bins(LDOS_2d_bins, bs_env, E_min, scf_gw_soc)
1443 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d_bins
1445 REAL(kind=
dp) :: e_min
1446 CHARACTER(LEN=*) :: scf_gw_soc
1448 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_LDOS_2d_bins'
1450 CHARACTER(LEN=18) :: print_format
1451 CHARACTER(LEN=4) :: print_format_1, print_format_2
1452 CHARACTER(len=default_string_length) :: fname
1453 INTEGER :: handle, i_e, i_x, i_x_end, i_x_start, &
1454 i_y, i_y_end, i_y_start, iunit, n_e, &
1456 REAL(kind=
dp) :: energy
1457 REAL(kind=
dp),
DIMENSION(3) :: coord,
idx
1459 CALL timeset(routinen, handle)
1461 i_x_start = lbound(ldos_2d_bins, 1)
1462 i_x_end = ubound(ldos_2d_bins, 1)
1463 i_y_start = lbound(ldos_2d_bins, 2)
1464 i_y_end = ubound(ldos_2d_bins, 2)
1465 n_e =
SIZE(ldos_2d_bins, 3)
1467 n_x = i_x_end - i_x_start + 1
1468 n_y = i_y_end - i_y_start + 1
1470 IF (bs_env%para_env%is_source())
THEN
1472 DO i_y = i_y_start, i_y_end
1473 DO i_x = i_x_start, i_x_end
1475 idx(1) = (real(i_x, kind=
dp) - 0.5_dp)/real(n_x, kind=
dp)
1476 idx(2) = (real(i_y, kind=
dp) - 0.5_dp)/real(n_y, kind=
dp)
1478 coord(1:3) = matmul(bs_env%hmat,
idx)
1480 CALL get_print_format(coord(1), print_format_1)
1481 CALL get_print_format(coord(2), print_format_2)
1483 print_format =
"(3A,"//print_format_1//
",A,"//print_format_2//
",A)"
1485 WRITE (fname, print_format)
"LDOS_", scf_gw_soc, &
1488 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", &
1489 file_action=
"WRITE")
1491 WRITE (iunit,
"(2A)") Å
" Energy E (eV) average LDOS(x,y,E) (1/(eV*^2), ", &
1492 "integrated over z, averaged inside bin)"
1495 energy = e_min + i_e*bs_env%energy_step_DOS
1496 WRITE (iunit,
"(2F17.3)") energy*
evolt, &
1497 ldos_2d_bins(i_x, i_y, i_e)* &
1498 bs_env%unit_ldos_int_z_inv_Ang2_eV
1508 CALL timestop(handle)
1510 END SUBROUTINE print_ldos_2d_bins
1517 SUBROUTINE get_print_format(coord, print_format)
1518 REAL(kind=
dp) :: coord
1519 CHARACTER(LEN=4) :: print_format
1521 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_print_format'
1525 CALL timeset(routinen, handle)
1528 print_format =
"F9.2"
1529 ELSE IF (coord < -1000/
angstrom)
THEN
1530 print_format =
"F8.2"
1531 ELSE IF (coord < -100/
angstrom)
THEN
1532 print_format =
"F7.2"
1533 ELSE IF (coord < -10/
angstrom)
THEN
1534 print_format =
"F6.2"
1536 print_format =
"F5.2"
1538 print_format =
"F4.2"
1539 ELSE IF (coord < 100/
angstrom)
THEN
1540 print_format =
"F5.2"
1541 ELSE IF (coord < 1000/
angstrom)
THEN
1542 print_format =
"F6.2"
1543 ELSE IF (coord < 10000/
angstrom)
THEN
1544 print_format =
"F7.2"
1546 print_format =
"F8.2"
1549 CALL timestop(handle)
1551 END SUBROUTINE get_print_format
1568 SUBROUTINE soc_ev(bs_env, qs_env, ikp, eigenval_no_SOC, band_edges_no_SOC, E_min, cfm_mos_ikp, &
1569 DOS, PDOS, band_edges, eigenval_spinor, cfm_spinor_wf_ikp)
1574 REAL(kind=
dp),
DIMENSION(:, :, :) :: eigenval_no_soc
1576 REAL(kind=
dp) :: e_min
1578 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos
1579 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
1581 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor
1584 CHARACTER(LEN=*),
PARAMETER :: routinen =
'SOC_ev'
1586 INTEGER :: handle, homo_spinor, n_ao, n_e, nkind
1587 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor_no_soc
1588 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind_spinor
1590 cfm_ks_ikp_spinor, cfm_mos_ikp_spinor, &
1591 cfm_soc_ikp_spinor, cfm_work_ikp_spinor
1593 CALL timeset(routinen, handle)
1596 homo_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
1598 nkind =
SIZE(pdos, 2)
1600 CALL cp_cfm_create(cfm_ks_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1601 CALL cp_cfm_create(cfm_soc_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1602 CALL cp_cfm_create(cfm_mos_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1603 CALL cp_cfm_create(cfm_work_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1604 CALL cp_cfm_create(cfm_eigenvec_ikp_spinor, bs_env%cfm_SOC_spinor_ao(1)%matrix_struct)
1606 ALLOCATE (eigenval_spinor_no_soc(2*n_ao))
1607 ALLOCATE (proj_mo_on_kind_spinor(2*n_ao, nkind))
1609 proj_mo_on_kind_spinor(:, :) = 0.0_dp
1612 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
1616 CALL cfm_ikp_from_cfm_spinor_gamma(cfm_soc_ikp_spinor, &
1617 bs_env%cfm_SOC_spinor_ao(1), &
1618 bs_env%fm_s_Gamma%matrix_struct, &
1619 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
1624 CALL cp_cfm_to_cfm(bs_env%cfm_SOC_spinor_ao(ikp), cfm_soc_ikp_spinor)
1634 CALL add_cfm_submat(cfm_mos_ikp_spinor, cfm_mos_ikp(bs_env%n_spin), n_ao + 1, n_ao + 1)
1638 cfm_mos_ikp_spinor, cfm_soc_ikp_spinor, &
1639 z_zero, cfm_work_ikp_spinor)
1643 cfm_work_ikp_spinor, cfm_mos_ikp_spinor, &
1644 z_zero, cfm_ks_ikp_spinor)
1649 eigenval_spinor_no_soc(1:n_ao) = eigenval_no_soc(1:n_ao, ikp, 1)
1650 eigenval_spinor_no_soc(n_ao + 1:) = eigenval_no_soc(1:n_ao, ikp, bs_env%n_spin)
1651 IF (bs_env%energy_window_soc > 0.0_dp)
THEN
1653 bs_env%energy_window_soc, &
1654 eigenval_spinor_no_soc, &
1655 band_edges_no_soc%VBM, &
1656 band_edges_no_soc%CBM)
1663 CALL cp_cfm_heevd(cfm_ks_ikp_spinor, cfm_eigenvec_ikp_spinor, eigenval_spinor)
1666 CALL add_to_dos_pdos(dos, pdos, eigenval_spinor, &
1667 ikp, bs_env, n_e, e_min, proj_mo_on_kind_spinor)
1670 band_edges%VBM = max(band_edges%VBM, eigenval_spinor(homo_spinor))
1671 band_edges%CBM = min(band_edges%CBM, eigenval_spinor(homo_spinor + 1))
1672 band_edges%DBG = min(band_edges%DBG, eigenval_spinor(homo_spinor + 1) &
1673 - eigenval_spinor(homo_spinor))
1677 cfm_mos_ikp_spinor, cfm_eigenvec_ikp_spinor, &
1678 z_zero, cfm_spinor_wf_ikp)
1686 CALL timestop(handle)
1688 END SUBROUTINE soc_ev
1701 SUBROUTINE add_to_dos_pdos(DOS, PDOS, eigenval, ikp, bs_env, n_E, E_min, proj_mo_on_kind)
1703 REAL(kind=
dp),
DIMENSION(:) :: dos
1704 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
1705 REAL(kind=
dp),
DIMENSION(:) :: eigenval
1709 REAL(kind=
dp) :: e_min
1710 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind
1712 CHARACTER(LEN=*),
PARAMETER :: routinen =
'add_to_DOS_PDOS'
1714 INTEGER :: handle, i_e, i_kind, i_mo, n_mo, nkind
1715 REAL(kind=
dp) :: broadening, energy, energy_step_dos, wkp
1717 CALL timeset(routinen, handle)
1719 energy_step_dos = bs_env%energy_step_DOS
1720 broadening = bs_env%broadening_DOS
1722 n_mo =
SIZE(eigenval)
1723 nkind =
SIZE(proj_mo_on_kind, 2)
1726 wkp = bs_env%kpoints_DOS%wkp(ikp)*bs_env%spin_degeneracy
1728 energy = e_min + i_e*energy_step_dos
1731 dos(i_e) = dos(i_e) + wkp*
gaussian(energy - eigenval(i_mo), broadening)
1734 DO i_kind = 1, nkind
1735 IF (proj_mo_on_kind(i_mo, i_kind) > 0.0_dp)
THEN
1736 pdos(i_e, i_kind) = pdos(i_e, i_kind) + &
1737 proj_mo_on_kind(i_mo, i_kind)*wkp* &
1738 gaussian(energy - eigenval(i_mo), broadening)
1744 CALL timestop(handle)
1746 END SUBROUTINE add_to_dos_pdos
1760 SUBROUTINE add_to_ldos_2d(LDOS_2d, qs_env, ikp, bs_env, cfm_mos_ikp, eigenval, &
1761 band_edges, do_spinor, cfm_non_spinor)
1762 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d
1767 REAL(kind=
dp),
DIMENSION(:) :: eigenval
1769 LOGICAL,
OPTIONAL :: do_spinor
1772 CHARACTER(LEN=*),
PARAMETER :: routinen =
'add_to_LDOS_2d'
1774 INTEGER :: handle, i_e, i_x_end, i_x_start, i_y_end, i_y_start, i_z, i_z_end, i_z_start, &
1775 j_col, j_mo, n_e, n_mo, n_z, ncol_local, nimages, z_end_global, z_start_global
1776 INTEGER,
DIMENSION(:),
POINTER :: col_indices
1777 LOGICAL :: is_any_weight_non_zero, my_do_spinor
1778 REAL(kind=
dp) :: broadening, e_max, e_min, &
1779 e_total_window, energy, energy_step, &
1780 energy_window, spin_degeneracy, weight
1781 TYPE(
cp_cfm_type) :: cfm_weighted_dm_ikp, cfm_work
1782 TYPE(
cp_fm_type) :: fm_non_spinor, fm_weighted_dm_mic
1783 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: weighted_dm_mic
1791 CALL timeset(routinen, handle)
1793 my_do_spinor = .false.
1794 IF (
PRESENT(do_spinor)) my_do_spinor = do_spinor
1796 CALL get_qs_env(qs_env, ks_env=ks_env, pw_env=pw_env, dft_control=dft_control)
1799 nimages = dft_control%nimages
1800 dft_control%nimages = bs_env%nimages_scf
1802 energy_window = bs_env%energy_window_DOS
1803 energy_step = bs_env%energy_step_DOS
1804 broadening = bs_env%broadening_DOS
1806 e_min = band_edges%VBM - 0.5_dp*energy_window
1807 e_max = band_edges%CBM + 0.5_dp*energy_window
1808 e_total_window = e_max - e_min
1810 n_e = int(e_total_window/energy_step)
1812 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1814 CALL auxbas_pw_pool%create_pw(ldos_3d)
1815 CALL auxbas_pw_pool%create_pw(rho_g)
1817 i_x_start = lbound(ldos_3d%array, 1)
1818 i_x_end = ubound(ldos_3d%array, 1)
1819 i_y_start = lbound(ldos_3d%array, 2)
1820 i_y_end = ubound(ldos_3d%array, 2)
1821 i_z_start = lbound(ldos_3d%array, 3)
1822 i_z_end = ubound(ldos_3d%array, 3)
1824 z_start_global = i_z_start
1825 z_end_global = i_z_end
1827 CALL bs_env%para_env%min(z_start_global)
1828 CALL bs_env%para_env%max(z_end_global)
1829 n_z = z_end_global - z_start_global + 1
1831 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)) &
1832 cpabort(°
"Please choose a cell that has 90 angles to the z-direction.")
1834 bs_env%unit_ldos_int_z_inv_Ang2_eV = bs_env%hmat(3, 3)/real(n_z, kind=
dp)/
evolt/
angstrom**2
1837 ALLOCATE (ldos_2d(i_x_start:i_x_end, i_y_start:i_y_end, n_e))
1838 ldos_2d(:, :, :) = 0.0_dp
1842 CALL cp_cfm_create(cfm_weighted_dm_ikp, cfm_mos_ikp%matrix_struct)
1843 CALL cp_fm_create(fm_weighted_dm_mic, cfm_mos_ikp%matrix_struct)
1844 IF (my_do_spinor)
THEN
1845 CALL cp_fm_create(fm_non_spinor, cfm_non_spinor%matrix_struct)
1850 ncol_local=ncol_local, &
1851 col_indices=col_indices)
1853 NULLIFY (weighted_dm_mic)
1855 ALLOCATE (weighted_dm_mic(1)%matrix)
1856 CALL dbcsr_create(weighted_dm_mic(1)%matrix, template=bs_env%mat_ao_ao%matrix, &
1857 matrix_type=dbcsr_type_symmetric)
1861 energy = e_min + i_e*energy_step
1863 is_any_weight_non_zero = .false.
1865 DO j_col = 1, ncol_local
1867 j_mo = col_indices(j_col)
1869 IF (my_do_spinor)
THEN
1870 spin_degeneracy = 1.0_dp
1872 spin_degeneracy = bs_env%spin_degeneracy
1875 weight =
gaussian(energy - eigenval(j_mo), broadening)*spin_degeneracy
1877 cfm_work%local_data(:, j_col) = cfm_mos_ikp%local_data(:, j_col)*weight
1879 IF (weight > 1.0e-5_dp) is_any_weight_non_zero = .true.
1883 CALL bs_env%para_env%sync()
1884 CALL bs_env%para_env%sum(is_any_weight_non_zero)
1885 CALL bs_env%para_env%sync()
1888 IF (is_any_weight_non_zero)
THEN
1891 cfm_mos_ikp, cfm_work,
z_zero, cfm_weighted_dm_ikp)
1893 IF (my_do_spinor)
THEN
1899 cfm_non_spinor, ikp, bs_env%kpoints_DOS, &
1900 "ORB", bs_env%kpoints_DOS%wkp(ikp))
1903 CALL get_cfm_submat(cfm_non_spinor, cfm_weighted_dm_ikp, n_mo/2, n_mo/2)
1905 cfm_non_spinor, ikp, bs_env%kpoints_DOS, &
1906 "ORB", bs_env%kpoints_DOS%wkp(ikp))
1908 keep_sparsity=.false.)
1912 cfm_weighted_dm_ikp, ikp, bs_env%kpoints_DOS, &
1913 "ORB", bs_env%kpoints_DOS%wkp(ikp))
1915 keep_sparsity=.false.)
1918 ldos_3d%array(:, :, :) = 0.0_dp
1925 DO i_z = i_z_start, i_z_end
1926 ldos_2d(:, :, i_e) = ldos_2d(:, :, i_e) + ldos_3d%array(:, :, i_z)
1934 dft_control%nimages = nimages
1936 CALL auxbas_pw_pool%give_back_pw(ldos_3d)
1937 CALL auxbas_pw_pool%give_back_pw(rho_g)
1946 IF (my_do_spinor)
THEN
1950 CALL timestop(handle)
1952 END SUBROUTINE add_to_ldos_2d
1962 SUBROUTINE write_soc_eigenvalues(eigenval_spinor, ikp_for_file, ikp, bs_env, eigenval_spinor_G0W0)
1964 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor
1965 INTEGER :: ikp_for_file, ikp
1967 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: eigenval_spinor_g0w0
1969 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_SOC_eigenvalues'
1971 CHARACTER(len=3) :: occ_vir
1972 CHARACTER(LEN=default_string_length) :: fname
1973 INTEGER :: handle, i_mo, iunit, n_occ_spinor
1975 CALL timeset(routinen, handle)
1977 fname =
"bandstructure_SCF_and_G0W0_plus_SOC"
1979 IF (bs_env%para_env%is_source())
THEN
1981 IF (ikp_for_file == 1)
THEN
1982 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", &
1983 file_action=
"WRITE")
1985 CALL open_file(trim(fname), unit_number=iunit, file_status=
"OLD", &
1986 file_action=
"WRITE", file_position=
"APPEND")
1989 WRITE (iunit,
"(A)")
" "
1990 WRITE (iunit,
"(A10,I7,A25,3F10.4)")
"kpoint: ", ikp_for_file,
"coordinate: ", &
1991 bs_env%kpoints_DOS%xkp(:, ikp)
1992 WRITE (iunit,
"(A)")
" "
1994 IF (
PRESENT(eigenval_spinor_g0w0))
THEN
1996 WRITE (iunit,
"(A5,A12,2A22)")
"n",
"k", ϵ
"_nk^DFT+SOC (eV)", ϵ
"_nk^G0W0+SOC (eV)"
1999 WRITE (iunit,
"(A5,A12,A22)")
"n",
"k", ϵ
"_nk^DFT+SOC (eV)"
2002 n_occ_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
2004 DO i_mo = 1,
SIZE(eigenval_spinor)
2005 IF (i_mo .LE. n_occ_spinor) occ_vir =
'occ'
2006 IF (i_mo > n_occ_spinor) occ_vir =
'vir'
2007 IF (
PRESENT(eigenval_spinor_g0w0))
THEN
2009 WRITE (iunit,
"(I5,3A,I5,4F16.3,2F17.3)") i_mo,
' (', occ_vir,
') ', &
2010 ikp_for_file, eigenval_spinor(i_mo)*
evolt, eigenval_spinor_g0w0(i_mo)*
evolt
2013 WRITE (iunit,
"(I5,3A,I5,4F16.3,F17.3)") i_mo,
' (', occ_vir,
') ', &
2014 ikp_for_file, eigenval_spinor(i_mo)*
evolt
2022 CALL timestop(handle)
2024 END SUBROUTINE write_soc_eigenvalues
2031 PURE FUNCTION count_digits(int_number)
2033 INTEGER,
INTENT(IN) :: int_number
2034 INTEGER :: count_digits
2036 INTEGER :: digitcount, tempint
2040 tempint = int_number
2042 DO WHILE (tempint /= 0)
2043 tempint = tempint/10
2044 digitcount = digitcount + 1
2047 count_digits = digitcount
2049 END FUNCTION count_digits
2057 SUBROUTINE write_band_edges(band_edges, scf_gw_soc, bs_env)
2060 CHARACTER(LEN=*) :: scf_gw_soc
2063 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_band_edges'
2065 CHARACTER(LEN=17) :: print_format
2066 INTEGER :: handle, u
2068 CALL timeset(routinen, handle)
2071 print_format =
"(T2,2A,T61,F20.3)"
2075 WRITE (u,
'(T2,A)')
''
2076 WRITE (u, print_format) scf_gw_soc,
' valence band maximum (eV):', band_edges%VBM*
evolt
2077 WRITE (u, print_format) scf_gw_soc,
' conduction band minimum (eV):', band_edges%CBM*
evolt
2078 WRITE (u, print_format) scf_gw_soc,
' indirect band gap (eV):', band_edges%IDBG*
evolt
2079 WRITE (u, print_format) scf_gw_soc,
' direct band gap (eV):', band_edges%DBG*
evolt
2082 CALL timestop(handle)
2084 END SUBROUTINE write_band_edges
2096 SUBROUTINE write_dos_pdos(DOS, PDOS, bs_env, qs_env, scf_gw_soc, E_min, E_VBM)
2097 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos
2098 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
2101 CHARACTER(LEN=*) :: scf_gw_soc
2102 REAL(kind=
dp) :: e_min, e_vbm
2104 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_dos_pdos'
2106 CHARACTER(LEN=3),
DIMENSION(100) :: elements
2107 CHARACTER(LEN=default_string_length) :: atom_name, fname, output_string
2108 INTEGER :: handle, i_e, i_kind, iatom, iunit, n_a, &
2110 REAL(kind=
dp) :: energy
2113 CALL timeset(routinen, handle)
2115 WRITE (fname,
"(3A)")
"DOS_PDOS_", scf_gw_soc,
".out"
2118 nkind =
SIZE(pdos, 2)
2119 CALL get_qs_env(qs_env, particle_set=particle_set)
2121 IF (bs_env%para_env%is_source())
THEN
2123 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", file_action=
"WRITE")
2127 DO iatom = 1, bs_env%n_atom
2129 kind_number=i_kind, name=atom_name)
2130 elements(i_kind) = atom_name(1:3)
2133 WRITE (output_string,
"(A,I1,A)")
"(", n_a,
"A)"
2135 WRITE (iunit, trim(output_string))
"Energy-E_F (eV) DOS (1/eV) PDOS (1/eV) ", &
2136 " of atom type ", elements(1:nkind)
2138 WRITE (output_string,
"(A,I1,A)")
"(", n_a,
"F13.5)"
2142 energy = e_min + i_e*bs_env%energy_step_DOS - e_vbm
2143 WRITE (iunit, trim(output_string)) energy*
evolt, dos(i_e)/
evolt, pdos(i_e, :)/
evolt
2150 CALL timestop(handle)
2152 END SUBROUTINE write_dos_pdos
2160 PURE FUNCTION gaussian(energy, broadening)
2162 REAL(kind=
dp),
INTENT(IN) :: energy, broadening
2165 IF (abs(energy) < 5*broadening)
THEN
2166 gaussian = 1.0_dp/broadening/sqrt(
twopi)*exp(-0.5_dp*energy**2/broadening**2)
2180 SUBROUTINE compute_proj_mo_on_kind(proj_mo_on_kind, qs_env, cfm_mos, cfm_s)
2181 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind
2185 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_proj_mo_on_kind'
2187 INTEGER :: handle, i_atom, i_global, i_kind, i_row, &
2188 j_col, n_ao, n_mo, ncol_local, nkind, &
2190 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf, kind_of
2191 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2193 TYPE(
cp_cfm_type) :: cfm_proj, cfm_s_i_kind, cfm_work
2196 CALL timeset(routinen, handle)
2198 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, nkind=nkind)
2203 nrow_local=nrow_local, &
2204 ncol_local=ncol_local, &
2205 row_indices=row_indices, &
2206 col_indices=col_indices)
2208 n_ao = qs_env%bs_env%n_ao
2210 ALLOCATE (atom_from_bf(n_ao))
2213 proj_mo_on_kind(:, :) = 0.0_dp
2221 DO i_kind = 1, nkind
2226 DO j_col = 1, ncol_local
2227 DO i_row = 1, nrow_local
2229 i_global = row_indices(i_row)
2231 IF (i_global .LE. n_ao)
THEN
2232 i_atom = atom_from_bf(i_global)
2233 ELSE IF (i_global .LE. 2*n_ao)
THEN
2234 i_atom = atom_from_bf(i_global - n_ao)
2236 cpabort(
"Wrong indices.")
2239 IF (i_kind .NE. kind_of(i_atom))
THEN
2240 cfm_s_i_kind%local_data(i_row, j_col) =
z_zero
2247 cfm_s_i_kind, cfm_mos,
z_zero, cfm_work)
2249 cfm_mos, cfm_work,
z_zero, cfm_proj)
2264 CALL timestop(handle)
2266 END SUBROUTINE compute_proj_mo_on_kind
2278 SUBROUTINE cfm_ikp_from_cfm_spinor_gamma(cfm_spinor_ikp, cfm_spinor_Gamma, fm_struct_non_spinor, &
2279 ikp, qs_env, kpoints, basis_type)
2280 TYPE(
cp_cfm_type) :: cfm_spinor_ikp, cfm_spinor_gamma
2285 CHARACTER(LEN=*) :: basis_type
2287 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cfm_ikp_from_cfm_spinor_Gamma'
2289 INTEGER :: handle, i_block, i_offset, j_block, &
2291 TYPE(
cp_cfm_type) :: cfm_non_spinor_gamma, cfm_non_spinor_ikp
2292 TYPE(
cp_fm_type) :: fm_non_spinor_gamma_im, &
2293 fm_non_spinor_gamma_re
2295 CALL timeset(routinen, handle)
2297 CALL cp_cfm_create(cfm_non_spinor_gamma, fm_struct_non_spinor)
2298 CALL cp_cfm_create(cfm_non_spinor_ikp, fm_struct_non_spinor)
2299 CALL cp_fm_create(fm_non_spinor_gamma_re, fm_struct_non_spinor)
2300 CALL cp_fm_create(fm_non_spinor_gamma_im, fm_struct_non_spinor)
2308 i_offset = i_block*n_ao + 1
2309 j_offset = j_block*n_ao + 1
2310 CALL get_cfm_submat(cfm_non_spinor_gamma, cfm_spinor_gamma, i_offset, j_offset)
2311 CALL cp_cfm_to_fm(cfm_non_spinor_gamma, fm_non_spinor_gamma_re, fm_non_spinor_gamma_im)
2315 ikp, qs_env, kpoints, basis_type)
2316 CALL add_cfm_submat(cfm_spinor_ikp, cfm_non_spinor_ikp, i_offset, j_offset)
2320 ikp, qs_env, kpoints, basis_type)
2331 CALL timestop(handle)
2333 END SUBROUTINE cfm_ikp_from_cfm_spinor_gamma
2350 CHARACTER(LEN=*) :: basis_type
2352 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cfm_ikp_from_fm_Gamma'
2354 INTEGER :: col_global, handle, i_atom, i_atom_old, i_cell, i_mic_cell, i_row, j_atom, &
2355 j_atom_old, j_cell, j_col, n_bf, ncol_local, nrow_local, num_cells, row_global
2356 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf
2357 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2358 INTEGER,
DIMENSION(:, :),
POINTER :: index_to_cell
2359 LOGICAL :: i_cell_is_the_minimum_image_cell
2360 REAL(kind=
dp) :: abs_rab_cell_i, abs_rab_cell_j, arg
2361 REAL(kind=
dp),
DIMENSION(3) :: cell_vector, cell_vector_j, rab_cell_i, &
2363 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
2367 CALL timeset(routinen, handle)
2369 IF (.NOT.
ASSOCIATED(cfm_ikp%local_data))
THEN
2375 nrow_local=nrow_local, &
2376 ncol_local=ncol_local, &
2377 row_indices=row_indices, &
2378 col_indices=col_indices)
2381 IF (basis_type ==
"ORB")
THEN
2382 n_bf = qs_env%bs_env%n_ao
2383 ELSE IF (basis_type ==
"RI_AUX")
THEN
2384 n_bf = qs_env%bs_env%n_RI
2386 cpabort(
"Only ORB and RI_AUX basis implemented.")
2389 ALLOCATE (atom_from_bf(n_bf))
2392 NULLIFY (cell, particle_set)
2393 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
2396 index_to_cell => kpoints%index_to_cell
2398 num_cells =
SIZE(index_to_cell, 2)
2402 DO j_col = 1, ncol_local
2403 DO i_row = 1, nrow_local
2405 row_global = row_indices(i_row)
2406 col_global = col_indices(j_col)
2408 i_atom = atom_from_bf(row_global)
2409 j_atom = atom_from_bf(col_global)
2412 IF (i_atom .NE. i_atom_old .OR. j_atom .NE. j_atom_old)
THEN
2413 DO i_cell = 1, num_cells
2416 IF (any(abs(index_to_cell(1:3, i_cell)) > 1)) cycle
2418 cell_vector(1:3) = matmul(hmat, real(index_to_cell(1:3, i_cell),
dp))
2420 rab_cell_i(1:3) =
pbc(particle_set(i_atom)%r(1:3), cell) - &
2421 (
pbc(particle_set(j_atom)%r(1:3), cell) + cell_vector(1:3))
2422 abs_rab_cell_i = sqrt(rab_cell_i(1)**2 + rab_cell_i(2)**2 + rab_cell_i(3)**2)
2425 i_cell_is_the_minimum_image_cell = .true.
2426 DO j_cell = 1, num_cells
2427 cell_vector_j(1:3) = matmul(hmat, real(index_to_cell(1:3, j_cell),
dp))
2428 rab_cell_j(1:3) =
pbc(particle_set(i_atom)%r(1:3), cell) - &
2429 (
pbc(particle_set(j_atom)%r(1:3), cell) + cell_vector_j(1:3))
2430 abs_rab_cell_j = sqrt(rab_cell_j(1)**2 + rab_cell_j(2)**2 + rab_cell_j(3)**2)
2432 IF (abs_rab_cell_i > abs_rab_cell_j + 1.0e-6_dp)
THEN
2433 i_cell_is_the_minimum_image_cell = .false.
2437 IF (i_cell_is_the_minimum_image_cell)
THEN
2444 arg = real(index_to_cell(1, i_mic_cell),
dp)*kpoints%xkp(1, ikp) + &
2445 REAL(index_to_cell(2, i_mic_cell),
dp)*kpoints%xkp(2, ikp) + &
2446 REAL(index_to_cell(3, i_mic_cell),
dp)*kpoints%xkp(3, ikp)
2448 cfm_ikp%local_data(i_row, j_col) = cos(
twopi*arg)*fm_gamma%local_data(i_row, j_col)*
z_one + &
2449 sin(
twopi*arg)*fm_gamma%local_data(i_row, j_col)*
gaussi
2457 CALL timestop(handle)
2473 cfm_W_ikp_freq_j, ikp, kpoints, basis_type, wkp_ext)
2478 INTEGER,
INTENT(IN) :: ikp
2480 CHARACTER(LEN=*) :: basis_type
2481 REAL(kind=
dp),
OPTIONAL :: wkp_ext
2483 CHARACTER(LEN=*),
PARAMETER :: routinen =
'MIC_contribution_from_ikp'
2485 INTEGER :: handle, i_bf, iatom, iatom_old, irow, &
2486 j_bf, jatom, jatom_old, jcol, n_bf, &
2487 ncol_local, nrow_local, num_cells
2488 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf_index
2489 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2490 INTEGER,
DIMENSION(:, :),
POINTER :: index_to_cell
2491 REAL(kind=
dp) :: contribution, weight_im, weight_re, &
2493 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
2494 REAL(kind=
dp),
DIMENSION(:),
POINTER :: wkp
2495 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xkp
2499 CALL timeset(routinen, handle)
2502 IF (basis_type ==
"ORB")
THEN
2503 n_bf = qs_env%bs_env%n_ao
2504 ELSE IF (basis_type ==
"RI_AUX")
THEN
2505 n_bf = qs_env%bs_env%n_RI
2507 cpabort(
"Only ORB and RI_AUX basis implemented.")
2510 ALLOCATE (atom_from_bf_index(n_bf))
2513 NULLIFY (cell, particle_set)
2514 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
2518 nrow_local=nrow_local, &
2519 ncol_local=ncol_local, &
2520 row_indices=row_indices, &
2521 col_indices=col_indices)
2524 index_to_cell => kpoints%index_to_cell
2525 num_cells =
SIZE(index_to_cell, 2)
2530 DO jcol = 1, ncol_local
2531 DO irow = 1, nrow_local
2533 i_bf = row_indices(irow)
2534 j_bf = col_indices(jcol)
2536 iatom = atom_from_bf_index(i_bf)
2537 jatom = atom_from_bf_index(j_bf)
2539 IF (
PRESENT(wkp_ext))
THEN
2540 wkp_of_ikp = wkp_ext
2542 SELECT CASE (bs_env%l_RI(i_bf) + bs_env%l_RI(j_bf))
2545 wkp_of_ikp = wkp(ikp)
2548 wkp_of_ikp = bs_env%wkp_s_p(ikp)
2551 wkp_of_ikp = bs_env%wkp_no_extra(ikp)
2555 IF (iatom .NE. iatom_old .OR. jatom .NE. jatom_old)
THEN
2558 num_cells, iatom, jatom, xkp(1:3, ikp), wkp_of_ikp, &
2559 cell, index_to_cell, hmat, particle_set)
2566 contribution = weight_re*real(cfm_w_ikp_freq_j%local_data(irow, jcol)) + &
2567 weight_im*aimag(cfm_w_ikp_freq_j%local_data(irow, jcol))
2569 fm_w_mic_freq_j%local_data(irow, jcol) = fm_w_mic_freq_j%local_data(irow, jcol) &
2575 CALL timestop(handle)
2588 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xkp
2589 INTEGER :: ikp_start, ikp_end
2590 INTEGER,
DIMENSION(3) :: grid
2592 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_xkp'
2594 INTEGER :: handle, i, ix, iy, iz
2596 CALL timeset(routinen, handle)
2603 IF (i > ikp_end) cycle
2605 xkp(1, i) = real(2*ix - grid(1) - 1, kind=
dp)/(2._dp*real(grid(1), kind=
dp))
2606 xkp(2, i) = real(2*iy - grid(2) - 1, kind=
dp)/(2._dp*real(grid(2), kind=
dp))
2607 xkp(3, i) = real(2*iz - grid(3) - 1, kind=
dp)/(2._dp*real(grid(3), kind=
dp))
2614 CALL timestop(handle)
2628 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_init_cell_index_simple'
2630 INTEGER :: handle, nimages
2636 CALL timeset(routinen, handle)
2638 NULLIFY (dft_control, para_env, sab_orb)
2639 CALL get_qs_env(qs_env=qs_env, para_env=para_env, dft_control=dft_control, sab_orb=sab_orb)
2640 nimages = dft_control%nimages
2644 dft_control%nimages = nimages
2646 CALL timestop(handle)
2655 SUBROUTINE soc(qs_env, bs_env)
2659 CHARACTER(LEN=*),
PARAMETER :: routinen =
'soc'
2663 CALL timeset(routinen, handle)
2671 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
2675 CALL h_ks_spinor_gamma(bs_env)
2680 CALL h_ks_spinor_kp(qs_env, bs_env)
2684 CALL timestop(handle)
2692 SUBROUTINE h_ks_spinor_gamma(bs_env)
2696 CHARACTER(LEN=*),
PARAMETER :: routinen =
'H_KS_spinor_Gamma'
2698 INTEGER :: handle, nao, s
2701 CALL timeset(routinen, handle)
2705 ALLOCATE (bs_env%cfm_SOC_spinor_ao(1))
2706 CALL create_cfm_double(bs_env%cfm_SOC_spinor_ao(1), fm_orig=bs_env%fm_ks_Gamma(1))
2709 str => bs_env%fm_ks_Gamma(1)%matrix_struct
2715 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(1, 1)%matrix, &
2716 str, s, 1,
z_one, .true.)
2717 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(2, 1)%matrix, &
2718 str, s, 1,
gaussi, .true.)
2719 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(3, 1)%matrix, &
2720 str, 1, 1,
z_one, .false.)
2721 CALL add_dbcsr_submat(bs_env%cfm_SOC_spinor_ao(1), bs_env%mat_V_SOC_xyz(3, 1)%matrix, &
2722 str, s, s, -
z_one, .false.)
2724 CALL timestop(handle)
2726 END SUBROUTINE h_ks_spinor_gamma
2733 SUBROUTINE h_ks_spinor_kp(qs_env, bs_env)
2737 CHARACTER(LEN=*),
PARAMETER :: routinen =
'H_KS_spinor_kp'
2739 INTEGER :: handle, i_dim, ikp, n_spin, &
2741 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index_scf
2742 REAL(kind=
dp),
DIMENSION(3) :: xkp
2749 CALL timeset(routinen, handle)
2751 nkp_bs_and_dos = bs_env%nkp_bs_and_DOS
2752 n_spin = bs_env%n_spin
2754 str => bs_env%cfm_ks_kp(1, 1)%matrix_struct
2756 CALL cp_cfm_create(cfm_v_soc_xyz_ikp, bs_env%cfm_work_mo%matrix_struct)
2758 CALL alloc_cfm_double_array_1d(bs_env%cfm_SOC_spinor_ao, bs_env%cfm_ks_kp(1, 1), nkp_bs_and_dos)
2763 CALL get_kpoint_info(kpoints_scf, sab_nl=sab_nl, cell_to_index=cell_to_index_scf)
2767 DO ikp = 1, nkp_bs_and_dos
2769 xkp(1:3) = bs_env%kpoints_DOS%xkp(1:3, ikp)
2773 CALL rsmat_to_kp(bs_env%mat_V_SOC_xyz, i_dim, xkp, cell_to_index_scf, &
2774 sab_nl, bs_env, cfm_v_soc_xyz_ikp, imag_rs_mat=.true.)
2782 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, 1, s)
2783 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, s, 1)
2787 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, 1, s)
2789 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, s, 1)
2792 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, 1, 1)
2794 CALL add_cfm_submat(bs_env%cfm_SOC_spinor_ao(ikp), cfm_v_soc_xyz_ikp, s, s)
2803 CALL timestop(handle)
2805 END SUBROUTINE h_ks_spinor_kp
2813 SUBROUTINE alloc_cfm_double_array_1d(cfm_array, cfm_template, n)
2814 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: cfm_array
2818 CHARACTER(LEN=*),
PARAMETER :: routinen =
'alloc_cfm_double_array_1d'
2820 INTEGER :: handle, i
2822 CALL timeset(routinen, handle)
2824 ALLOCATE (cfm_array(n))
2830 CALL timestop(handle)
2832 END SUBROUTINE alloc_cfm_double_array_1d
2842 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_all_VBM_CBM_bandgaps'
2846 CALL timeset(routinen, handle)
2852 CALL timestop(handle)
2864 REAL(kind=
dp),
DIMENSION(:, :, :) :: ev
2867 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_VBM_CBM_bandgaps'
2869 INTEGER :: handle, homo, homo_1, homo_2, ikp, &
2870 ispin, lumo, lumo_1, lumo_2, n_mo
2871 REAL(kind=
dp) :: e_dbg_at_ikp
2873 CALL timeset(routinen, handle)
2877 band_edges%DBG = 1000.0_dp
2879 SELECT CASE (bs_env%n_spin)
2881 homo = bs_env%n_occ(1)
2883 band_edges%VBM = maxval(ev(1:homo, :, 1))
2884 band_edges%CBM = minval(ev(homo + 1:n_mo, :, 1))
2886 homo_1 = bs_env%n_occ(1)
2888 homo_2 = bs_env%n_occ(2)
2890 band_edges%VBM = max(maxval(ev(1:homo_1, :, 1)), maxval(ev(1:homo_2, :, 2)))
2891 band_edges%CBM = min(minval(ev(homo_1 + 1:n_mo, :, 1)), minval(ev(homo_2 + 1:n_mo, :, 2)))
2893 cpabort(
"Error with number of spins.")
2896 band_edges%IDBG = band_edges%CBM - band_edges%VBM
2898 DO ispin = 1, bs_env%n_spin
2900 homo = bs_env%n_occ(ispin)
2902 DO ikp = 1, bs_env%nkp_bs_and_DOS
2904 e_dbg_at_ikp = -maxval(ev(1:homo, ikp, ispin)) + minval(ev(homo + 1:n_mo, ikp, ispin))
2906 IF (e_dbg_at_ikp < band_edges%DBG) band_edges%DBG = e_dbg_at_ikp
2912 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_create(matrix, matrix_struct, name)
Creates a new full matrix with the given structure.
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_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, use_sp)
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, dft_control)
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 kpoint_create(kpoint)
Create a kpoint environment.
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)
Retrieve information from 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 dos_pdos_ldos(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, 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, 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, eigenval, e_homo, e_lumo)
...
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)
...
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 ...