51 USE dbcsr_api,
ONLY: dbcsr_create,&
53 dbcsr_type_no_symmetry,&
100#include "base/base_uses.f90"
110 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'post_scf_bandstructure_utils'
125 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_and_init_bs_env'
129 CALL timeset(routinen, handle)
133 CALL print_header(bs_env)
135 CALL read_bandstructure_input_parameters(bs_env, post_scf_bandstructure_section)
137 CALL get_parameters_from_qs_env(qs_env, bs_env)
139 CALL set_heuristic_parameters(bs_env)
141 CALL setup_kpoints_dos(qs_env, bs_env, bs_env%kpoints_DOS)
143 CALL allocate_and_fill_fm_ks_fm_s(qs_env, bs_env)
145 CALL diagonalize_ks_matrix(bs_env)
147 CALL check_positive_definite_overlap_mat(bs_env, qs_env)
149 IF (bs_env%do_bs)
THEN
150 CALL setup_kpoints_bandstructure(bs_env, bs_env%kpoints_bandstructure)
151 CALL setup_primitive_cell_for_bandstructure(qs_env, bs_env)
154 CALL timestop(handle)
163 SUBROUTINE read_bandstructure_input_parameters(bs_env, bs_sec)
167 CHARACTER(LEN=*),
PARAMETER :: routinen =
'read_bandstructure_input_parameters'
169 CHARACTER(LEN=default_string_length), &
170 DIMENSION(:),
POINTER :: string_ptr
171 CHARACTER(LEN=max_line_length) :: error_msg
172 INTEGER :: handle, i, ikp
175 CALL timeset(routinen, handle)
206 ALLOCATE (bs_env%xkp_special(3, bs_env%input_kp_bs_n_sp_pts))
207 ALLOCATE (bs_env%kp_special_name(bs_env%input_kp_bs_n_sp_pts))
208 DO ikp = 1, bs_env%input_kp_bs_n_sp_pts
210 cpassert(
SIZE(string_ptr(:), 1) == 4)
211 bs_env%kp_special_name(ikp) = string_ptr(1)
214 IF (len_trim(error_msg) > 0) cpabort(trim(error_msg))
218 CALL timestop(handle)
220 END SUBROUTINE read_bandstructure_input_parameters
226 SUBROUTINE print_header(bs_env)
230 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_header'
234 CALL timeset(routinen, handle)
242 WRITE (u,
'(T2,2A)')
'-------------------------------------------------', &
243 '------------------------------'
244 WRITE (u,
'(T2,2A)')
'- ', &
246 WRITE (u,
'(T2,2A)')
'- BANDSTRUCTURE CALCULATION', &
248 WRITE (u,
'(T2,2A)')
'- ', &
250 WRITE (u,
'(T2,2A)')
'--------------------------------------------------', &
251 '-----------------------------'
252 WRITE (u,
'(T2,A)')
' '
255 CALL timestop(handle)
257 END SUBROUTINE print_header
265 SUBROUTINE setup_kpoints_dos(qs_env, bs_env, kpoints)
271 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_DOS'
273 INTEGER :: handle, i_dim, nkp, u
274 INTEGER,
DIMENSION(3) :: nkp_grid, periodic
276 CALL timeset(routinen, handle)
282 kpoints%kp_scheme =
"GENERAL"
284 periodic(1:3) = bs_env%periodic(1:3)
288 cpassert(periodic(i_dim) == 0 .OR. periodic(i_dim) == 1)
290 IF (bs_env%nkp_grid_DOS_input(i_dim) < 0)
THEN
291 IF (periodic(i_dim) == 1) nkp_grid(i_dim) = 2
292 IF (periodic(i_dim) == 0) nkp_grid(i_dim) = 1
294 nkp_grid(i_dim) = bs_env%nkp_grid_DOS_input(i_dim)
300 IF (nkp_grid(1) > 1)
THEN
301 nkp = (nkp_grid(1) + 1)/2*nkp_grid(2)*nkp_grid(3)
302 ELSE IF (nkp_grid(2) > 1)
THEN
303 nkp = nkp_grid(1)*(nkp_grid(2) + 1)/2*nkp_grid(3)
304 ELSE IF (nkp_grid(3) > 1)
THEN
305 nkp = nkp_grid(1)*nkp_grid(2)*(nkp_grid(3) + 1)/2
310 kpoints%nkp_grid(1:3) = nkp_grid(1:3)
315 ALLOCATE (kpoints%xkp(3, nkp), kpoints%wkp(nkp))
316 kpoints%wkp(1:nkp) = 1.0_dp/real(nkp, kind=
dp)
325 WRITE (unit=u, fmt=
"(T2,1A,T69,3I4)")
"K-point mesh for the density of states (DOS)", &
329 CALL timestop(handle)
331 END SUBROUTINE setup_kpoints_dos
338 SUBROUTINE setup_kpoints_bandstructure(bs_env, kpoints)
343 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_bandstructure'
345 INTEGER :: handle, i_kp_in_line, i_special_kp, ikk, &
346 n_kp_in_line, n_special_kp, nkp, u
348 CALL timeset(routinen, handle)
354 n_special_kp = bs_env%input_kp_bs_n_sp_pts
355 n_kp_in_line = bs_env%input_kp_bs_npoints
357 nkp = n_kp_in_line*(n_special_kp - 1) + 1
359 IF (n_special_kp < 1) &
360 cpabort(
"Please specify special k-points in the Brillouin zone via SPECIAL_POINT.")
361 IF (n_kp_in_line < 1) &
362 cpabort(
"Please specify the number of k-points between special k-points.")
364 ALLOCATE (kpoints%xkp(3, nkp))
367 kpoints%xkp(1:3, 1) = bs_env%xkp_special(1:3, 1)
373 DO i_special_kp = 2, n_special_kp
374 DO i_kp_in_line = 1, n_kp_in_line
376 kpoints%xkp(1:3, ikk) = bs_env%xkp_special(1:3, i_special_kp - 1) + &
377 REAL(i_kp_in_line, kind=
dp)/real(n_kp_in_line, kind=
dp)* &
378 (bs_env%xkp_special(1:3, i_special_kp) - &
379 bs_env%xkp_special(1:3, i_special_kp - 1))
386 WRITE (unit=u, fmt=
"(T2,1A,T77,I4)")
"Number of special k-points for the bandstructure", &
388 WRITE (unit=u, fmt=
"(T2,1A,T77,I4)")
"Number of k-points for the bandstructure", nkp
391 CALL timestop(handle)
393 END SUBROUTINE setup_kpoints_bandstructure
399 SUBROUTINE diagonalize_ks_matrix(bs_env)
402 CHARACTER(LEN=*),
PARAMETER :: routinen =
'diagonalize_ks_matrix'
404 INTEGER :: handle, ispin
405 REAL(kind=
dp) :: cbm, vbm
407 CALL timeset(routinen, handle)
409 ALLOCATE (bs_env%eigenval_scf_Gamma(bs_env%n_ao, bs_env%n_spin))
411 DO ispin = 1, bs_env%n_spin
414 CALL cp_fm_to_fm(bs_env%fm_ks_Gamma(ispin), bs_env%fm_work_mo(1))
415 CALL cp_fm_to_fm(bs_env%fm_s_Gamma, bs_env%fm_work_mo(2))
420 bs_env%fm_work_mo(2), &
421 bs_env%fm_mo_coeff_Gamma(ispin), &
422 bs_env%eigenval_scf_Gamma(:, ispin), &
423 bs_env%fm_work_mo(3), &
424 bs_env%eps_eigval_mat_s)
426 vbm = bs_env%eigenval_scf_Gamma(bs_env%n_occ(ispin), ispin)
427 cbm = bs_env%eigenval_scf_Gamma(bs_env%n_occ(ispin) + 1, ispin)
429 bs_env%band_edges_scf_Gamma(ispin)%VBM = vbm
430 bs_env%band_edges_scf_Gamma(ispin)%CBM = cbm
431 bs_env%e_fermi(ispin) = 0.5_dp*(vbm + cbm)
435 CALL timestop(handle)
437 END SUBROUTINE diagonalize_ks_matrix
444 SUBROUTINE check_positive_definite_overlap_mat(bs_env, qs_env)
448 CHARACTER(LEN=*),
PARAMETER :: routinen =
'check_positive_definite_overlap_mat'
450 INTEGER :: handle, ikp, info, u
453 CALL timeset(routinen, handle)
455 DO ikp = 1, bs_env%kpoints_DOS%nkp
459 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
466 IF (info .NE. 0)
THEN
470 WRITE (unit=u, fmt=
"(T2,A)")
""
471 WRITE (unit=u, fmt=
"(T2,A)")
"ERROR: The Cholesky decomposition "// &
472 "of the k-point overlap matrix failed. This is"
473 WRITE (unit=u, fmt=
"(T2,A)")
"because the algorithm is "// &
474 "only correct in the limit of large cells. The cell of "
475 WRITE (unit=u, fmt=
"(T2,A)")
"the calculation is too small. "// &
476 "Use MULTIPLE_UNIT_CELL to create a larger cell "
477 WRITE (unit=u, fmt=
"(T2,A)")
"and to prevent this error."
480 CALL bs_env%para_env%sync()
481 cpabort(
"Please see information on the error above.")
489 CALL timestop(handle)
491 END SUBROUTINE check_positive_definite_overlap_mat
498 SUBROUTINE get_parameters_from_qs_env(qs_env, bs_env)
502 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_parameters_from_qs_env'
504 INTEGER :: color_sub, handle, homo, n_ao, n_atom, u
505 INTEGER,
DIMENSION(3) :: periodic
506 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
514 CALL timeset(routinen, handle)
517 dft_control=dft_control, &
518 scf_control=scf_control, &
521 bs_env%n_spin = dft_control%nspins
522 IF (bs_env%n_spin == 1) bs_env%spin_degeneracy = 2.0_dp
523 IF (bs_env%n_spin == 2) bs_env%spin_degeneracy = 1.0_dp
525 CALL get_mo_set(mo_set=mos(1), nao=n_ao, homo=homo)
527 bs_env%n_occ(1:2) = homo
528 bs_env%n_vir(1:2) = n_ao - homo
530 IF (bs_env%n_spin == 2)
THEN
532 bs_env%n_occ(2) = homo
533 bs_env%n_vir(2) = n_ao - homo
536 bs_env%eps_eigval_mat_s = scf_control%eps_eigval
541 ALLOCATE (bs_env%para_env)
542 CALL bs_env%para_env%from_split(para_env, color_sub)
544 CALL get_qs_env(qs_env, particle_set=particle_set)
546 n_atom =
SIZE(particle_set)
547 bs_env%n_atom = n_atom
550 CALL get_cell(cell=cell, periodic=periodic, h=hmat)
551 bs_env%periodic(1:3) = periodic(1:3)
552 bs_env%hmat(1:3, 1:3) = hmat
557 WRITE (unit=u, fmt=
"(T2,2A,T73,I8)")
"Number of occupied molecular orbitals (MOs) ", &
558 "= Number of occupied bands", homo
559 WRITE (unit=u, fmt=
"(T2,2A,T73,I8)")
"Number of unoccupied (= virtual) MOs ", &
560 "= Number of unoccupied bands", n_ao - homo
561 WRITE (unit=u, fmt=
"(T2,A,T73,I8)")
"Number of Gaussian basis functions for MOs", n_ao
564 CALL timestop(handle)
566 END SUBROUTINE get_parameters_from_qs_env
572 SUBROUTINE set_heuristic_parameters(bs_env)
575 CHARACTER(LEN=*),
PARAMETER :: routinen =
'set_heuristic_parameters'
579 CALL timeset(routinen, handle)
581 bs_env%n_bins_max_for_printing = 5000
583 CALL timestop(handle)
585 END SUBROUTINE set_heuristic_parameters
592 SUBROUTINE allocate_and_fill_fm_ks_fm_s(qs_env, bs_env)
596 CHARACTER(LEN=*),
PARAMETER :: routinen =
'allocate_and_fill_fm_ks_fm_s'
598 INTEGER :: handle, i_work, ispin
601 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s
604 CALL timeset(routinen, handle)
608 blacs_env=blacs_env, &
609 matrix_ks=matrix_ks, &
614 ncol_global=bs_env%n_ao, para_env=para_env)
616 DO i_work = 1,
SIZE(bs_env%fm_work_mo)
623 DO ispin = 1, bs_env%n_spin
626 CALL cp_fm_create(bs_env%fm_mo_coeff_Gamma(ispin), fm_struct)
631 NULLIFY (bs_env%mat_ao_ao%matrix)
632 ALLOCATE (bs_env%mat_ao_ao%matrix)
633 CALL dbcsr_create(bs_env%mat_ao_ao%matrix, template=matrix_s(1)%matrix, &
634 matrix_type=dbcsr_type_no_symmetry)
636 ALLOCATE (bs_env%eigenval_scf(bs_env%n_ao, bs_env%nkp_DOS, bs_env%n_spin))
638 CALL timestop(handle)
640 END SUBROUTINE allocate_and_fill_fm_ks_fm_s
647 SUBROUTINE setup_primitive_cell_for_bandstructure(qs_env, bs_env)
651 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_primitive_cell_for_bandstructure'
653 INTEGER :: handle, i_atom, i_x_cell, index_j, j_atom, j_atom_prim_cell, j_y_cell, k_z_cell, &
654 n_atom, n_atom_in_primitive_cell, n_max_check, n_max_x, n_max_y, n_max_z, &
655 n_mult_unit_cell_x, n_mult_unit_cell_y, n_mult_unit_cell_z, n_primitive_cells, n_x, n_y, &
657 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kind_of
658 LOGICAL :: i_atom_has_image_in_every_subcell, i_atom_has_image_in_subcell_ijk
659 LOGICAL,
ALLOCATABLE,
DIMENSION(:, :, :) :: valid_multiple_unit_cell
660 REAL(
dp),
DIMENSION(3) :: center_primitive_cell, coord_ijk, coord_sub_cell_ijk, &
661 index_atom_i, index_ijk, index_sub_cell_ijk, offset, ra, ra_ijk, rab, rb
663 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
668 CALL timeset(routinen, handle)
670 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, particle_set=particle_set, cell=cell)
676 n_max_x = n_max_check*bs_env%periodic(1) + 1
677 n_max_y = n_max_check*bs_env%periodic(2) + 1
678 n_max_z = n_max_check*bs_env%periodic(3) + 1
680 ALLOCATE (valid_multiple_unit_cell(n_max_x, n_max_y, n_max_z))
681 valid_multiple_unit_cell(:, :, :) = .true.
683 n_atom = bs_env%n_atom
685 DO i_atom = 1, n_atom
687 IF (.NOT.
modulo(i_atom, bs_env%para_env%num_pe) == bs_env%para_env%mepos) cycle
689 ra(1:3) = particle_set(i_atom)%r(1:3)
695 i_atom_has_image_in_every_subcell = .true.
697 DO i_x_cell = 0, n_x - 1
698 DO j_y_cell = 0, n_y - 1
699 DO k_z_cell = 0, n_z - 1
701 i_atom_has_image_in_subcell_ijk = .false.
703 DO j_atom = 1, n_atom
705 IF (kind_of(i_atom) .NE. kind_of(j_atom)) cycle
707 IF (i_atom_has_image_in_subcell_ijk) cycle
709 IF (.NOT. i_atom_has_image_in_every_subcell) cycle
711 index_sub_cell_ijk(1:3) = (/real(i_x_cell,
dp)/real(n_x,
dp), &
712 REAL(j_y_cell,
dp)/
REAL(n_y, dp), &
713 REAL(k_z_cell,
dp)/
REAL(n_z,
dp)/)
715 coord_sub_cell_ijk(1:3) = matmul(hmat, index_sub_cell_ijk)
717 ra_ijk(1:3) = ra(1:3) + coord_sub_cell_ijk(1:3)
719 rb(1:3) =
pbc(particle_set(j_atom)%r(1:3), cell)
721 rab(1:3) = rb(1:3) -
pbc(ra_ijk(1:3), cell)
723 dab = sqrt((rab(1))**2 + (rab(2))**2 + (rab(3))**2)
725 IF (dab < 1.0e-5) i_atom_has_image_in_subcell_ijk = .true.
729 IF (.NOT. i_atom_has_image_in_subcell_ijk)
THEN
730 i_atom_has_image_in_every_subcell = .false.
738 valid_multiple_unit_cell(n_x, n_y, n_z) = i_atom_has_image_in_every_subcell .AND. &
739 valid_multiple_unit_cell(n_x, n_y, n_z)
747 CALL mpi_and(valid_multiple_unit_cell, bs_env%para_env)
749 n_mult_unit_cell_x = 1
750 n_mult_unit_cell_y = 1
751 n_mult_unit_cell_z = 1
756 IF (valid_multiple_unit_cell(n_x, n_y, n_z))
THEN
757 n_mult_unit_cell_x = max(n_mult_unit_cell_x, n_x)
758 n_mult_unit_cell_y = max(n_mult_unit_cell_y, n_y)
759 n_mult_unit_cell_z = max(n_mult_unit_cell_z, n_z)
765 bs_env%multiple_unit_cell(1) = n_mult_unit_cell_x
766 bs_env%multiple_unit_cell(2) = n_mult_unit_cell_y
767 bs_env%multiple_unit_cell(3) = n_mult_unit_cell_z
769 IF (n_mult_unit_cell_x .NE. 1 .OR. &
770 n_mult_unit_cell_y .NE. 1 .OR. &
771 n_mult_unit_cell_z .NE. 1)
THEN
772 bs_env%calculate_bandstructure_of_primitive_cell = .true.
774 bs_env%calculate_bandstructure_of_primitive_cell = .false.
777 n_atom_in_primitive_cell = n_atom/n_mult_unit_cell_x/n_mult_unit_cell_y/n_mult_unit_cell_z
778 bs_env%n_atom_in_primitive_cell = n_atom_in_primitive_cell
780 n_primitive_cells = n_atom/n_atom_in_primitive_cell
781 bs_env%n_primitive_cells = n_primitive_cells
783 bs_env%hmat_primitive_cell(1, 1:3) = hmat(1, 1:3)/real(n_mult_unit_cell_x)
784 bs_env%hmat_primitive_cell(2, 1:3) = hmat(2, 1:3)/real(n_mult_unit_cell_y)
785 bs_env%hmat_primitive_cell(3, 1:3) = hmat(3, 1:3)/real(n_mult_unit_cell_z)
787 bs_env%hinv_primitive_cell =
inv_3x3(bs_env%hmat_primitive_cell)
789 bs_env%do_bs_primitive_cell = bs_env%do_bs .AND. n_atom_in_primitive_cell < 20 &
790 .AND. n_primitive_cells > 1
792 ALLOCATE (bs_env%atoms_i_primitive_cell(n_atom_in_primitive_cell))
793 bs_env%atoms_i_primitive_cell(:) = 0
796 offset(1:3) = matmul(bs_env%hmat_primitive_cell, (/0.001_dp, 0.001_dp, 0.001_dp/))
797 center_primitive_cell(1:3) =
pbc(particle_set(1)%r(1:3), cell) - offset(1:3)
800 DO i_atom = 1, n_atom
802 rb(1:3) =
pbc(particle_set(i_atom)%r(1:3), cell) - center_primitive_cell(1:3)
804 index_atom_i(1:3) = matmul(bs_env%hinv_primitive_cell, rb)
806 IF (index_atom_i(1) > -0.5_dp .AND. index_atom_i(1) < 0.5_dp .AND. &
807 index_atom_i(2) > -0.5_dp .AND. index_atom_i(2) < 0.5_dp .AND. &
808 index_atom_i(3) > -0.5_dp .AND. index_atom_i(3) < 0.5_dp)
THEN
810 index_j = index_j + 1
811 cpassert(index_j .LE. n_atom_in_primitive_cell)
812 bs_env%atoms_i_primitive_cell(index_j) = i_atom
818 ALLOCATE (bs_env%ref_atom_primitive_cell(n_atom))
819 ALLOCATE (bs_env%cell_of_i_atom(n_atom, 3))
821 DO i_atom = 1, n_atom
823 ra(1:3) =
pbc(particle_set(i_atom)%r(1:3), cell)
825 DO j_atom_prim_cell = 1, n_atom_in_primitive_cell
827 j_atom = bs_env%atoms_i_primitive_cell(j_atom_prim_cell)
829 rb(1:3) =
pbc(particle_set(j_atom)%r(1:3), cell)
831 DO i_x_cell = -n_mult_unit_cell_x/2, n_mult_unit_cell_x/2
832 DO j_y_cell = -n_mult_unit_cell_y/2, n_mult_unit_cell_y/2
833 DO k_z_cell = -n_mult_unit_cell_z/2, n_mult_unit_cell_z/2
835 index_ijk(1:3) = (/real(i_x_cell,
dp), real(j_y_cell,
dp), real(k_z_cell,
dp)/)
836 coord_ijk(1:3) = matmul(bs_env%hmat_primitive_cell, index_ijk)
838 ra_ijk(1:3) = ra(1:3) + coord_ijk(1:3)
840 rab(1:3) = rb(1:3) -
pbc(ra_ijk(1:3), cell)
842 dab = sqrt((rab(1))**2 + (rab(2))**2 + (rab(3))**2)
844 IF (dab < 1.0e-5)
THEN
845 bs_env%ref_atom_primitive_cell(i_atom) = j_atom
846 bs_env%cell_of_i_atom(i_atom, 1) = i_x_cell
847 bs_env%cell_of_i_atom(i_atom, 2) = j_y_cell
848 bs_env%cell_of_i_atom(i_atom, 3) = k_z_cell
856 IF (bs_env%unit_nr > 0 .AND. bs_env%calculate_bandstructure_of_primitive_cell)
THEN
857 WRITE (bs_env%unit_nr,
'(T2,A,3I4)') &
858 'Detected a multiple unit cell (will be used for band structure) ', &
859 bs_env%multiple_unit_cell
860 WRITE (bs_env%unit_nr,
'(T2,A,I28)') &
861 'Number of occupied bands in the primitive unit cell', &
862 bs_env%n_occ(1)/bs_env%n_primitive_cells
863 WRITE (bs_env%unit_nr,
'(T2,A,I26)') &
864 'Number of unoccupied bands in the primitive unit cell', &
865 bs_env%n_vir(1)/bs_env%n_primitive_cells
868 CALL timestop(handle)
870 END SUBROUTINE setup_primitive_cell_for_bandstructure
877 SUBROUTINE mpi_and(logical_array_3d, para_env)
878 LOGICAL,
ALLOCATABLE,
DIMENSION(:, :, :) :: logical_array_3d
881 CHARACTER(LEN=*),
PARAMETER :: routinen =
'mpi_AND'
883 INTEGER :: handle, i, j, k, n_1, n_2, n_3
884 INTEGER,
ALLOCATABLE,
DIMENSION(:, :, :) :: integer_array_3d
886 CALL timeset(routinen, handle)
888 n_1 =
SIZE(logical_array_3d, 1)
889 n_2 =
SIZE(logical_array_3d, 2)
890 n_3 =
SIZE(logical_array_3d, 3)
892 ALLOCATE (integer_array_3d(n_1, n_2, n_3))
893 integer_array_3d(:, :, :) = 0
898 IF (logical_array_3d(i, j, k)) integer_array_3d(i, j, k) = 1
904 CALL para_env%sum(integer_array_3d)
907 logical_array_3d(:, :, :) = .false.
912 IF (integer_array_3d(i, j, k) == para_env%num_pe) logical_array_3d(i, j, k) = .true.
917 CALL timestop(handle)
919 END SUBROUTINE mpi_and
932 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: eigenvalues
933 CHARACTER(LEN=*) :: filename
936 CHARACTER(LEN=*),
PARAMETER :: routinen =
'bandstructure_primitive_cell'
938 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: h_munu_k, mo_coeff_k, s_munu_k
939 INTEGER :: col_global, handle, i, i_atom, i_dim, i_row, ikp, imo, ip, iunit, j, j_atom, &
940 j_col, n_ao, n_ao_primitive_cell, n_atom, ncol_local, nrow_local, ref_atom_j, row_global
941 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf, first_bf_from_atom, &
942 first_bf_of_primit_atom
943 INTEGER,
DIMENSION(3) :: cell_atom_i, cell_atom_j, min_max_cell
944 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
947 CALL timeset(routinen, handle)
950 n_ao_primitive_cell = n_ao/bs_env%n_primitive_cells
951 n_atom = bs_env%n_atom
953 ALLOCATE (h_munu_k(n_ao_primitive_cell, n_ao_primitive_cell))
954 ALLOCATE (s_munu_k(n_ao_primitive_cell, n_ao_primitive_cell))
955 ALLOCATE (mo_coeff_k(n_ao_primitive_cell, n_ao_primitive_cell))
956 ALLOCATE (eigenvalues(n_ao_primitive_cell, bs_env%nkp_bs))
958 ALLOCATE (atom_from_bf(n_ao))
959 ALLOCATE (first_bf_from_atom(n_atom))
963 ALLOCATE (first_bf_of_primit_atom(n_atom))
964 CALL get_basis_function_index_of_primitive_atoms(bs_env, first_bf_of_primit_atom, &
967 IF (bs_env%para_env%is_source())
THEN
968 CALL open_file(filename, unit_number=iunit, file_status=
"REPLACE", &
969 file_action=
"WRITE", file_position=
"APPEND")
976 WRITE (unit=iunit, fmt=
"(2(A,I0),A)")
"# ", &
977 bs_env%input_kp_bs_n_sp_pts,
" special points, ", bs_env%nkp_bs,
" k-points"
978 DO ip = 1, bs_env%input_kp_bs_n_sp_pts
979 WRITE (unit=iunit, fmt=
"(A,I0,T20,T24,3(1X,F14.8),2X,A)") &
980 "# Special point ", ip, bs_env%xkp_special(1:3, ip), &
981 adjustl(trim(bs_env%kp_special_name(ip)))
987 nrow_local=nrow_local, &
988 ncol_local=ncol_local, &
989 row_indices=row_indices, &
990 col_indices=col_indices)
993 min_max_cell(i_dim) = min(maxval(bs_env%cell_of_i_atom(:, i_dim)), &
994 maxval(-bs_env%cell_of_i_atom(:, i_dim)))
997 DO ikp = 1, bs_env%nkp_bs
1002 DO i_row = 1, nrow_local
1003 DO j_col = 1, ncol_local
1005 row_global = row_indices(i_row)
1006 col_global = col_indices(j_col)
1008 i_atom = atom_from_bf(row_global)
1009 j_atom = atom_from_bf(col_global)
1011 cell_atom_i = bs_env%cell_of_i_atom(i_atom, 1:3)
1015 IF (any(cell_atom_i(1:3) .NE. 0)) cycle
1017 cell_atom_j = bs_env%cell_of_i_atom(j_atom, 1:3)
1021 IF (any(abs(cell_atom_j(1:3)) > min_max_cell(1:3))) cycle
1023 arg = (real(cell_atom_j(1),
dp)*bs_env%kpoints_bandstructure%xkp(1, ikp) + &
1024 REAL(cell_atom_j(2),
dp)*bs_env%kpoints_bandstructure%xkp(2, ikp) + &
1025 REAL(cell_atom_j(3),
dp)*bs_env%kpoints_bandstructure%xkp(3, ikp))*
twopi
1027 ref_atom_j = bs_env%ref_atom_primitive_cell(j_atom)
1029 i = row_global - first_bf_from_atom(i_atom) + first_bf_of_primit_atom(i_atom)
1030 j = col_global - first_bf_from_atom(j_atom) + first_bf_of_primit_atom(ref_atom_j)
1032 h_munu_k(i, j) = h_munu_k(i, j) + &
1033 cos(arg)*fm_h_gamma%local_data(i_row, j_col)*
z_one + &
1034 sin(arg)*fm_h_gamma%local_data(i_row, j_col)*
gaussi
1036 s_munu_k(i, j) = s_munu_k(i, j) + &
1037 cos(arg)*bs_env%fm_s_Gamma%local_data(i_row, j_col)*
z_one + &
1038 sin(arg)*bs_env%fm_s_Gamma%local_data(i_row, j_col)*
gaussi
1042 CALL bs_env%para_env%sync()
1043 CALL bs_env%para_env%sum(h_munu_k)
1044 CALL bs_env%para_env%sum(s_munu_k)
1045 CALL bs_env%para_env%sync()
1047 CALL complex_geeig(h_munu_k, s_munu_k, mo_coeff_k, eigenvalues(:, ikp))
1051 WRITE (unit=iunit, fmt=
"(A,I0,T15,A,T24,3(1X,F14.8))") &
1052 "# Point ", ikp,
":", bs_env%kpoints_bandstructure%xkp(1:3, ikp)
1053 WRITE (unit=iunit, fmt=
"(A)")
"# Band Energy [eV]"
1054 DO imo = 1, n_ao_primitive_cell
1055 WRITE (unit=iunit, fmt=
"(T2,I7,1X,F14.8)") imo, eigenvalues(imo, ikp)*
evolt
1062 IF (bs_env%para_env%is_source())
CALL close_file(unit_number=iunit)
1064 CALL timestop(handle)
1080 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: eigenvalues
1081 CHARACTER(LEN=*) :: filename
1084 CHARACTER(LEN=*),
PARAMETER :: routinen =
'bandstructure_primitive_cell_spinor'
1086 COMPLEX(KIND=dp) :: arg, s_z
1087 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:) :: s_dot_mo_coeff_down, s_dot_mo_coeff_up
1088 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: h_munu_k, mo_coeff_k, s_munu_k, &
1090 INTEGER :: col_global, handle, i, i_atom, i_atom_non_spinor, i_dim, i_row, ikp, imo, ip, &
1091 iunit, j, j_atom, j_atom_non_spinor, j_col, n_ao, n_ao_primitive_cell, n_atom, &
1092 n_atom_primitive_cell, ncol_local, nrow_local, ref_atom_j, row_global
1093 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf, first_bf_from_atom, &
1094 first_bf_of_primit_atom
1095 INTEGER,
DIMENSION(3) :: cell_atom_i, cell_atom_j, min_max_cell
1096 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1098 CALL timeset(routinen, handle)
1101 n_ao_primitive_cell = n_ao/bs_env%n_primitive_cells
1102 n_atom = bs_env%n_atom
1103 n_atom_primitive_cell = n_atom/bs_env%n_primitive_cells
1105 ALLOCATE (h_munu_k(2*n_ao_primitive_cell, 2*n_ao_primitive_cell))
1106 ALLOCATE (s_munu_k(2*n_ao_primitive_cell, 2*n_ao_primitive_cell))
1107 ALLOCATE (s_munu_k_single(n_ao_primitive_cell, n_ao_primitive_cell))
1108 ALLOCATE (mo_coeff_k(2*n_ao_primitive_cell, 2*n_ao_primitive_cell))
1109 ALLOCATE (eigenvalues(2*n_ao_primitive_cell, bs_env%nkp_bs))
1110 ALLOCATE (s_dot_mo_coeff_up(n_ao_primitive_cell))
1111 ALLOCATE (s_dot_mo_coeff_down(n_ao_primitive_cell))
1113 ALLOCATE (atom_from_bf(2*n_ao))
1114 ALLOCATE (first_bf_from_atom(2*n_atom))
1117 atom_from_bf(n_ao + 1:2*n_ao) = atom_from_bf(1:n_ao) + n_atom
1118 first_bf_from_atom(n_atom + 1:2*n_atom) = first_bf_from_atom(1:n_atom) + n_ao
1120 ALLOCATE (first_bf_of_primit_atom(2*n_atom))
1121 CALL get_basis_function_index_of_primitive_atoms(bs_env, first_bf_of_primit_atom, &
1123 first_bf_of_primit_atom(n_atom + 1:2*n_atom) = first_bf_of_primit_atom(1:n_atom) &
1124 + n_ao_primitive_cell
1126 IF (bs_env%para_env%is_source())
THEN
1127 CALL open_file(filename, unit_number=iunit, file_status=
"REPLACE", &
1128 file_action=
"WRITE", file_position=
"APPEND")
1135 WRITE (unit=iunit, fmt=
"(2(A,I0),A)")
"# ", &
1136 bs_env%input_kp_bs_n_sp_pts,
" special points, ", bs_env%nkp_bs,
" k-points"
1137 DO ip = 1, bs_env%input_kp_bs_n_sp_pts
1138 WRITE (unit=iunit, fmt=
"(A,I0,T20,T24,3(1X,F14.8),2X,A)") &
1139 "# Special point ", ip, bs_env%xkp_special(1:3, ip), &
1140 adjustl(trim(bs_env%kp_special_name(ip)))
1146 nrow_local=nrow_local, &
1147 ncol_local=ncol_local, &
1148 row_indices=row_indices, &
1149 col_indices=col_indices)
1152 min_max_cell(i_dim) = min(maxval(bs_env%cell_of_i_atom(:, i_dim)), &
1153 maxval(-bs_env%cell_of_i_atom(:, i_dim)))
1156 DO ikp = 1, bs_env%nkp_bs
1161 DO i_row = 1, nrow_local
1162 DO j_col = 1, ncol_local
1164 row_global = row_indices(i_row)
1165 col_global = col_indices(j_col)
1167 i_atom = atom_from_bf(row_global)
1168 j_atom = atom_from_bf(col_global)
1170 IF (i_atom > n_atom)
THEN
1171 i_atom_non_spinor = i_atom - n_atom
1173 i_atom_non_spinor = i_atom
1176 IF (j_atom > n_atom)
THEN
1177 j_atom_non_spinor = j_atom - n_atom
1179 j_atom_non_spinor = j_atom
1182 cell_atom_i = bs_env%cell_of_i_atom(i_atom_non_spinor, 1:3)
1186 IF (any(cell_atom_i(1:3) .NE. 0)) cycle
1188 cell_atom_j = bs_env%cell_of_i_atom(j_atom_non_spinor, 1:3)
1192 IF (any(abs(cell_atom_j(1:3)) > min_max_cell(1:3))) cycle
1194 arg = (real(cell_atom_j(1),
dp)*bs_env%kpoints_bandstructure%xkp(1, ikp) + &
1195 REAL(cell_atom_j(2),
dp)*bs_env%kpoints_bandstructure%xkp(2, ikp) + &
1196 REAL(cell_atom_j(3),
dp)*bs_env%kpoints_bandstructure%xkp(3, ikp))*
twopi
1198 IF (j_atom > n_atom)
THEN
1199 ref_atom_j = bs_env%ref_atom_primitive_cell(j_atom_non_spinor) + n_atom
1201 ref_atom_j = bs_env%ref_atom_primitive_cell(j_atom)
1204 i = row_global - first_bf_from_atom(i_atom) + first_bf_of_primit_atom(i_atom)
1205 j = col_global - first_bf_from_atom(j_atom) + first_bf_of_primit_atom(ref_atom_j)
1207 h_munu_k(i, j) = h_munu_k(i, j) + &
1208 cos(arg)*cfm_h_gamma_spinor%local_data(i_row, j_col) + &
1209 sin(arg)*cfm_h_gamma_spinor%local_data(i_row, j_col)*
gaussi
1211 s_munu_k(i, j) = s_munu_k(i, j) + &
1212 cos(arg)*bs_env%cfm_s_spinor_Gamma%local_data(i_row, j_col) + &
1213 sin(arg)*bs_env%cfm_s_spinor_Gamma%local_data(i_row, j_col)*
gaussi
1218 CALL bs_env%para_env%sync()
1219 CALL bs_env%para_env%sum(h_munu_k)
1220 CALL bs_env%para_env%sum(s_munu_k)
1221 CALL bs_env%para_env%sync()
1223 CALL complex_geeig(h_munu_k, s_munu_k, mo_coeff_k, eigenvalues(:, ikp))
1227 s_munu_k_single(:, :) = s_munu_k(1:n_ao_primitive_cell, 1:n_ao_primitive_cell)
1229 WRITE (unit=iunit, fmt=
"(A,I0,T15,A,T24,3(1X,F14.8))") &
1230 "# Point ", ikp,
":", bs_env%kpoints_bandstructure%xkp(1:3, ikp)
1231 WRITE (unit=iunit, fmt=
"(A)") ħ
"# Band Energy [eV] <S_z> / (/2) "
1232 DO imo = 1, 2*n_ao_primitive_cell
1233 s_dot_mo_coeff_up(:) = matmul(s_munu_k_single, &
1234 mo_coeff_k(1:n_ao_primitive_cell, imo))
1235 s_dot_mo_coeff_down(:) = matmul(s_munu_k_single, &
1236 mo_coeff_k(n_ao_primitive_cell + 1:, imo))
1237 s_z = sum(conjg(mo_coeff_k(1:n_ao_primitive_cell, imo))*s_dot_mo_coeff_up) - &
1238 sum(conjg(mo_coeff_k(n_ao_primitive_cell + 1:, imo))*s_dot_mo_coeff_down)
1239 WRITE (unit=iunit, fmt=
"(T2,I7,1X,2F14.8)") imo, eigenvalues(imo, ikp)*
evolt, &
1247 IF (bs_env%para_env%is_source())
CALL close_file(unit_number=iunit)
1249 CALL timestop(handle)
1260 SUBROUTINE complex_geeig(matrix, overlap, eigenvectors, eigenvalues)
1262 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(INOUT) :: matrix, overlap, eigenvectors
1263 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: eigenvalues
1265 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: overlap_sqrt_inv, work_1, work_2
1267 LOGICAL :: check_size
1271 check_size =
SIZE(matrix, 2) == n .AND.
SIZE(overlap, 1) == n .AND. &
1272 SIZE(eigenvalues) == n .AND. &
1273 SIZE(eigenvectors, 1) == n .AND.
SIZE(eigenvectors, 2) == n
1274 cpassert(check_size)
1276 ALLOCATE (work_1(n, n), work_2(n, n), overlap_sqrt_inv(n, n))
1282 IF (eigenvalues(i) > 1.0e-5_dp)
THEN
1283 work_1(i, i) = eigenvalues(i)**(-0.5_dp)
1286 work_2(:, :) = matmul(work_1, transpose(conjg(eigenvectors)))
1287 overlap_sqrt_inv(:, :) = matmul(eigenvectors, work_2)
1289 work_1(:, :) = matmul(matrix, overlap_sqrt_inv)
1290 work_2(:, :) = matmul(overlap_sqrt_inv, work_1)
1294 work_2(:, :) = matmul(overlap_sqrt_inv, eigenvectors)
1295 eigenvectors(:, :) = work_2(:, :)
1297 END SUBROUTINE complex_geeig
1305 SUBROUTINE get_basis_function_index_of_primitive_atoms(bs_env, first_bf_of_primit_atom, &
1308 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: first_bf_of_primit_atom, &
1311 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_basis_function_index_of_primitive_atoms'
1313 INTEGER :: handle, i_atom, n_atom, n_bf_of_atom_i
1315 CALL timeset(routinen, handle)
1317 first_bf_of_primit_atom(:) = 1
1319 n_atom = bs_env%n_atom
1321 DO i_atom = 2, n_atom
1322 IF (any(bs_env%atoms_i_primitive_cell(:) == i_atom))
THEN
1323 n_bf_of_atom_i = first_bf_from_atom(i_atom) - first_bf_from_atom(i_atom - 1)
1324 first_bf_of_primit_atom(i_atom:n_atom) = first_bf_of_primit_atom(i_atom:n_atom) &
1329 CALL timestop(handle)
1331 END SUBROUTINE get_basis_function_index_of_primitive_atoms
1342 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dos_pdos_ldos'
1344 INTEGER :: handle, homo, homo_1, homo_2, &
1345 homo_spinor, ikp, ispin, n_ao, n_e, &
1347 REAL(kind=
dp) :: broadening, e_max, e_max_g0w0, e_min, &
1348 e_min_g0w0, e_total_window, &
1349 energy_step_dos, energy_window_dos
1350 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos_g0w0, dos_g0w0_soc, dos_scf, dos_scf_soc, &
1351 eigenval, eigenval_spinor, eigenval_spinor_g0w0, eigenval_spinor_no_soc
1352 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos_g0w0, pdos_g0w0_soc, pdos_scf, &
1353 pdos_scf_soc, proj_mo_on_kind
1354 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_g0w0_2d, ldos_scf_2d, &
1357 band_edges_scf, band_edges_scf_guess, &
1359 TYPE(
cp_cfm_type) :: cfm_ks_ikp, cfm_ks_ikp_spinor, cfm_mos_ikp_spinor, cfm_s_ikp, &
1360 cfm_s_ikp_copy, cfm_s_ikp_spinor, cfm_s_ikp_spinor_copy, cfm_soc_ikp_spinor, &
1361 cfm_spinor_wf_ikp, cfm_work_ikp, cfm_work_ikp_spinor
1364 CALL timeset(routinen, handle)
1368 energy_window_dos = bs_env%energy_window_DOS
1369 energy_step_dos = bs_env%energy_step_DOS
1370 broadening = bs_env%broadening_DOS
1373 IF (bs_env%do_gw)
THEN
1374 band_edges_scf = bs_env%band_edges_scf
1375 band_edges_scf_guess = band_edges_scf
1378 IF (bs_env%n_spin == 1)
THEN
1379 homo = bs_env%n_occ(1)
1380 band_edges_scf_guess%VBM = bs_env%eigenval_scf_Gamma(homo, 1)
1381 band_edges_scf_guess%CBM = bs_env%eigenval_scf_Gamma(homo + 1, 1)
1383 homo_1 = bs_env%n_occ(1)
1384 homo_2 = bs_env%n_occ(2)
1385 band_edges_scf_guess%VBM = max(bs_env%eigenval_scf_Gamma(homo_1, 1), &
1386 bs_env%eigenval_scf_Gamma(homo_2, 2))
1387 band_edges_scf_guess%CBM = min(bs_env%eigenval_scf_Gamma(homo_1 + 1, 1), &
1388 bs_env%eigenval_scf_Gamma(homo_2 + 1, 2))
1392 band_edges_scf%VBM = -1000.0_dp
1393 band_edges_scf%CBM = 1000.0_dp
1394 band_edges_scf%DBG = 1000.0_dp
1397 e_min = band_edges_scf_guess%VBM - 0.5_dp*energy_window_dos
1398 e_max = band_edges_scf_guess%CBM + 0.5_dp*energy_window_dos
1400 IF (bs_env%do_gw)
THEN
1401 band_edges_g0w0 = bs_env%band_edges_G0W0
1402 e_min_g0w0 = band_edges_g0w0%VBM - 0.5_dp*energy_window_dos
1403 e_max_g0w0 = band_edges_g0w0%CBM + 0.5_dp*energy_window_dos
1404 e_min = min(e_min, e_min_g0w0)
1405 e_max = max(e_max, e_max_g0w0)
1408 e_total_window = e_max - e_min
1410 n_e = int(e_total_window/energy_step_dos)
1412 ALLOCATE (dos_scf(n_e))
1414 ALLOCATE (dos_scf_soc(n_e))
1415 dos_scf_soc(:) = 0.0_dp
1419 ALLOCATE (pdos_scf(n_e, nkind))
1420 pdos_scf(:, :) = 0.0_dp
1421 ALLOCATE (pdos_scf_soc(n_e, nkind))
1422 pdos_scf_soc(:, :) = 0.0_dp
1424 ALLOCATE (proj_mo_on_kind(n_ao, nkind))
1425 proj_mo_on_kind(:, :) = 0.0_dp
1427 ALLOCATE (eigenval(n_ao))
1428 ALLOCATE (eigenval_spinor(2*n_ao))
1429 ALLOCATE (eigenval_spinor_no_soc(2*n_ao))
1430 ALLOCATE (eigenval_spinor_g0w0(2*n_ao))
1432 IF (bs_env%do_gw)
THEN
1434 ALLOCATE (dos_g0w0(n_e))
1435 dos_g0w0(:) = 0.0_dp
1436 ALLOCATE (dos_g0w0_soc(n_e))
1437 dos_g0w0_soc(:) = 0.0_dp
1439 ALLOCATE (pdos_g0w0(n_e, nkind))
1440 pdos_g0w0(:, :) = 0.0_dp
1441 ALLOCATE (pdos_g0w0_soc(n_e, nkind))
1442 pdos_g0w0_soc(:, :) = 0.0_dp
1446 CALL cp_cfm_create(cfm_mos_ikp(1), bs_env%fm_ks_Gamma(1)%matrix_struct)
1447 CALL cp_cfm_create(cfm_mos_ikp(2), bs_env%fm_ks_Gamma(1)%matrix_struct)
1448 CALL cp_cfm_create(cfm_work_ikp, bs_env%fm_ks_Gamma(1)%matrix_struct)
1449 CALL cp_cfm_create(cfm_s_ikp_copy, bs_env%fm_ks_Gamma(1)%matrix_struct)
1451 IF (bs_env%do_soc)
THEN
1453 CALL cp_cfm_create(cfm_mos_ikp_spinor, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1454 CALL cp_cfm_create(cfm_work_ikp_spinor, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1455 CALL cp_cfm_create(cfm_s_ikp_spinor_copy, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1456 CALL cp_cfm_create(cfm_ks_ikp_spinor, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1457 CALL cp_cfm_create(cfm_soc_ikp_spinor, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1458 CALL cp_cfm_create(cfm_s_ikp_spinor, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1459 CALL cp_cfm_create(cfm_spinor_wf_ikp, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1461 homo_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
1463 band_edges_scf_soc%VBM = -1000.0_dp
1464 band_edges_scf_soc%CBM = 1000.0_dp
1465 band_edges_scf_soc%DBG = 1000.0_dp
1467 IF (bs_env%do_gw)
THEN
1468 band_edges_g0w0_soc%VBM = -1000.0_dp
1469 band_edges_g0w0_soc%CBM = 1000.0_dp
1470 band_edges_g0w0_soc%DBG = 1000.0_dp
1475 IF (bs_env%do_ldos)
THEN
1479 IF (bs_env%unit_nr > 0)
THEN
1480 WRITE (bs_env%unit_nr,
'(A)')
''
1483 DO ikp = 1, bs_env%kpoints_DOS%nkp
1487 DO ispin = 1, bs_env%n_spin
1491 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
1495 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
1499 CALL cp_cfm_geeig(cfm_ks_ikp, cfm_s_ikp_copy, cfm_mos_ikp(ispin), &
1500 eigenval, cfm_work_ikp)
1504 CALL compute_proj_mo_on_kind(proj_mo_on_kind, qs_env, cfm_mos_ikp(ispin), cfm_s_ikp)
1507 CALL add_to_dos_pdos(dos_scf, pdos_scf, eigenval, ikp, bs_env, n_e, e_min, &
1509 IF (bs_env%do_gw)
THEN
1510 CALL add_to_dos_pdos(dos_g0w0, pdos_g0w0, bs_env%eigenval_G0W0(:, ikp, ispin), &
1511 ikp, bs_env, n_e, e_min, proj_mo_on_kind)
1514 IF (bs_env%do_ldos)
THEN
1515 CALL add_to_ldos_2d(ldos_scf_2d, qs_env, ikp, bs_env, cfm_mos_ikp(ispin), &
1516 eigenval(:), band_edges_scf_guess)
1518 IF (bs_env%do_gw)
THEN
1519 CALL add_to_ldos_2d(ldos_g0w0_2d, qs_env, ikp, bs_env, cfm_mos_ikp(ispin), &
1520 bs_env%eigenval_G0W0(:, ikp, 1), band_edges_g0w0)
1525 homo = bs_env%n_occ(ispin)
1527 band_edges_scf%VBM = max(band_edges_scf%VBM, eigenval(homo))
1528 band_edges_scf%CBM = min(band_edges_scf%CBM, eigenval(homo + 1))
1529 band_edges_scf%DBG = min(band_edges_scf%DBG, eigenval(homo + 1) - eigenval(homo))
1534 IF (bs_env%do_soc)
THEN
1537 CALL soc(bs_env, qs_env, ikp, bs_env%eigenval_scf, band_edges_scf, e_min, cfm_mos_ikp, &
1538 dos_scf_soc, pdos_scf_soc, band_edges_scf_soc, eigenval_spinor, &
1541 IF (.NOT. bs_env%do_gw)
CALL write_soc_eigenvalues(eigenval_spinor,
"SCF", ikp, bs_env)
1543 IF (bs_env%do_ldos)
THEN
1544 CALL add_to_ldos_2d(ldos_scf_2d_soc, qs_env, ikp, bs_env, cfm_spinor_wf_ikp, &
1545 eigenval_spinor, band_edges_scf_guess, .true., cfm_work_ikp)
1548 IF (bs_env%do_gw)
THEN
1551 CALL soc(bs_env, qs_env, ikp, bs_env%eigenval_G0W0, band_edges_g0w0, &
1552 e_min, cfm_mos_ikp, dos_g0w0_soc, pdos_g0w0_soc, &
1553 band_edges_g0w0_soc, eigenval_spinor_g0w0, cfm_spinor_wf_ikp)
1557 CALL write_soc_eigenvalues(eigenval_spinor,
"SCF_and_G0W0", ikp, bs_env, &
1558 eigenval_spinor_g0w0)
1564 IF (bs_env%unit_nr > 0)
THEN
1565 WRITE (bs_env%unit_nr,
'(T2,A,T43,I5,A,I3,A,F7.1,A)') &
1566 'Compute DOS, LDOS for k-point ', ikp,
' /', bs_env%kpoints_DOS%nkp, &
1567 ', Execution time',
m_walltime() - bs_env%t1,
' s'
1572 band_edges_scf%IDBG = band_edges_scf%CBM - band_edges_scf%VBM
1573 IF (bs_env%do_soc)
THEN
1574 band_edges_scf_soc%IDBG = band_edges_scf_soc%CBM - band_edges_scf_soc%VBM
1575 IF (bs_env%do_gw)
THEN
1576 band_edges_g0w0_soc%IDBG = band_edges_g0w0_soc%CBM - band_edges_g0w0_soc%VBM
1580 CALL write_band_edges(band_edges_scf,
"SCF", bs_env)
1581 CALL write_dos_pdos(dos_scf, pdos_scf, bs_env, qs_env,
"SCF", e_min, band_edges_scf%VBM)
1582 IF (bs_env%do_ldos)
THEN
1583 CALL print_ldos_main(ldos_scf_2d, bs_env, band_edges_scf,
"SCF")
1586 IF (bs_env%do_soc)
THEN
1587 CALL write_band_edges(band_edges_scf_soc,
"SCF+SOC", bs_env)
1588 CALL write_dos_pdos(dos_scf_soc, pdos_scf_soc, bs_env, qs_env,
"SCF_SOC", &
1589 e_min, band_edges_scf_soc%VBM)
1590 IF (bs_env%do_ldos)
THEN
1593 CALL print_ldos_main(ldos_scf_2d_soc, bs_env, band_edges_scf, &
1598 IF (bs_env%do_gw)
THEN
1599 CALL write_band_edges(band_edges_g0w0,
"G0W0", bs_env)
1600 CALL write_dos_pdos(dos_g0w0, pdos_g0w0, bs_env, qs_env,
"G0W0", e_min, &
1601 band_edges_g0w0%VBM)
1602 IF (bs_env%do_ldos)
THEN
1603 CALL print_ldos_main(ldos_g0w0_2d, bs_env, band_edges_g0w0,
"G0W0")
1607 IF (bs_env%do_soc .AND. bs_env%do_gw)
THEN
1608 CALL write_band_edges(band_edges_g0w0_soc,
"G0W0+SOC", bs_env)
1609 CALL write_dos_pdos(dos_g0w0_soc, pdos_g0w0_soc, bs_env, qs_env,
"G0W0_SOC", e_min, &
1610 band_edges_g0w0_soc%VBM)
1628 CALL timestop(handle)
1639 SUBROUTINE print_ldos_main(LDOS_2d, bs_env, band_edges, scf_gw_soc)
1640 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d
1643 CHARACTER(LEN=*) :: scf_gw_soc
1645 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_LDOS_main'
1647 INTEGER :: handle, i_x, i_x_bin, i_x_end, i_x_end_bin, i_x_end_glob, i_x_start, &
1648 i_x_start_bin, i_x_start_glob, i_y, i_y_bin, i_y_end, i_y_end_bin, i_y_end_glob, &
1649 i_y_start, i_y_start_bin, i_y_start_glob, n_e
1650 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: n_sum_for_bins
1651 INTEGER,
DIMENSION(2) :: bin_mesh
1652 LOGICAL :: do_xy_bins
1653 REAL(kind=
dp) :: e_min, energy_step, energy_window
1654 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d_bins
1656 CALL timeset(routinen, handle)
1658 n_e =
SIZE(ldos_2d, 3)
1660 energy_window = bs_env%energy_window_DOS
1661 energy_step = bs_env%energy_step_DOS
1662 e_min = band_edges%VBM - 0.5_dp*energy_window
1664 bin_mesh(1:2) = bs_env%bin_mesh(1:2)
1665 do_xy_bins = (bin_mesh(1) > 0 .AND. bin_mesh(2) > 0)
1667 i_x_start = lbound(ldos_2d, 1)
1668 i_x_end = ubound(ldos_2d, 1)
1669 i_y_start = lbound(ldos_2d, 2)
1670 i_y_end = ubound(ldos_2d, 2)
1672 IF (do_xy_bins)
THEN
1674 i_x_end_bin = bin_mesh(1)
1676 i_y_end_bin = bin_mesh(2)
1678 i_x_start_bin = i_x_start
1679 i_x_end_bin = i_x_end
1680 i_y_start_bin = i_y_start
1681 i_y_end_bin = i_y_end
1684 ALLOCATE (ldos_2d_bins(i_x_start_bin:i_x_end_bin, i_y_start_bin:i_y_end_bin, n_e))
1685 ldos_2d_bins(:, :, :) = 0.0_dp
1687 IF (do_xy_bins)
THEN
1689 i_x_start_glob = i_x_start
1690 i_x_end_glob = i_x_end
1691 i_y_start_glob = i_y_start
1692 i_y_end_glob = i_y_end
1694 CALL bs_env%para_env%min(i_x_start_glob)
1695 CALL bs_env%para_env%max(i_x_end_glob)
1696 CALL bs_env%para_env%min(i_y_start_glob)
1697 CALL bs_env%para_env%max(i_y_end_glob)
1699 ALLOCATE (n_sum_for_bins(bin_mesh(1), bin_mesh(2)))
1700 n_sum_for_bins(:, :) = 0
1703 DO i_x = i_x_start, i_x_end
1704 DO i_y = i_y_start, i_y_end
1705 i_x_bin = bin_mesh(1)*(i_x - i_x_start_glob)/(i_x_end_glob - i_x_start_glob + 1) + 1
1706 i_y_bin = bin_mesh(2)*(i_y - i_y_start_glob)/(i_y_end_glob - i_y_start_glob + 1) + 1
1707 ldos_2d_bins(i_x_bin, i_y_bin, :) = ldos_2d_bins(i_x_bin, i_y_bin, :) + &
1708 ldos_2d(i_x, i_y, :)
1709 n_sum_for_bins(i_x_bin, i_y_bin) = n_sum_for_bins(i_x_bin, i_y_bin) + 1
1713 CALL bs_env%para_env%sum(ldos_2d_bins)
1714 CALL bs_env%para_env%sum(n_sum_for_bins)
1717 DO i_x_bin = 1, bin_mesh(1)
1718 DO i_y_bin = 1, bin_mesh(2)
1719 ldos_2d_bins(i_x_bin, i_y_bin, :) = ldos_2d_bins(i_x_bin, i_y_bin, :)/ &
1720 REAL(n_sum_for_bins(i_x_bin, i_y_bin), kind=
dp)
1726 ldos_2d_bins(:, :, :) = ldos_2d(:, :, :)
1730 IF (bin_mesh(1)*bin_mesh(2) < bs_env%n_bins_max_for_printing)
THEN
1731 CALL print_ldos_2d_bins(ldos_2d_bins, bs_env, e_min, scf_gw_soc)
1733 cpwarn(
"The number of bins for the LDOS is too large. Decrease BIN_MESH.")
1736 CALL timestop(handle)
1738 END SUBROUTINE print_ldos_main
1747 SUBROUTINE print_ldos_2d_bins(LDOS_2d_bins, bs_env, E_min, scf_gw_soc)
1748 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d_bins
1750 REAL(kind=
dp) :: e_min
1751 CHARACTER(LEN=*) :: scf_gw_soc
1753 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_LDOS_2d_bins'
1755 CHARACTER(LEN=18) :: print_format
1756 CHARACTER(LEN=4) :: print_format_1, print_format_2
1757 CHARACTER(len=default_string_length) :: fname
1758 INTEGER :: handle, i_e, i_x, i_x_end, i_x_start, &
1759 i_y, i_y_end, i_y_start, iunit, n_e, &
1761 REAL(kind=
dp) :: energy
1762 REAL(kind=
dp),
DIMENSION(3) :: coord,
idx
1764 CALL timeset(routinen, handle)
1766 i_x_start = lbound(ldos_2d_bins, 1)
1767 i_x_end = ubound(ldos_2d_bins, 1)
1768 i_y_start = lbound(ldos_2d_bins, 2)
1769 i_y_end = ubound(ldos_2d_bins, 2)
1770 n_e =
SIZE(ldos_2d_bins, 3)
1772 n_x = i_x_end - i_x_start + 1
1773 n_y = i_y_end - i_y_start + 1
1775 IF (bs_env%para_env%is_source())
THEN
1777 DO i_x = i_x_start, i_x_end
1778 DO i_y = i_y_start, i_y_end
1780 idx(1) = (real(i_x, kind=
dp) - 0.5_dp)/real(n_x, kind=
dp)
1781 idx(2) = (real(i_y, kind=
dp) - 0.5_dp)/real(n_y, kind=
dp)
1783 coord(1:3) = matmul(bs_env%hmat,
idx)
1785 CALL get_print_format(coord(1), print_format_1)
1786 CALL get_print_format(coord(2), print_format_2)
1788 print_format =
"(3A,"//print_format_1//
",A,"//print_format_2//
",A)"
1790 WRITE (fname, print_format)
"LDOS_", scf_gw_soc, &
1793 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", &
1794 file_action=
"WRITE")
1796 WRITE (iunit,
"(2A)") Ã…
" Energy E (eV) average LDOS(x,y,E) (1/(eV*^2), ", &
1797 "integrated over z, averaged inside bin)"
1800 energy = e_min + i_e*bs_env%energy_step_DOS
1801 WRITE (iunit,
"(2F17.3)") energy*
evolt, &
1802 ldos_2d_bins(i_x, i_y, i_e)* &
1803 bs_env%unit_ldos_int_z_inv_Ang2_eV
1813 CALL timestop(handle)
1815 END SUBROUTINE print_ldos_2d_bins
1822 SUBROUTINE get_print_format(coord, print_format)
1823 REAL(kind=
dp) :: coord
1824 CHARACTER(LEN=4) :: print_format
1826 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_print_format'
1830 CALL timeset(routinen, handle)
1833 print_format =
"F9.2"
1834 ELSE IF (coord < -1000/
angstrom)
THEN
1835 print_format =
"F8.2"
1836 ELSE IF (coord < -100/
angstrom)
THEN
1837 print_format =
"F7.2"
1838 ELSE IF (coord < -10/
angstrom)
THEN
1839 print_format =
"F6.2"
1841 print_format =
"F5.2"
1843 print_format =
"F4.2"
1844 ELSE IF (coord < 100/
angstrom)
THEN
1845 print_format =
"F5.2"
1846 ELSE IF (coord < 1000/
angstrom)
THEN
1847 print_format =
"F6.2"
1848 ELSE IF (coord < 10000/
angstrom)
THEN
1849 print_format =
"F7.2"
1851 print_format =
"F8.2"
1854 CALL timestop(handle)
1856 END SUBROUTINE get_print_format
1873 SUBROUTINE soc(bs_env, qs_env, ikp, eigenval_no_SOC, band_edges_no_SOC, E_min, cfm_mos_ikp, &
1874 DOS, PDOS, band_edges, eigenval_spinor, cfm_spinor_wf_ikp)
1879 REAL(kind=
dp),
DIMENSION(:, :, :) :: eigenval_no_soc
1881 REAL(kind=
dp) :: e_min
1883 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos
1884 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
1886 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor
1889 CHARACTER(LEN=*),
PARAMETER :: routinen =
'SOC'
1891 INTEGER :: handle, homo_spinor, n_ao, n_e, nkind
1892 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor_no_soc
1893 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind_spinor
1895 cfm_ks_ikp_spinor, cfm_mos_ikp_spinor, &
1896 cfm_soc_ikp_spinor, cfm_work_ikp_spinor
1898 CALL timeset(routinen, handle)
1901 homo_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
1903 nkind =
SIZE(pdos, 2)
1905 CALL cp_cfm_create(cfm_ks_ikp_spinor, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1906 CALL cp_cfm_create(cfm_soc_ikp_spinor, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1907 CALL cp_cfm_create(cfm_mos_ikp_spinor, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1908 CALL cp_cfm_create(cfm_work_ikp_spinor, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1909 CALL cp_cfm_create(cfm_eigenvec_ikp_spinor, bs_env%cfm_ks_spinor_ao_Gamma%matrix_struct)
1911 ALLOCATE (eigenval_spinor_no_soc(2*n_ao))
1912 ALLOCATE (proj_mo_on_kind_spinor(2*n_ao, nkind))
1914 proj_mo_on_kind_spinor(:, :) = 0.0_dp
1917 CALL cfm_ikp_from_cfm_spinor_gamma(cfm_soc_ikp_spinor, &
1918 bs_env%cfm_SOC_spinor_ao_Gamma, &
1919 bs_env%fm_s_Gamma%matrix_struct, &
1920 ikp, qs_env, bs_env%kpoints_DOS,
"ORB")
1928 CALL add_cfm_submat(cfm_mos_ikp_spinor, cfm_mos_ikp(bs_env%n_spin), n_ao + 1, n_ao + 1)
1932 cfm_mos_ikp_spinor, cfm_soc_ikp_spinor, &
1933 z_zero, cfm_work_ikp_spinor)
1937 cfm_work_ikp_spinor, cfm_mos_ikp_spinor, &
1938 z_zero, cfm_ks_ikp_spinor)
1943 eigenval_spinor_no_soc(1:n_ao) = eigenval_no_soc(1:n_ao, ikp, 1)
1944 eigenval_spinor_no_soc(n_ao + 1:) = eigenval_no_soc(1:n_ao, ikp, bs_env%n_spin)
1945 IF (bs_env%energy_window_soc > 0.0_dp)
THEN
1947 bs_env%energy_window_soc, &
1948 eigenval_spinor_no_soc, &
1949 band_edges_no_soc%VBM, &
1950 band_edges_no_soc%CBM)
1957 CALL cp_cfm_heevd(cfm_ks_ikp_spinor, cfm_eigenvec_ikp_spinor, eigenval_spinor)
1960 CALL add_to_dos_pdos(dos, pdos, eigenval_spinor, &
1961 ikp, bs_env, n_e, e_min, proj_mo_on_kind_spinor)
1964 band_edges%VBM = max(band_edges%VBM, eigenval_spinor(homo_spinor))
1965 band_edges%CBM = min(band_edges%CBM, eigenval_spinor(homo_spinor + 1))
1966 band_edges%DBG = min(band_edges%DBG, eigenval_spinor(homo_spinor + 1) &
1967 - eigenval_spinor(homo_spinor))
1971 cfm_mos_ikp_spinor, cfm_eigenvec_ikp_spinor, &
1972 z_zero, cfm_spinor_wf_ikp)
1980 CALL timestop(handle)
1995 SUBROUTINE add_to_dos_pdos(DOS, PDOS, eigenval, ikp, bs_env, n_E, E_min, proj_mo_on_kind)
1997 REAL(kind=
dp),
DIMENSION(:) :: dos
1998 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
1999 REAL(kind=
dp),
DIMENSION(:) :: eigenval
2003 REAL(kind=
dp) :: e_min
2004 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind
2006 CHARACTER(LEN=*),
PARAMETER :: routinen =
'add_to_DOS_PDOS'
2008 INTEGER :: handle, i_e, i_kind, i_mo, n_mo, &
2009 n_primitive_cells, nkind
2010 REAL(kind=
dp) :: broadening, energy, energy_step_dos, wkp
2012 CALL timeset(routinen, handle)
2014 energy_step_dos = bs_env%energy_step_DOS
2015 broadening = bs_env%broadening_DOS
2017 n_primitive_cells = 1
2018 IF (bs_env%do_bs) n_primitive_cells = bs_env%n_primitive_cells
2020 n_mo =
SIZE(eigenval)
2021 nkind =
SIZE(proj_mo_on_kind, 2)
2024 wkp = bs_env%kpoints_DOS%wkp(ikp)/n_primitive_cells*bs_env%spin_degeneracy
2026 energy = e_min + i_e*energy_step_dos
2029 dos(i_e) = dos(i_e) + wkp*
gaussian(energy - eigenval(i_mo), broadening)
2032 DO i_kind = 1, nkind
2033 IF (proj_mo_on_kind(i_mo, i_kind) > 0.0_dp)
THEN
2034 pdos(i_e, i_kind) = pdos(i_e, i_kind) + &
2035 proj_mo_on_kind(i_mo, i_kind)*wkp* &
2036 gaussian(energy - eigenval(i_mo), broadening)
2042 CALL timestop(handle)
2044 END SUBROUTINE add_to_dos_pdos
2058 SUBROUTINE add_to_ldos_2d(LDOS_2d, qs_env, ikp, bs_env, cfm_mos_ikp, eigenval, &
2059 band_edges, do_spinor, cfm_non_spinor)
2060 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: ldos_2d
2065 REAL(kind=
dp),
DIMENSION(:) :: eigenval
2067 LOGICAL,
OPTIONAL :: do_spinor
2070 CHARACTER(LEN=*),
PARAMETER :: routinen =
'add_to_LDOS_2d'
2072 INTEGER :: handle, i_e, i_x_end, i_x_start, i_y_end, i_y_start, i_z, i_z_end, i_z_start, &
2073 j_col, j_mo, n_e, n_mo, n_z, ncol_local, nimages, z_end_global, z_start_global
2074 INTEGER,
DIMENSION(:),
POINTER :: col_indices
2075 LOGICAL :: is_any_weight_non_zero, my_do_spinor
2076 REAL(kind=
dp) :: broadening, e_max, e_min, &
2077 e_total_window, energy, energy_step, &
2078 energy_window, spin_degeneracy, weight
2079 TYPE(
cp_cfm_type) :: cfm_weighted_dm_ikp, cfm_work
2080 TYPE(
cp_fm_type) :: fm_non_spinor, fm_weighted_dm_mic
2081 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: weighted_dm_mic
2089 CALL timeset(routinen, handle)
2091 my_do_spinor = .false.
2092 IF (
PRESENT(do_spinor)) my_do_spinor = do_spinor
2094 CALL get_qs_env(qs_env, ks_env=ks_env, pw_env=pw_env, dft_control=dft_control)
2097 nimages = dft_control%nimages
2098 dft_control%nimages = 1
2100 energy_window = bs_env%energy_window_DOS
2101 energy_step = bs_env%energy_step_DOS
2102 broadening = bs_env%broadening_DOS
2104 e_min = band_edges%VBM - 0.5_dp*energy_window
2105 e_max = band_edges%CBM + 0.5_dp*energy_window
2106 e_total_window = e_max - e_min
2108 n_e = int(e_total_window/energy_step)
2110 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
2112 CALL auxbas_pw_pool%create_pw(ldos_3d)
2113 CALL auxbas_pw_pool%create_pw(rho_g)
2115 i_x_start = lbound(ldos_3d%array, 1)
2116 i_x_end = ubound(ldos_3d%array, 1)
2117 i_y_start = lbound(ldos_3d%array, 2)
2118 i_y_end = ubound(ldos_3d%array, 2)
2119 i_z_start = lbound(ldos_3d%array, 3)
2120 i_z_end = ubound(ldos_3d%array, 3)
2122 z_start_global = i_z_start
2123 z_end_global = i_z_end
2125 CALL bs_env%para_env%min(z_start_global)
2126 CALL bs_env%para_env%max(z_end_global)
2127 n_z = z_end_global - z_start_global + 1
2129 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)) &
2130 cpabort(°
"Please choose a cell that has 90 angles to the z-direction.")
2132 bs_env%unit_ldos_int_z_inv_Ang2_eV = bs_env%hmat(3, 3)/real(n_z, kind=
dp)/
evolt/
angstrom**2
2135 ALLOCATE (ldos_2d(i_x_start:i_x_end, i_y_start:i_y_end, n_e))
2136 ldos_2d(:, :, :) = 0.0_dp
2140 CALL cp_cfm_create(cfm_weighted_dm_ikp, cfm_mos_ikp%matrix_struct)
2141 CALL cp_fm_create(fm_weighted_dm_mic, cfm_mos_ikp%matrix_struct)
2142 IF (my_do_spinor)
THEN
2143 CALL cp_fm_create(fm_non_spinor, cfm_non_spinor%matrix_struct)
2148 ncol_local=ncol_local, &
2149 col_indices=col_indices)
2151 NULLIFY (weighted_dm_mic)
2153 ALLOCATE (weighted_dm_mic(1)%matrix)
2154 CALL dbcsr_create(weighted_dm_mic(1)%matrix, template=bs_env%mat_ao_ao%matrix, &
2155 matrix_type=dbcsr_type_symmetric)
2159 energy = e_min + i_e*energy_step
2161 is_any_weight_non_zero = .false.
2163 DO j_col = 1, ncol_local
2165 j_mo = col_indices(j_col)
2167 IF (my_do_spinor)
THEN
2168 spin_degeneracy = 1.0_dp
2170 spin_degeneracy = bs_env%spin_degeneracy
2173 weight =
gaussian(energy - eigenval(j_mo), broadening)*spin_degeneracy
2175 cfm_work%local_data(:, j_col) = cfm_mos_ikp%local_data(:, j_col)*weight
2177 IF (weight > 1.0e-5_dp) is_any_weight_non_zero = .true.
2181 CALL bs_env%para_env%sync()
2182 CALL bs_env%para_env%sum(is_any_weight_non_zero)
2183 CALL bs_env%para_env%sync()
2186 IF (is_any_weight_non_zero)
THEN
2189 cfm_mos_ikp, cfm_work,
z_zero, cfm_weighted_dm_ikp)
2191 IF (my_do_spinor)
THEN
2197 cfm_non_spinor, ikp, bs_env%kpoints_DOS, &
2198 "ORB", bs_env%kpoints_DOS%wkp(ikp))
2201 CALL get_cfm_submat(cfm_non_spinor, cfm_weighted_dm_ikp, n_mo/2, n_mo/2)
2203 cfm_non_spinor, ikp, bs_env%kpoints_DOS, &
2204 "ORB", bs_env%kpoints_DOS%wkp(ikp))
2206 keep_sparsity=.false.)
2210 cfm_weighted_dm_ikp, ikp, bs_env%kpoints_DOS, &
2211 "ORB", bs_env%kpoints_DOS%wkp(ikp))
2213 keep_sparsity=.false.)
2216 ldos_3d%array(:, :, :) = 0.0_dp
2223 DO i_z = i_z_start, i_z_end
2224 ldos_2d(:, :, i_e) = ldos_2d(:, :, i_e) + ldos_3d%array(:, :, i_z)
2232 dft_control%nimages = nimages
2234 CALL auxbas_pw_pool%give_back_pw(ldos_3d)
2235 CALL auxbas_pw_pool%give_back_pw(rho_g)
2244 IF (my_do_spinor)
THEN
2248 CALL timestop(handle)
2250 END SUBROUTINE add_to_ldos_2d
2260 SUBROUTINE write_soc_eigenvalues(eigenval_spinor, scf_gw, ikp, bs_env, eigenval_spinor_G0W0)
2262 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_spinor
2263 CHARACTER(LEN=*) :: scf_gw
2266 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: eigenval_spinor_g0w0
2268 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_SOC_eigenvalues'
2270 CHARACTER(len=3) :: occ_vir
2271 CHARACTER(LEN=default_string_length) :: fname
2272 INTEGER :: handle, i_mo, iunit, n_occ_spinor
2274 CALL timeset(routinen, handle)
2276 CALL get_fname(fname, bs_env, ikp, scf_gw, soc=.true.)
2278 IF (bs_env%para_env%is_source())
THEN
2280 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", file_action=
"WRITE")
2282 WRITE (iunit,
"(A)")
" "
2283 WRITE (iunit,
"(A10,3F10.4)")
"kpoint: ", bs_env%kpoints_DOS%xkp(:, ikp)
2284 WRITE (iunit,
"(A)")
" "
2286 n_occ_spinor = bs_env%n_occ(1) + bs_env%n_occ(bs_env%n_spin)
2288 DO i_mo = 1,
SIZE(eigenval_spinor)
2289 IF (i_mo .LE. n_occ_spinor) occ_vir =
'occ'
2290 IF (i_mo > n_occ_spinor) occ_vir =
'vir'
2291 IF (
PRESENT(eigenval_spinor_g0w0))
THEN
2293 WRITE (iunit,
"(I5,3A,4F16.3,2F17.3)") i_mo,
' (', occ_vir,
') ', &
2294 eigenval_spinor(i_mo)*
evolt, eigenval_spinor_g0w0(i_mo)*
evolt
2297 WRITE (iunit,
"(I5,3A,4F16.3,F17.3)") i_mo,
' (', occ_vir,
') ', &
2298 eigenval_spinor(i_mo)*
evolt
2306 CALL timestop(handle)
2308 END SUBROUTINE write_soc_eigenvalues
2319 SUBROUTINE get_fname(fname, bs_env, ikp, scf_gw, ispin, SOC)
2320 CHARACTER(len=default_string_length) :: fname
2323 CHARACTER(len=*) :: scf_gw
2324 INTEGER,
OPTIONAL :: ispin
2325 LOGICAL,
OPTIONAL :: soc
2327 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_fname'
2329 CHARACTER(len=1) :: digits_ikp
2330 CHARACTER(len=default_string_length) :: core_name
2331 INTEGER :: handle, n_zeros
2334 CALL timeset(routinen, handle)
2337 IF (
PRESENT(soc)) my_soc = soc
2339 n_zeros = count_digits(bs_env%kpoints_DOS%nkp) - count_digits(ikp)
2341 WRITE (digits_ikp,
'(I1)') count_digits(ikp)
2343 IF (bs_env%kpoints_DOS%nkp == 1)
THEN
2345 core_name = trim(scf_gw)//
"_eigenvalues"
2348 core_name = trim(scf_gw)//
"_band_struct_kp"
2351 SELECT CASE (n_zeros)
2353 WRITE (fname,
"(2A,I"//digits_ikp//
")") trim(core_name),
"_", ikp
2355 WRITE (fname,
"(2A,I"//digits_ikp//
")") trim(core_name),
"_0", ikp
2357 WRITE (fname,
"(2A,I"//digits_ikp//
")") trim(core_name),
"_00", ikp
2359 WRITE (fname,
"(2A,I"//digits_ikp//
")") trim(core_name),
"_000", ikp
2361 cpabort(
"Too many zeros.")
2365 IF (ikp == 1 .AND. bs_env%kpoints_DOS%nkp == 1)
THEN
2366 WRITE (fname,
"(A)") trim(core_name)
2370 WRITE (fname,
"(2A)") trim(fname),
"_+_SOC"
2373 IF (bs_env%n_spin == 2 .AND. .NOT. my_soc)
THEN
2374 cpassert(
PRESENT(ispin))
2375 WRITE (fname,
"(2A,I1)") trim(fname),
"_spin_", ispin
2378 CALL timestop(handle)
2387 PURE FUNCTION count_digits(int_number)
2389 INTEGER,
INTENT(IN) :: int_number
2390 INTEGER :: count_digits
2392 INTEGER :: digitcount, tempint
2396 tempint = int_number
2398 DO WHILE (tempint /= 0)
2399 tempint = tempint/10
2400 digitcount = digitcount + 1
2403 count_digits = digitcount
2405 END FUNCTION count_digits
2413 SUBROUTINE write_band_edges(band_edges, scf_gw_soc, bs_env)
2416 CHARACTER(LEN=*) :: scf_gw_soc
2419 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_band_edges'
2421 CHARACTER(LEN=17) :: print_format
2422 INTEGER :: handle, u
2424 CALL timeset(routinen, handle)
2427 print_format =
"(T2,2A,T61,F20.3)"
2431 WRITE (u,
'(T2,A)')
''
2432 WRITE (u, print_format) scf_gw_soc,
' valence band maximum (eV):', band_edges%VBM*
evolt
2433 WRITE (u, print_format) scf_gw_soc,
' conduction band minimum (eV):', band_edges%CBM*
evolt
2434 WRITE (u, print_format) scf_gw_soc,
' indirect band gap (eV):', band_edges%IDBG*
evolt
2435 WRITE (u, print_format) scf_gw_soc,
' direct band gap (eV):', band_edges%DBG*
evolt
2438 CALL timestop(handle)
2440 END SUBROUTINE write_band_edges
2452 SUBROUTINE write_dos_pdos(DOS, PDOS, bs_env, qs_env, scf_gw_soc, E_min, E_VBM)
2453 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dos
2454 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pdos
2457 CHARACTER(LEN=*) :: scf_gw_soc
2458 REAL(kind=
dp) :: e_min, e_vbm
2460 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_dos_pdos'
2462 CHARACTER(LEN=3),
DIMENSION(100) :: elements
2463 CHARACTER(LEN=default_string_length) :: atom_name, fname, output_string
2464 INTEGER :: handle, i_e, i_kind, iatom, iunit, n_a, &
2466 REAL(kind=
dp) :: energy
2469 CALL timeset(routinen, handle)
2471 WRITE (fname,
"(3A)")
"DOS_PDOS_", scf_gw_soc,
".out"
2474 nkind =
SIZE(pdos, 2)
2475 CALL get_qs_env(qs_env, particle_set=particle_set)
2477 IF (bs_env%para_env%is_source())
THEN
2479 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", file_action=
"WRITE")
2483 DO iatom = 1, bs_env%n_atom
2485 kind_number=i_kind, name=atom_name)
2486 elements(i_kind) = atom_name
2489 WRITE (output_string,
"(A,I1,A)")
"(", n_a,
"A)"
2491 WRITE (iunit, trim(output_string))
"Energy-E_F (eV) DOS (1/eV) PDOS (1/eV) ", &
2492 " of atom type ", elements(1:nkind)
2494 WRITE (output_string,
"(A,I1,A)")
"(", n_a,
"F13.5)"
2498 energy = e_min + i_e*bs_env%energy_step_DOS - e_vbm
2499 WRITE (iunit, trim(output_string)) energy*
evolt, dos(i_e)/
evolt, pdos(i_e, :)/
evolt
2506 CALL timestop(handle)
2508 END SUBROUTINE write_dos_pdos
2516 PURE FUNCTION gaussian(energy, broadening)
2518 REAL(kind=
dp),
INTENT(IN) :: energy, broadening
2521 IF (abs(energy) < 5*broadening)
THEN
2522 gaussian = 1.0_dp/broadening/sqrt(
twopi)*exp(-0.5_dp*energy**2/broadening**2)
2536 SUBROUTINE compute_proj_mo_on_kind(proj_mo_on_kind, qs_env, cfm_mos, cfm_s)
2537 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: proj_mo_on_kind
2541 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_proj_mo_on_kind'
2543 INTEGER :: handle, i_atom, i_global, i_kind, i_row, &
2544 j_col, n_ao, n_mo, ncol_local, nkind, &
2546 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf, kind_of
2547 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2549 TYPE(
cp_cfm_type) :: cfm_proj, cfm_s_i_kind, cfm_work
2552 CALL timeset(routinen, handle)
2554 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, nkind=nkind)
2559 nrow_local=nrow_local, &
2560 ncol_local=ncol_local, &
2561 row_indices=row_indices, &
2562 col_indices=col_indices)
2564 n_ao = qs_env%bs_env%n_ao
2566 ALLOCATE (atom_from_bf(n_ao))
2569 proj_mo_on_kind(:, :) = 0.0_dp
2577 DO i_kind = 1, nkind
2582 DO i_row = 1, nrow_local
2583 DO j_col = 1, ncol_local
2585 i_global = row_indices(i_row)
2587 IF (i_global .LE. n_ao)
THEN
2588 i_atom = atom_from_bf(i_global)
2589 ELSE IF (i_global .LE. 2*n_ao)
THEN
2590 i_atom = atom_from_bf(i_global - n_ao)
2592 cpabort(
"Wrong indices.")
2595 IF (i_kind .NE. kind_of(i_atom))
THEN
2596 cfm_s_i_kind%local_data(i_row, j_col) =
z_zero
2603 cfm_s_i_kind, cfm_mos,
z_zero, cfm_work)
2605 cfm_mos, cfm_work,
z_zero, cfm_proj)
2620 CALL timestop(handle)
2622 END SUBROUTINE compute_proj_mo_on_kind
2634 SUBROUTINE cfm_ikp_from_cfm_spinor_gamma(cfm_spinor_ikp, cfm_spinor_Gamma, fm_struct_non_spinor, &
2635 ikp, qs_env, kpoints, basis_type)
2636 TYPE(
cp_cfm_type) :: cfm_spinor_ikp, cfm_spinor_gamma
2641 CHARACTER(LEN=*) :: basis_type
2643 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cfm_ikp_from_cfm_spinor_Gamma'
2645 INTEGER :: handle, i_block, i_offset, j_block, &
2647 TYPE(
cp_cfm_type) :: cfm_non_spinor_gamma, cfm_non_spinor_ikp
2648 TYPE(
cp_fm_type) :: fm_non_spinor_gamma_im, &
2649 fm_non_spinor_gamma_re
2651 CALL timeset(routinen, handle)
2653 CALL cp_cfm_create(cfm_non_spinor_gamma, fm_struct_non_spinor)
2654 CALL cp_cfm_create(cfm_non_spinor_ikp, fm_struct_non_spinor)
2655 CALL cp_fm_create(fm_non_spinor_gamma_re, fm_struct_non_spinor)
2656 CALL cp_fm_create(fm_non_spinor_gamma_im, fm_struct_non_spinor)
2664 i_offset = i_block*n_ao + 1
2665 j_offset = j_block*n_ao + 1
2666 CALL get_cfm_submat(cfm_non_spinor_gamma, cfm_spinor_gamma, i_offset, j_offset)
2667 CALL cp_cfm_to_fm(cfm_non_spinor_gamma, fm_non_spinor_gamma_re, fm_non_spinor_gamma_im)
2671 ikp, qs_env, kpoints, basis_type)
2672 CALL add_cfm_submat(cfm_spinor_ikp, cfm_non_spinor_ikp, i_offset, j_offset)
2676 ikp, qs_env, kpoints, basis_type)
2687 CALL timestop(handle)
2689 END SUBROUTINE cfm_ikp_from_cfm_spinor_gamma
2706 CHARACTER(LEN=*) :: basis_type
2708 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cfm_ikp_from_fm_Gamma'
2710 INTEGER :: col_global, handle, i, i_atom, i_atom_old, i_cell, i_mic_cell, i_row, j, j_atom, &
2711 j_atom_old, j_cell, j_col, n_bf, ncol_local, nrow_local, num_cells, row_global
2712 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf
2713 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2714 INTEGER,
DIMENSION(:, :),
POINTER :: index_to_cell
2715 LOGICAL :: i_cell_is_the_minimum_image_cell
2716 REAL(kind=
dp) :: abs_rab_cell_i, abs_rab_cell_j, arg
2717 REAL(kind=
dp),
DIMENSION(3) :: cell_vector, cell_vector_j, rab_cell_i, &
2719 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
2723 CALL timeset(routinen, handle)
2725 IF (.NOT.
ASSOCIATED(cfm_ikp%local_data))
THEN
2731 nrow_local=nrow_local, &
2732 ncol_local=ncol_local, &
2733 row_indices=row_indices, &
2734 col_indices=col_indices)
2737 IF (basis_type ==
"ORB")
THEN
2738 n_bf = qs_env%bs_env%n_ao
2739 ELSE IF (basis_type ==
"RI_AUX")
THEN
2740 n_bf = qs_env%bs_env%n_RI
2742 cpabort(
"Only ORB and RI_AUX basis implemented.")
2745 ALLOCATE (atom_from_bf(n_bf))
2748 NULLIFY (cell, particle_set)
2749 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
2752 index_to_cell => kpoints%index_to_cell
2754 num_cells =
SIZE(index_to_cell, 2)
2758 DO i_row = 1, nrow_local
2759 DO j_col = 1, ncol_local
2761 row_global = row_indices(i_row)
2762 col_global = col_indices(j_col)
2764 i_atom = atom_from_bf(row_global)
2765 j_atom = atom_from_bf(col_global)
2768 IF (i_atom .NE. i_atom_old .OR. j_atom .NE. j_atom_old)
THEN
2769 DO i_cell = 1, num_cells
2772 IF (any(abs(index_to_cell(1:3, i_cell)) > 1)) cycle
2774 cell_vector(1:3) = matmul(hmat, real(index_to_cell(1:3, i_cell),
dp))
2776 rab_cell_i(1:3) =
pbc(particle_set(i_atom)%r(1:3), cell) - &
2777 (
pbc(particle_set(j_atom)%r(1:3), cell) + cell_vector(1:3))
2778 abs_rab_cell_i = sqrt(rab_cell_i(1)**2 + rab_cell_i(2)**2 + rab_cell_i(3)**2)
2781 i_cell_is_the_minimum_image_cell = .true.
2782 DO j_cell = 1, num_cells
2783 cell_vector_j(1:3) = matmul(hmat, real(index_to_cell(1:3, j_cell),
dp))
2784 rab_cell_j(1:3) =
pbc(particle_set(i_atom)%r(1:3), cell) - &
2785 (
pbc(particle_set(j_atom)%r(1:3), cell) + cell_vector_j(1:3))
2786 abs_rab_cell_j = sqrt(rab_cell_j(1)**2 + rab_cell_j(2)**2 + rab_cell_j(3)**2)
2788 IF (abs_rab_cell_i > abs_rab_cell_j + 1.0e-6_dp)
THEN
2789 i_cell_is_the_minimum_image_cell = .false.
2793 IF (i_cell_is_the_minimum_image_cell)
THEN
2800 arg = real(index_to_cell(1, i_mic_cell),
dp)*kpoints%xkp(1, ikp) + &
2801 REAL(index_to_cell(2, i_mic_cell),
dp)*kpoints%xkp(2, ikp) + &
2802 REAL(index_to_cell(3, i_mic_cell),
dp)*kpoints%xkp(3, ikp)
2807 cfm_ikp%local_data(i, j) = cos(
twopi*arg)*fm_gamma%local_data(i, j)*
z_one + &
2816 CALL timestop(handle)
2832 cfm_W_ikp_freq_j, ikp, kpoints, basis_type, wkp_ext)
2839 CHARACTER(LEN=*) :: basis_type
2840 REAL(kind=
dp),
OPTIONAL :: wkp_ext
2842 CHARACTER(LEN=*),
PARAMETER :: routinen =
'MIC_contribution_from_ikp'
2844 INTEGER :: handle, i_bf, iatom, iatom_old, irow, &
2845 j_bf, jatom, jatom_old, jcol, n_bf, &
2846 ncol_local, nrow_local, num_cells
2847 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_from_bf_index
2848 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2849 INTEGER,
DIMENSION(:, :),
POINTER :: index_to_cell
2850 REAL(kind=
dp) :: contribution, weight_im, weight_re, &
2852 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
2853 REAL(kind=
dp),
DIMENSION(:),
POINTER :: wkp
2854 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xkp
2858 CALL timeset(routinen, handle)
2861 IF (basis_type ==
"ORB")
THEN
2862 n_bf = qs_env%bs_env%n_ao
2863 ELSE IF (basis_type ==
"RI_AUX")
THEN
2864 n_bf = qs_env%bs_env%n_RI
2866 cpabort(
"Only ORB and RI_AUX basis implemented.")
2869 ALLOCATE (atom_from_bf_index(n_bf))
2872 NULLIFY (cell, particle_set)
2873 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
2877 nrow_local=nrow_local, &
2878 ncol_local=ncol_local, &
2879 row_indices=row_indices, &
2880 col_indices=col_indices)
2883 index_to_cell => kpoints%index_to_cell
2884 num_cells =
SIZE(index_to_cell, 2)
2889 DO irow = 1, nrow_local
2890 DO jcol = 1, ncol_local
2892 i_bf = row_indices(irow)
2893 j_bf = col_indices(jcol)
2895 iatom = atom_from_bf_index(i_bf)
2896 jatom = atom_from_bf_index(j_bf)
2898 IF (
PRESENT(wkp_ext))
THEN
2899 wkp_of_ikp = wkp_ext
2901 SELECT CASE (bs_env%l_RI(i_bf) + bs_env%l_RI(j_bf))
2904 wkp_of_ikp = wkp(ikp)
2907 wkp_of_ikp = bs_env%wkp_s_p(ikp)
2910 wkp_of_ikp = bs_env%wkp_no_extra(ikp)
2914 IF (iatom .NE. iatom_old .OR. jatom .NE. jatom_old)
THEN
2917 num_cells, iatom, jatom, xkp(1:3, ikp), wkp_of_ikp, &
2918 cell, index_to_cell, hmat, particle_set)
2925 contribution = weight_re*real(cfm_w_ikp_freq_j%local_data(irow, jcol)) + &
2926 weight_im*aimag(cfm_w_ikp_freq_j%local_data(irow, jcol))
2928 fm_w_mic_freq_j%local_data(irow, jcol) = fm_w_mic_freq_j%local_data(irow, jcol) &
2934 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.
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.
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_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...
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.
subroutine, public compute_xkp(xkp, ikp_start, ikp_end, grid)
...
subroutine, public kpoint_init_cell_index_simple(kpoints, qs_env)
...
Defines the basic variable types.
integer, parameter, public max_line_length
integer, parameter, public dp
integer, parameter, public default_string_length
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
Collection of simple mathematical functions and subroutines.
subroutine, public complex_diag(matrix, eigenvectors, eigenvalues)
Diagonalizes a local complex Hermitian matrix using LAPACK. Based on cp_cfm_heevd.
pure real(kind=dp) function, dimension(3, 3), public inv_3x3(a)
Returns the inverse of the 3 x 3 matrix a.
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 bandstructure_primitive_cell_spinor(qs_env, bs_env, eigenvalues, filename, cfm_h_gamma_spinor)
...
subroutine, public cfm_ikp_from_fm_gamma(cfm_ikp, fm_gamma, ikp, qs_env, kpoints, basis_type)
...
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 get_fname(fname, bs_env, ikp, scf_gw, ispin, soc)
...
subroutine, public bandstructure_primitive_cell(qs_env, bs_env, eigenvalues, filename, fm_h_gamma)
...
subroutine, public create_and_init_bs_env(qs_env, bs_env, post_scf_bandstructure_section)
...
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_nonbond, sab_almo, sab_kp, sab_kp_nosym, 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, ecoul_1c, rho0_s_rs, rho0_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, 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, rhs)
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.
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 remove_soc_outside_energy_window_mo(cfm_ks_spinor, e_win, eigenval, e_homo, e_lumo)
...
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 ...