81#include "./base/base_uses.f90"
87 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'kpoint_methods'
110 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_initialize'
112 INTEGER :: handle, i, ic, ik, iounit, ir, ira, is, &
113 j, natom, nkind, nr, ns
114 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atype
116 REAL(kind=
dp) :: wsum
117 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: coord, scoord
121 CALL timeset(routinen, handle)
123 cpassert(
ASSOCIATED(kpoint))
125 SELECT CASE (kpoint%kp_scheme)
130 ALLOCATE (kpoint%xkp(3, 1), kpoint%wkp(1))
131 kpoint%xkp(1:3, 1) = 0.0_dp
132 kpoint%wkp(1) = 1.0_dp
133 ALLOCATE (kpoint%kp_sym(1))
134 NULLIFY (kpoint%kp_sym(1)%kpoint_sym)
136 CASE (
"MONKHORST-PACK",
"MACDONALD")
138 IF (.NOT. kpoint%symmetry)
THEN
141 ALLOCATE (coord(3, natom), scoord(3, natom), atype(natom))
144 coord(1, i) = sin(i*0.12345_dp)
145 coord(2, i) = cos(i*0.23456_dp)
146 coord(3, i) = sin(i*0.34567_dp)
150 natom =
SIZE(particle_set)
151 ALLOCATE (scoord(3, natom), atype(natom))
153 CALL get_atomic_kind(atomic_kind=particle_set(i)%atomic_kind, kind_number=atype(i))
157 IF (kpoint%verbose)
THEN
163 ALLOCATE (kpoint%atype(natom))
166 CALL crys_sym_gen(crys_sym, scoord, atype, cell%hmat, delta=kpoint%eps_geo, iounit=iounit)
167 CALL kpoint_gen(crys_sym, kpoint%nkp_grid, symm=kpoint%symmetry, shift=kpoint%kp_shift, &
168 full_grid=kpoint%full_grid)
169 kpoint%nkp = crys_sym%nkpoint
170 ALLOCATE (kpoint%xkp(3, kpoint%nkp), kpoint%wkp(kpoint%nkp))
171 wsum = sum(crys_sym%wkpoint)
172 DO ik = 1, kpoint%nkp
173 kpoint%xkp(1:3, ik) = crys_sym%xkpoint(1:3, ik)
174 kpoint%wkp(ik) = crys_sym%wkpoint(ik)/wsum
182 ALLOCATE (kpoint%kp_sym(kpoint%nkp))
183 DO ik = 1, kpoint%nkp
184 NULLIFY (kpoint%kp_sym(ik)%kpoint_sym)
186 kpsym => kpoint%kp_sym(ik)%kpoint_sym
187 IF (crys_sym%symlib .AND. .NOT. crys_sym%fullgrid .AND. crys_sym%istriz == 1)
THEN
189 kpsym%nwght = nint(crys_sym%wkpoint(ik))
193 kpsym%apply_symmetry = .true.
194 natom =
SIZE(particle_set)
195 ALLOCATE (
kpsym%rot(3, 3, ns))
196 ALLOCATE (
kpsym%xkp(3, ns))
197 ALLOCATE (
kpsym%rotp(ns))
198 ALLOCATE (
kpsym%f0(natom, ns))
200 DO is = 1,
SIZE(crys_sym%kplink, 2)
201 IF (crys_sym%kplink(2, is) == ik)
THEN
203 ir = crys_sym%kpop(is)
207 kpsym%rot(1:3, 1:3, nr) = crys_sym%rt(1:3, 1:3, ira)
209 kpsym%rot(1:3, 1:3, nr) = -crys_sym%rt(1:3, 1:3, ira)
211 kpsym%xkp(1:3, nr) = crys_sym%kpmesh(1:3, is)
212 DO ic = 1, crys_sym%nrtot
213 IF (crys_sym%ibrot(ic) == ira)
THEN
214 kpsym%f0(1:natom, nr) = crys_sym%f0(1:natom, ic)
225 IF (kpoint%symmetry)
THEN
226 nkind = maxval(atype)
228 ALLOCATE (kpoint%kind_rotmat(ns, nkind))
231 NULLIFY (kpoint%kind_rotmat(i, j)%rmat)
234 ALLOCATE (kpoint%ibrot(ns))
235 kpoint%ibrot(1:ns) = crys_sym%ibrot(1:ns)
239 DEALLOCATE (scoord, atype)
243 ALLOCATE (kpoint%kp_sym(kpoint%nkp))
245 NULLIFY (kpoint%kp_sym(i)%kpoint_sym)
253 SELECT CASE (kpoint%kp_scheme)
257 cpassert(kpoint%nkp == 1)
258 cpassert(sum(abs(kpoint%xkp)) <= 1.e-12_dp)
259 cpassert(kpoint%wkp(1) == 1.0_dp)
260 cpassert(.NOT. kpoint%symmetry)
262 cpassert(.NOT. kpoint%symmetry)
263 cpassert(kpoint%nkp >= 1)
264 CASE (
"MONKHORST-PACK",
"MACDONALD")
265 cpassert(kpoint%nkp >= 1)
267 IF (kpoint%use_real_wfn)
THEN
269 ikloop:
DO ik = 1, kpoint%nkp
271 spez = (kpoint%xkp(i, ik) == 0.0_dp .OR. kpoint%xkp(i, ik) == 0.5_dp)
272 IF (.NOT. spez)
EXIT ikloop
277 CALL cp_warn(__location__, &
278 "A calculation using real wavefunctions is requested. "// &
279 "We could not determine if the symmetry of the system allows real wavefunctions. ")
283 CALL timestop(handle)
299 LOGICAL,
INTENT(IN),
OPTIONAL :: with_aux_fit
301 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_env_initialize'
303 INTEGER :: handle, igr, ik, ikk, ngr, niogrp, nkp, &
304 nkp_grp, nkp_loc, npe, unit_nr
305 INTEGER,
DIMENSION(2) :: dims, pos
312 CALL timeset(routinen, handle)
314 IF (
PRESENT(with_aux_fit))
THEN
315 aux_fit = with_aux_fit
320 kpoint%para_env => para_env
321 CALL kpoint%para_env%retain()
322 kpoint%blacs_env_all => blacs_env
323 CALL kpoint%blacs_env_all%retain()
325 cpassert(.NOT.
ASSOCIATED(kpoint%kp_env))
327 cpassert(.NOT.
ASSOCIATED(kpoint%kp_aux_env))
330 NULLIFY (kp_env, kp_aux_env)
332 npe = para_env%num_pe
335 ALLOCATE (kp_env(nkp))
337 NULLIFY (kp_env(ik)%kpoint_env)
339 kp => kp_env(ik)%kpoint_env
341 kp%wkp = kpoint%wkp(ik)
342 kp%xkp(1:3) = kpoint%xkp(1:3, ik)
345 kpoint%kp_env => kp_env
348 ALLOCATE (kp_aux_env(nkp))
350 NULLIFY (kp_aux_env(ik)%kpoint_env)
352 kp => kp_aux_env(ik)%kpoint_env
354 kp%wkp = kpoint%wkp(ik)
355 kp%xkp(1:3) = kpoint%xkp(1:3, ik)
359 kpoint%kp_aux_env => kp_aux_env
362 ALLOCATE (kpoint%kp_dist(2, 1))
363 kpoint%kp_dist(1, 1) = 1
364 kpoint%kp_dist(2, 1) = nkp
365 kpoint%kp_range(1) = 1
366 kpoint%kp_range(2) = nkp
369 kpoint%para_env_kp => para_env
370 CALL kpoint%para_env_kp%retain()
371 kpoint%para_env_inter_kp => para_env
372 CALL kpoint%para_env_inter_kp%retain()
373 kpoint%iogrp = .true.
374 kpoint%nkp_groups = 1
376 IF (kpoint%parallel_group_size == -1)
THEN
381 IF (mod(npe, igr) .NE. 0) cycle
383 IF (mod(nkp, nkp_grp) .NE. 0) cycle
386 ELSE IF (kpoint%parallel_group_size == 0)
THEN
389 ELSE IF (kpoint%parallel_group_size > 0)
THEN
390 ngr = min(kpoint%parallel_group_size, npe)
398 cpassert(mod(nkp, nkp_grp) == 0)
399 nkp_loc = nkp/nkp_grp
401 IF ((dims(1)*dims(2) /= npe))
THEN
402 cpabort(
"Number of processors is not divisible by the kpoint group size.")
406 CALL comm_cart%create(comm_old=para_env, ndims=2, dims=dims)
407 pos = comm_cart%mepos_cart
408 ALLOCATE (para_env_kp)
409 CALL para_env_kp%from_split(comm_cart, pos(2))
410 ALLOCATE (para_env_inter_kp)
411 CALL para_env_inter_kp%from_split(comm_cart, pos(1))
412 CALL comm_cart%free()
415 IF (para_env%is_source()) niogrp = 1
416 CALL para_env_kp%sum(niogrp)
417 kpoint%iogrp = (niogrp == 1)
420 kpoint%para_env_kp => para_env_kp
421 kpoint%para_env_inter_kp => para_env_inter_kp
424 ALLOCATE (kpoint%kp_dist(2, nkp_grp))
426 kpoint%kp_dist(1:2, igr) =
get_limit(nkp, nkp_grp, igr - 1)
429 kpoint%kp_range(1:2) = kpoint%kp_dist(1:2, para_env_inter_kp%mepos + 1)
431 ALLOCATE (kp_env(nkp_loc))
433 NULLIFY (kp_env(ik)%kpoint_env)
434 ikk = kpoint%kp_range(1) + ik - 1
436 kp => kp_env(ik)%kpoint_env
438 kp%wkp = kpoint%wkp(ikk)
439 kp%xkp(1:3) = kpoint%xkp(1:3, ikk)
440 kp%is_local = (ngr == 1)
442 kpoint%kp_env => kp_env
445 ALLOCATE (kp_aux_env(nkp_loc))
447 NULLIFY (kp_aux_env(ik)%kpoint_env)
448 ikk = kpoint%kp_range(1) + ik - 1
450 kp => kp_aux_env(ik)%kpoint_env
452 kp%wkp = kpoint%wkp(ikk)
453 kp%xkp(1:3) = kpoint%xkp(1:3, ikk)
454 kp%is_local = (ngr == 1)
456 kpoint%kp_aux_env => kp_aux_env
461 IF (unit_nr > 0 .AND. kpoint%verbose)
THEN
463 WRITE (unit_nr, fmt=
"(T2,A,T71,I10)")
"KPOINTS| Number of kpoint groups ", nkp_grp
464 WRITE (unit_nr, fmt=
"(T2,A,T71,I10)")
"KPOINTS| Size of each kpoint group", ngr
465 WRITE (unit_nr, fmt=
"(T2,A,T71,I10)")
"KPOINTS| Number of kpoints per group", nkp_loc
467 kpoint%nkp_groups = nkp_grp
471 CALL timestop(handle)
485 TYPE(
mo_set_type),
DIMENSION(:),
INTENT(INOUT) :: mos
486 INTEGER,
INTENT(IN),
OPTIONAL :: added_mos
487 LOGICAL,
OPTIONAL :: for_aux_fit
489 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_initialize_mos'
491 INTEGER :: handle, ic, ik, is, nadd, nao, nc, &
492 nelectron, nkp_loc, nmo, nmorig(2), &
495 REAL(kind=
dp) :: flexible_electron_count, maxocc, n_el_f
503 CALL timeset(routinen, handle)
505 IF (
PRESENT(for_aux_fit))
THEN
506 aux_fit = for_aux_fit
511 cpassert(
ASSOCIATED(kpoint))
513 IF (.true. .OR.
ASSOCIATED(mos(1)%mo_coeff))
THEN
515 cpassert(
ASSOCIATED(kpoint%kp_aux_env))
518 IF (
PRESENT(added_mos))
THEN
524 IF (kpoint%use_real_wfn)
THEN
530 nkp_loc = kpoint%kp_range(2) - kpoint%kp_range(1) + 1
531 IF (nkp_loc > 0)
THEN
533 cpassert(
SIZE(kpoint%kp_aux_env) == nkp_loc)
535 cpassert(
SIZE(kpoint%kp_env) == nkp_loc)
540 kp => kpoint%kp_aux_env(ik)%kpoint_env
542 kp => kpoint%kp_env(ik)%kpoint_env
544 ALLOCATE (kp%mos(nc, nspin))
546 CALL get_mo_set(mos(is), nao=nao, nmo=nmo, nelectron=nelectron, &
547 n_el_f=n_el_f, maxocc=maxocc, flexible_electron_count=flexible_electron_count)
548 nmo = min(nao, nmo + nadd)
550 CALL allocate_mo_set(kp%mos(ic, is), nao, nmo, nelectron, n_el_f, maxocc, &
551 flexible_electron_count)
561 IF (
ASSOCIATED(kpoint%blacs_env))
THEN
562 blacs_env => kpoint%blacs_env
565 kpoint%blacs_env => blacs_env
571 nmo = min(nao, nmorig(is) + nadd)
579 blacs_env=blacs_env, para_env=kpoint%para_env_kp)
582 kpoint%mpools_aux_fit => mpools
584 kpoint%mpools => mpools
593 CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
599 kp => kpoint%kp_aux_env(ik)%kpoint_env
601 kp => kpoint%kp_env(ik)%kpoint_env
605 ALLOCATE (kp%pmat(nc, nspin))
613 ALLOCATE (kp%wmat(nc, nspin))
627 CALL timestop(handle)
638 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_initialize_mo_set'
640 INTEGER :: handle, ic, ik, ikk, ispin
643 TYPE(
mo_set_type),
DIMENSION(:, :),
POINTER :: moskp
645 CALL timeset(routinen, handle)
647 DO ik = 1,
SIZE(kpoint%kp_env)
648 CALL mpools_get(kpoint%mpools, ao_mo_fm_pools=ao_mo_fm_pools)
649 moskp => kpoint%kp_env(ik)%kpoint_env%mos
650 ikk = kpoint%kp_range(1) + ik - 1
651 cpassert(
ASSOCIATED(moskp))
652 DO ispin = 1,
SIZE(moskp, 2)
653 DO ic = 1,
SIZE(moskp, 1)
654 CALL get_mo_set(moskp(ic, ispin), mo_coeff=mo_coeff)
655 IF (.NOT.
ASSOCIATED(mo_coeff))
THEN
657 fm_pool=ao_mo_fm_pools(ispin)%pool, name=
"kpoints")
663 CALL timestop(handle)
683 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_init_cell_index'
685 INTEGER :: handle, i1, i2, i3, ic, icount, it, &
687 INTEGER,
DIMENSION(3) :: cell, itm
688 INTEGER,
DIMENSION(:, :),
POINTER :: index_to_cell,
list
689 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index, cti
692 DIMENSION(:),
POINTER :: nl_iterator
694 NULLIFY (cell_to_index, index_to_cell)
696 CALL timeset(routinen, handle)
698 cpassert(
ASSOCIATED(kpoint))
700 ALLOCATE (
list(3, 125))
710 IF (cell(1) ==
list(1, ic) .AND. cell(2) ==
list(2, ic) .AND. &
711 cell(3) ==
list(3, ic))
THEN
718 IF (icount >
SIZE(
list, 2))
THEN
721 list(1:3, icount) = cell(1:3)
727 itm(1) = maxval(abs(
list(1, 1:icount)))
728 itm(2) = maxval(abs(
list(2, 1:icount)))
729 itm(3) = maxval(abs(
list(3, 1:icount)))
730 CALL para_env%max(itm)
731 it = maxval(itm(1:3))
732 IF (
ASSOCIATED(kpoint%cell_to_index))
THEN
733 DEALLOCATE (kpoint%cell_to_index)
735 ALLOCATE (kpoint%cell_to_index(-itm(1):itm(1), -itm(2):itm(2), -itm(3):itm(3)))
736 cell_to_index => kpoint%cell_to_index
745 CALL para_env%sum(cti)
747 DO i1 = -itm(1), itm(1)
748 DO i2 = -itm(2), itm(2)
749 DO i3 = -itm(3), itm(3)
750 IF (cti(i1, i2, i3) == 0)
THEN
751 cti(i1, i2, i3) = 1000000
754 cti(i1, i2, i3) = (abs(i1) + abs(i2) + abs(i3))*1000 + abs(i3)*100 + abs(i2)*10 + abs(i1)
755 cti(i1, i2, i3) = cti(i1, i2, i3) + (i1 + i2 + i3)
761 IF (
ASSOCIATED(kpoint%index_to_cell))
THEN
762 DEALLOCATE (kpoint%index_to_cell)
764 ALLOCATE (kpoint%index_to_cell(3, ncount))
765 index_to_cell => kpoint%index_to_cell
768 i1 = cell(1) - 1 - itm(1)
769 i2 = cell(2) - 1 - itm(2)
770 i3 = cell(3) - 1 - itm(3)
771 cti(i1, i2, i3) = 1000000
772 index_to_cell(1, ic) = i1
773 index_to_cell(2, ic) = i2
774 index_to_cell(3, ic) = i3
778 i1 = index_to_cell(1, ic)
779 i2 = index_to_cell(2, ic)
780 i3 = index_to_cell(3, ic)
785 kpoint%sab_nl => sab_nl
788 dft_control%nimages =
SIZE(index_to_cell, 2)
792 CALL timestop(handle)
808 xkp, cell_to_index, sab_nl, is_complex, rs_sign)
813 INTEGER,
INTENT(IN) :: ispin
814 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xkp
815 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
818 LOGICAL,
INTENT(IN),
OPTIONAL :: is_complex
819 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: rs_sign
821 CHARACTER(LEN=*),
PARAMETER :: routinen =
'rskp_transform'
823 INTEGER :: handle, iatom, ic, icol, irow, jatom, &
825 INTEGER,
DIMENSION(3) :: cell
826 LOGICAL :: do_symmetric, found, my_complex, &
828 REAL(kind=
dp) :: arg, coskl, fsign, fsym, sinkl
829 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: cblock, rblock, rsblock
831 DIMENSION(:),
POINTER :: nl_iterator
833 CALL timeset(routinen, handle)
836 IF (
PRESENT(is_complex)) my_complex = is_complex
839 IF (
PRESENT(rs_sign)) fsign = rs_sign
841 wfn_real_only = .true.
842 IF (
PRESENT(cmatrix)) wfn_real_only = .false.
844 nimg =
SIZE(rsmat, 2)
857 IF (do_symmetric .AND. (iatom > jatom))
THEN
863 ic = cell_to_index(cell(1), cell(2), cell(3))
864 IF (ic < 1 .OR. ic > nimg) cycle
866 arg = real(cell(1),
dp)*xkp(1) + real(cell(2),
dp)*xkp(2) + real(cell(3),
dp)*xkp(3)
868 coskl = fsign*fsym*cos(
twopi*arg)
869 sinkl = fsign*sin(
twopi*arg)
871 coskl = fsign*cos(
twopi*arg)
872 sinkl = fsign*fsym*sin(
twopi*arg)
876 block=rsblock, found=found)
877 IF (.NOT. found) cycle
879 IF (wfn_real_only)
THEN
881 block=rblock, found=found)
882 IF (.NOT. found) cycle
883 rblock = rblock + coskl*rsblock
886 block=rblock, found=found)
887 IF (.NOT. found) cycle
889 block=cblock, found=found)
890 IF (.NOT. found) cycle
891 rblock = rblock + coskl*rsblock
892 cblock = cblock + sinkl*rsblock
898 CALL timestop(handle)
912 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_set_mo_occupation'
914 INTEGER :: handle, ik, ikpgr, ispin, kplocal, nb, &
915 ne_a, ne_b, nelectron, nkp, nmo, nspin
916 INTEGER,
DIMENSION(2) :: kp_range
917 REAL(kind=
dp) :: kts, mu, mus(2), nel
918 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: weig, wocc
919 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eigenvalues, occupation, wkp
924 CALL timeset(routinen, handle)
928 kp => kpoint%kp_env(1)%kpoint_env
929 nspin =
SIZE(kp%mos, 2)
930 mo_set => kp%mos(1, 1)
931 CALL get_mo_set(mo_set, nmo=nmo, nelectron=nelectron)
934 CALL get_mo_set(kp%mos(1, 2), nmo=nb, nelectron=ne_b)
937 ALLOCATE (weig(nmo, nkp, nspin), wocc(nmo, nkp, nspin))
941 kplocal = kp_range(2) - kp_range(1) + 1
942 DO ikpgr = 1, kplocal
943 ik = kp_range(1) + ikpgr - 1
944 kp => kpoint%kp_env(ikpgr)%kpoint_env
946 mo_set => kp%mos(1, ispin)
947 CALL get_mo_set(mo_set, eigenvalues=eigenvalues)
948 weig(1:nmo, ik, ispin) = eigenvalues(1:nmo)
952 CALL para_env_inter_kp%sum(weig)
955 IF (smear%do_smear)
THEN
957 SELECT CASE (smear%method)
960 nel = real(nelectron, kind=
dp)
961 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, &
962 smear%electronic_temperature, 2.0_dp)
963 ELSE IF (smear%fixed_mag_mom > 0.0_dp)
THEN
964 cpabort(
"kpoints: Smearing with fixed magnetic moments not (yet) supported")
965 nel = real(ne_a, kind=
dp)
966 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, &
967 smear%electronic_temperature, 1.0_dp)
968 nel = real(ne_b, kind=
dp)
969 CALL fermikp(wocc(:, :, 2), mus(2), kts, weig(:, :, 2), nel, wkp, &
970 smear%electronic_temperature, 1.0_dp)
972 nel = real(ne_a, kind=
dp) + real(ne_b, kind=
dp)
973 CALL fermikp2(wocc(:, :, :), mu, kts, weig(:, :, :), nel, wkp, &
974 smear%electronic_temperature)
979 cpabort(
"kpoints: Selected smearing not (yet) supported")
984 nel = real(nelectron, kind=
dp)
985 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, 0.0_dp, 2.0_dp)
987 nel = real(ne_a, kind=
dp)
988 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, 0.0_dp, 1.0_dp)
989 nel = real(ne_b, kind=
dp)
990 CALL fermikp(wocc(:, :, 2), mus(2), kts, weig(:, :, 2), nel, wkp, 0.0_dp, 1.0_dp)
993 DO ikpgr = 1, kplocal
994 ik = kp_range(1) + ikpgr - 1
995 kp => kpoint%kp_env(ikpgr)%kpoint_env
997 mo_set => kp%mos(1, ispin)
998 CALL get_mo_set(mo_set, eigenvalues=eigenvalues, occupation_numbers=occupation)
999 eigenvalues(1:nmo) = weig(1:nmo, ik, ispin)
1000 occupation(1:nmo) = wocc(1:nmo, ik, ispin)
1002 mo_set%mu = mus(ispin)
1006 DEALLOCATE (weig, wocc)
1008 CALL timestop(handle)
1021 LOGICAL,
OPTIONAL :: energy_weighted, for_aux_fit
1023 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_density_matrices'
1025 INTEGER :: handle, ikpgr, ispin, kplocal, nao, nmo, &
1027 INTEGER,
DIMENSION(2) :: kp_range
1028 LOGICAL :: aux_fit, wtype
1029 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eigenvalues, occupation
1032 TYPE(
cp_fm_type),
POINTER :: cpmat, pmat, rpmat
1036 CALL timeset(routinen, handle)
1038 IF (
PRESENT(energy_weighted))
THEN
1039 wtype = energy_weighted
1045 IF (
PRESENT(for_aux_fit))
THEN
1046 aux_fit = for_aux_fit
1052 cpassert(
ASSOCIATED(kpoint%kp_aux_env))
1057 mo_set => kpoint%kp_aux_env(1)%kpoint_env%mos(1, 1)
1059 mo_set => kpoint%kp_env(1)%kpoint_env%mos(1, 1)
1062 CALL cp_fm_get_info(mo_set%mo_coeff, matrix_struct=matrix_struct)
1066 kplocal = kp_range(2) - kp_range(1) + 1
1067 DO ikpgr = 1, kplocal
1069 kp => kpoint%kp_aux_env(ikpgr)%kpoint_env
1071 kp => kpoint%kp_env(ikpgr)%kpoint_env
1073 nspin =
SIZE(kp%mos, 2)
1075 mo_set => kp%mos(1, ispin)
1077 CALL get_mo_set(mo_set, eigenvalues=eigenvalues)
1079 IF (kpoint%use_real_wfn)
THEN
1081 pmat => kp%wmat(1, ispin)
1083 pmat => kp%pmat(1, ispin)
1085 CALL get_mo_set(mo_set, occupation_numbers=occupation)
1091 CALL parallel_gemm(
"N",
"T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, pmat)
1094 rpmat => kp%wmat(1, ispin)
1095 cpmat => kp%wmat(2, ispin)
1097 rpmat => kp%pmat(1, ispin)
1098 cpmat => kp%pmat(2, ispin)
1100 CALL get_mo_set(mo_set, occupation_numbers=occupation)
1107 CALL parallel_gemm(
"N",
"T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, rpmat)
1108 mo_set => kp%mos(2, ispin)
1110 CALL parallel_gemm(
"N",
"T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, cpmat)
1112 CALL parallel_gemm(
"N",
"T", nao, nao, nmo, -1.0_dp, fwork, mo_set%mo_coeff, 1.0_dp, cpmat)
1119 CALL parallel_gemm(
"N",
"T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 1.0_dp, rpmat)
1126 CALL timestop(handle)
1146 LOGICAL,
INTENT(IN) :: wtype
1150 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: fmwork
1151 LOGICAL,
OPTIONAL :: for_aux_fit
1152 TYPE(
cp_fm_type),
DIMENSION(:, :, :),
INTENT(IN), &
1153 OPTIONAL :: pmat_ext
1155 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_density_transform'
1157 INTEGER :: handle, ic, ik, ikk, indx, ir, ira, is, &
1158 ispin, jr, nc, nimg, nkp, nspin
1159 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
1160 LOGICAL :: aux_fit, do_ext, do_symmetric, my_kpgrp, &
1162 REAL(kind=
dp) :: wkpx
1163 REAL(kind=
dp),
DIMENSION(:),
POINTER :: wkp
1164 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xkp
1167 TYPE(
dbcsr_type),
POINTER :: cpmat, rpmat, scpmat, srpmat
1173 CALL timeset(routinen, handle)
1177 IF (
PRESENT(for_aux_fit))
THEN
1178 aux_fit = for_aux_fit
1184 IF (
PRESENT(pmat_ext)) do_ext = .true.
1187 cpassert(
ASSOCIATED(kpoint%kp_aux_env))
1193 matrix_type=merge(dbcsr_type_symmetric, dbcsr_type_no_symmetry, do_symmetric))
1198 matrix_type=merge(dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, do_symmetric))
1201 IF (.NOT. kpoint%full_grid)
THEN
1213 cell_to_index=cell_to_index)
1216 kp => kpoint%kp_aux_env(1)%kpoint_env
1218 kp => kpoint%kp_env(1)%kpoint_env
1220 nspin =
SIZE(kp%mos, 2)
1221 nc =
SIZE(kp%mos, 1)
1222 nimg =
SIZE(denmat, 2)
1223 real_only = (nc == 1)
1225 para_env => kpoint%blacs_env_all%para_env
1226 ALLOCATE (info(nspin*nkp*nc))
1232 CALL dbcsr_set(denmat(ispin, ic)%matrix, 0.0_dp)
1236 my_kpgrp = (ik >= kpoint%kp_range(1) .AND. ik <= kpoint%kp_range(2))
1238 ikk = ik - kpoint%kp_range(1) + 1
1240 kp => kpoint%kp_aux_env(ikk)%kpoint_env
1242 kp => kpoint%kp_env(ikk)%kpoint_env
1248 cpassert(
SIZE(fmwork) >= nc)
1290 kpsym => kpoint%kp_sym(ik)%kpoint_sym
1291 cpassert(
ASSOCIATED(
kpsym))
1293 IF (
kpsym%apply_symmetry)
THEN
1294 wkpx = wkp(ik)/real(
kpsym%nwght, kind=
dp)
1295 DO is = 1,
kpsym%nwght
1296 ir = abs(
kpsym%rotp(is))
1298 DO jr = 1,
SIZE(kpoint%ibrot)
1299 IF (ir == kpoint%ibrot(jr)) ira = jr
1302 kind_rot => kpoint%kind_rotmat(ira, :)
1304 CALL symtrans(srpmat, rpmat, kind_rot,
kpsym%rot(1:3, 1:3, is), &
1305 kpsym%f0(:, is), kpoint%atype, symmetric=.true.)
1307 CALL symtrans(srpmat, rpmat, kind_rot,
kpsym%rot(1:3, 1:3, is), &
1308 kpsym%f0(:, is), kpoint%atype, symmetric=.true.)
1309 CALL symtrans(scpmat, cpmat, kind_rot,
kpsym%rot(1:3, 1:3, is), &
1310 kpsym%f0(:, is), kpoint%atype, antisymmetric=.true.)
1312 CALL transform_dmat(denmat, srpmat, scpmat, ispin, real_only, sab_nl, &
1313 cell_to_index,
kpsym%xkp(1:3, is), wkpx)
1317 CALL transform_dmat(denmat, rpmat, cpmat, ispin, real_only, sab_nl, &
1318 cell_to_index, xkp(1:3, ik), wkp(ik))
1327 my_kpgrp = (ik >= kpoint%kp_range(1) .AND. ik <= kpoint%kp_range(2))
1329 ikk = ik - kpoint%kp_range(1) + 1
1331 kp => kpoint%kp_aux_env(ikk)%kpoint_env
1333 kp => kpoint%kp_env(ikk)%kpoint_env
1353 IF (.NOT. kpoint%full_grid)
THEN
1358 CALL timestop(handle)
1374 SUBROUTINE transform_dmat(denmat, rpmat, cpmat, ispin, real_only, sab_nl, cell_to_index, xkp, wkp)
1378 INTEGER,
INTENT(IN) :: ispin
1379 LOGICAL,
INTENT(IN) :: real_only
1382 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
1383 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xkp
1384 REAL(kind=
dp),
INTENT(IN) :: wkp
1386 CHARACTER(LEN=*),
PARAMETER :: routinen =
'transform_dmat'
1388 INTEGER :: handle, iatom, icell, icol, irow, jatom, &
1390 INTEGER,
DIMENSION(3) :: cell
1391 LOGICAL :: do_symmetric, found
1392 REAL(kind=
dp) :: arg, coskl, fc, sinkl
1393 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: cblock, dblock, rblock
1395 DIMENSION(:),
POINTER :: nl_iterator
1397 CALL timeset(routinen, handle)
1399 nimg =
SIZE(denmat, 2)
1415 IF (do_symmetric .AND. iatom > jatom)
THEN
1421 icell = cell_to_index(cell(1), cell(2), cell(3))
1422 IF (icell < 1 .OR. icell > nimg) cycle
1424 arg = real(cell(1),
dp)*xkp(1) + real(cell(2),
dp)*xkp(2) + real(cell(3),
dp)*xkp(3)
1425 coskl = wkp*cos(
twopi*arg)
1426 sinkl = wkp*fc*sin(
twopi*arg)
1428 CALL dbcsr_get_block_p(matrix=denmat(ispin, icell)%matrix, row=irow, col=icol, &
1429 block=dblock, found=found)
1430 IF (.NOT. found) cycle
1433 CALL dbcsr_get_block_p(matrix=rpmat, row=irow, col=icol, block=rblock, found=found)
1434 IF (.NOT. found) cycle
1435 dblock = dblock + coskl*rblock
1437 CALL dbcsr_get_block_p(matrix=rpmat, row=irow, col=icol, block=rblock, found=found)
1438 IF (.NOT. found) cycle
1439 CALL dbcsr_get_block_p(matrix=cpmat, row=irow, col=icol, block=cblock, found=found)
1440 IF (.NOT. found) cycle
1441 dblock = dblock + coskl*rblock
1442 dblock = dblock + sinkl*cblock
1447 CALL timestop(handle)
1449 END SUBROUTINE transform_dmat
1462 SUBROUTINE symtrans(smat, pmat, kmat, rot, f0, atype, symmetric, antisymmetric)
1465 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: rot
1466 INTEGER,
DIMENSION(:),
INTENT(IN) :: f0, atype
1467 LOGICAL,
INTENT(IN),
OPTIONAL :: symmetric, antisymmetric
1469 CHARACTER(LEN=*),
PARAMETER :: routinen =
'symtrans'
1471 INTEGER :: handle, iatom, icol, ikind, ip, irow, &
1472 jcol, jkind, jp, jrow, natom, numnodes
1473 LOGICAL :: asym, dorot, found, perm, sym, trans
1474 REAL(kind=
dp) :: dr, fsign
1475 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: kroti, krotj, pblock, sblock
1479 CALL timeset(routinen, handle)
1483 IF (
PRESENT(symmetric)) sym = symmetric
1485 IF (
PRESENT(antisymmetric)) asym = antisymmetric
1487 cpassert(.NOT. (sym .AND. asym))
1488 cpassert((sym .OR. asym))
1494 IF (f0(iatom) == iatom) cycle
1501 IF (abs(sum(abs(rot)) - 3.0_dp) > 1.e-12_dp) dorot = .true.
1502 dr = abs(rot(1, 1) - 1.0_dp) + abs(rot(2, 2) - 1.0_dp) + abs(rot(3, 3) - 1.0_dp)
1503 IF (abs(dr) > 1.e-12_dp) dorot = .true.
1506 IF (asym) fsign = -1.0_dp
1508 IF (dorot .OR. perm)
THEN
1509 CALL cp_abort(__location__,
"k-points need FULL_GRID currently. "// &
1510 "Reduced grids not yet working correctly")
1515 IF (numnodes == 1)
THEN
1531 CALL dbcsr_get_block_p(matrix=smat, row=jrow, col=jcol, block=sblock, found=found)
1535 kroti => kmat(ikind)%rmat
1536 krotj => kmat(jkind)%rmat
1539 sblock = fsign*matmul(transpose(krotj), matmul(transpose(pblock), kroti))
1541 sblock = fsign*matmul(transpose(kroti), matmul(pblock, krotj))
1548 CALL cp_abort(__location__,
"k-points need FULL_GRID currently. "// &
1549 "Reduced grids not yet working correctly")
1570 kroti => kmat(ikind)%rmat
1571 krotj => kmat(jkind)%rmat
1574 sblock = fsign*matmul(transpose(krotj), matmul(transpose(sblock), kroti))
1576 sblock = fsign*matmul(transpose(kroti), matmul(sblock, krotj))
1587 CALL timestop(handle)
1589 END SUBROUTINE symtrans
1595 SUBROUTINE matprint(mat)
1598 INTEGER :: i, icol, iounit, irow
1599 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: mblock
1607 IF (iounit > 0)
THEN
1608 WRITE (iounit,
'(A,2I4)')
'BLOCK ', irow, icol
1609 DO i = 1,
SIZE(mblock, 1)
1610 WRITE (iounit,
'(8F12.6)') mblock(i, :)
1617 END SUBROUTINE matprint
Define the atomic kind types and their sub types.
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 real_to_scaled(s, r, cell)
Transform real to scaled cell coordinates. s=h_inv*r.
methods related to the blacs parallel environment
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_deallocate_matrix(matrix)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_distribution_get(dist, row_dist, col_dist, nrows, ncols, has_threads, group, mynode, numnodes, nprows, npcols, myprow, mypcol, pgrid, subgroups_defined, prow_group, pcol_group)
...
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_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
basic linear algebra operations for full matrices
subroutine, public cp_fm_column_scale(matrixa, scaling)
scales column i of matrix a with scaling(i)
pool for for elements that are retained and released
subroutine, public fm_pool_create_fm(pool, element, name)
returns an element, allocating it if none is in the pool
subroutine, public fm_pool_give_back_fm(pool, element)
returns the element to the pool
represent the structure of a full matrix
represent a full matrix distributed on many processors
subroutine, public cp_fm_start_copy_general(source, destination, para_env, info)
Initiates the copy operation: get distribution data, post MPI isend and irecvs.
subroutine, public cp_fm_cleanup_copy_general(info)
Completes the copy operation: wait for comms clean up MPI state.
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_finish_copy_general(destination, info)
Completes the copy operation: wait for comms, unpack, clean up MPI state.
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...
K-points and crystal symmetry routines.
subroutine, public print_crys_symmetry(csym)
...
subroutine, public crys_sym_gen(csym, scoor, types, hmat, delta, iounit)
...
subroutine, public release_csym_type(csym)
Release the CSYM type.
subroutine, public kpoint_gen(csym, nk, symm, shift, full_grid)
...
subroutine, public print_kp_symmetry(csym)
...
deal with the Fermi distribution, compute it, fix mu, get derivs
subroutine, public fermikp2(f, mu, kts, e, nel, wk, t)
Bisection search to find mu for a given nel (kpoint case)
subroutine, public fermikp(f, mu, kts, e, nel, wk, t, maxocc)
Bisection search to find mu for a given nel (kpoint case)
Defines the basic variable types.
integer, parameter, public dp
Routines needed for kpoint calculation.
subroutine, public kpoint_initialize_mo_set(kpoint)
...
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_initialize_mos(kpoint, mos, added_mos, for_aux_fit)
Initialize a set of MOs and density matrix for each kpoint (kpoint group)
subroutine, public kpoint_initialize(kpoint, particle_set, cell)
Generate the kpoints and initialize the kpoint environment.
subroutine, public kpoint_density_transform(kpoint, denmat, wtype, tempmat, sab_nl, fmwork, for_aux_fit, pmat_ext)
generate real space density matrices in DBCSR format
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.
subroutine, public kpoint_density_matrices(kpoint, energy_weighted, for_aux_fit)
Calculate kpoint density matrices (rho(k), owned by kpoint groups)
subroutine, public kpoint_env_initialize(kpoint, para_env, blacs_env, with_aux_fit)
Initialize the kpoint environment.
subroutine, public kpoint_set_mo_occupation(kpoint, smear)
Given the eigenvalues of all kpoints, calculates the occupation numbers.
Types and basic routines needed for a kpoint calculation.
subroutine, public kpoint_sym_create(kp_sym)
Create a single kpoint symmetry environment.
subroutine, public kpoint_env_create(kp_env)
Create a single 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.
K-points and crystal symmetry routines based on.
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition of mathematical constants and functions.
real(kind=dp), parameter, public twopi
Utility routines for the memory handling.
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
Define the data structure for the particle information.
wrapper for the pools of matrixes
subroutine, public mpools_create(mpools)
creates a mpools
subroutine, public mpools_rebuild_fm_pools(mpools, mos, blacs_env, para_env, nmosub)
rebuilds the pools of the (ao x mo, ao x ao , mo x mo) full matrixes
subroutine, public mpools_get(mpools, ao_mo_fm_pools, ao_ao_fm_pools, mo_mo_fm_pools, ao_mosub_fm_pools, mosub_mosub_fm_pools, maxao_maxmo_fm_pool, maxao_maxao_fm_pool, maxmo_maxmo_fm_pool)
returns various attributes of the mpools (notably the pools contained in it)
Definition and initialisation of the mo data type.
subroutine, public set_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, uniform_occupation, kts, mu, flexible_electron_count)
Set the components of a MO set data structure.
subroutine, public allocate_mo_set(mo_set, nao, nmo, nelectron, n_el_f, maxocc, flexible_electron_count)
Allocates a mo set and partially initializes it (nao,nmo,nelectron, and flexible_electron_count are v...
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.
subroutine, public init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name)
initializes an allocated mo_set. eigenvalues, mo_coeff, occupation_numbers are valid only after this ...
Define the neighbor list data types and the corresponding functionality.
subroutine, public neighbor_list_iterator_create(iterator_set, nl, search, nthread)
Neighbor list iterator functions.
subroutine, public neighbor_list_iterator_release(iterator_set)
...
subroutine, public get_neighbor_list_set_p(neighbor_list_sets, nlist, symmetric)
Return the components of the first neighbor list set.
integer function, public neighbor_list_iterate(iterator_set, mepos)
...
subroutine, public get_iterator_info(iterator_set, mepos, ikind, jkind, nkind, ilist, nlist, inode, nnode, iatom, jatom, r, cell)
...
parameters that control an scf iteration
All kind of helpful little routines.
pure integer function, dimension(2), public get_limit(m, n, me)
divide m entries into n parts, return size of part me
Type defining parameters related to the simulation cell.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
to create arrays of pools
keeps the information about the structure of a full matrix
Stores the state of a copy between cp_fm_start_copy_general and cp_fm_finish_copy_general.
Rotation matrices for basis sets.
Keeps information about a specific k-point.
Keeps symmetry information about a specific k-point.
Contains information about kpoints.
stores all the informations relevant to an mpi environment
container for the pools of matrixes used by qs
contains the parameters needed by a scf run