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 nel = real(ne_a, kind=
dp)
965 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, &
966 smear%electronic_temperature, 1.0_dp)
967 nel = real(ne_b, kind=
dp)
968 CALL fermikp(wocc(:, :, 2), mus(2), kts, weig(:, :, 2), nel, wkp, &
969 smear%electronic_temperature, 1.0_dp)
971 nel = real(ne_a, kind=
dp) + real(ne_b, kind=
dp)
972 CALL fermikp2(wocc(:, :, :), mu, kts, weig(:, :, :), nel, wkp, &
973 smear%electronic_temperature)
978 cpabort(
"kpoints: Selected smearing not (yet) supported")
983 nel = real(nelectron, kind=
dp)
984 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, 0.0_dp, 2.0_dp)
986 nel = real(ne_a, kind=
dp)
987 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, 0.0_dp, 1.0_dp)
988 nel = real(ne_b, kind=
dp)
989 CALL fermikp(wocc(:, :, 2), mus(2), kts, weig(:, :, 2), nel, wkp, 0.0_dp, 1.0_dp)
992 DO ikpgr = 1, kplocal
993 ik = kp_range(1) + ikpgr - 1
994 kp => kpoint%kp_env(ikpgr)%kpoint_env
996 mo_set => kp%mos(1, ispin)
997 CALL get_mo_set(mo_set, eigenvalues=eigenvalues, occupation_numbers=occupation)
998 eigenvalues(1:nmo) = weig(1:nmo, ik, ispin)
999 occupation(1:nmo) = wocc(1:nmo, ik, ispin)
1001 mo_set%mu = mus(ispin)
1005 DEALLOCATE (weig, wocc)
1007 CALL timestop(handle)
1020 LOGICAL,
OPTIONAL :: energy_weighted, for_aux_fit
1022 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_density_matrices'
1024 INTEGER :: handle, ikpgr, ispin, kplocal, nao, nmo, &
1026 INTEGER,
DIMENSION(2) :: kp_range
1027 LOGICAL :: aux_fit, wtype
1028 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eigenvalues, occupation
1031 TYPE(
cp_fm_type),
POINTER :: cpmat, pmat, rpmat
1035 CALL timeset(routinen, handle)
1037 IF (
PRESENT(energy_weighted))
THEN
1038 wtype = energy_weighted
1044 IF (
PRESENT(for_aux_fit))
THEN
1045 aux_fit = for_aux_fit
1051 cpassert(
ASSOCIATED(kpoint%kp_aux_env))
1056 mo_set => kpoint%kp_aux_env(1)%kpoint_env%mos(1, 1)
1058 mo_set => kpoint%kp_env(1)%kpoint_env%mos(1, 1)
1061 CALL cp_fm_get_info(mo_set%mo_coeff, matrix_struct=matrix_struct)
1065 kplocal = kp_range(2) - kp_range(1) + 1
1066 DO ikpgr = 1, kplocal
1068 kp => kpoint%kp_aux_env(ikpgr)%kpoint_env
1070 kp => kpoint%kp_env(ikpgr)%kpoint_env
1072 nspin =
SIZE(kp%mos, 2)
1074 mo_set => kp%mos(1, ispin)
1076 CALL get_mo_set(mo_set, eigenvalues=eigenvalues)
1078 IF (kpoint%use_real_wfn)
THEN
1080 pmat => kp%wmat(1, ispin)
1082 pmat => kp%pmat(1, ispin)
1084 CALL get_mo_set(mo_set, occupation_numbers=occupation)
1090 CALL parallel_gemm(
"N",
"T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, pmat)
1093 rpmat => kp%wmat(1, ispin)
1094 cpmat => kp%wmat(2, ispin)
1096 rpmat => kp%pmat(1, ispin)
1097 cpmat => kp%pmat(2, ispin)
1099 CALL get_mo_set(mo_set, occupation_numbers=occupation)
1106 CALL parallel_gemm(
"N",
"T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, rpmat)
1107 mo_set => kp%mos(2, ispin)
1109 CALL parallel_gemm(
"N",
"T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, cpmat)
1111 CALL parallel_gemm(
"N",
"T", nao, nao, nmo, -1.0_dp, fwork, mo_set%mo_coeff, 1.0_dp, cpmat)
1118 CALL parallel_gemm(
"N",
"T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 1.0_dp, rpmat)
1125 CALL timestop(handle)
1145 LOGICAL,
INTENT(IN) :: wtype
1149 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: fmwork
1150 LOGICAL,
OPTIONAL :: for_aux_fit
1151 TYPE(
cp_fm_type),
DIMENSION(:, :, :),
INTENT(IN), &
1152 OPTIONAL :: pmat_ext
1154 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_density_transform'
1156 INTEGER :: handle, ic, ik, ikk, indx, ir, ira, is, &
1157 ispin, jr, nc, nimg, nkp, nspin
1158 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
1159 LOGICAL :: aux_fit, do_ext, do_symmetric, my_kpgrp, &
1161 REAL(kind=
dp) :: wkpx
1162 REAL(kind=
dp),
DIMENSION(:),
POINTER :: wkp
1163 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xkp
1166 TYPE(
dbcsr_type),
POINTER :: cpmat, rpmat, scpmat, srpmat
1172 CALL timeset(routinen, handle)
1176 IF (
PRESENT(for_aux_fit))
THEN
1177 aux_fit = for_aux_fit
1183 IF (
PRESENT(pmat_ext)) do_ext = .true.
1186 cpassert(
ASSOCIATED(kpoint%kp_aux_env))
1192 matrix_type=merge(dbcsr_type_symmetric, dbcsr_type_no_symmetry, do_symmetric))
1197 matrix_type=merge(dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, do_symmetric))
1200 IF (.NOT. kpoint%full_grid)
THEN
1212 cell_to_index=cell_to_index)
1215 kp => kpoint%kp_aux_env(1)%kpoint_env
1217 kp => kpoint%kp_env(1)%kpoint_env
1219 nspin =
SIZE(kp%mos, 2)
1220 nc =
SIZE(kp%mos, 1)
1221 nimg =
SIZE(denmat, 2)
1222 real_only = (nc == 1)
1224 para_env => kpoint%blacs_env_all%para_env
1225 ALLOCATE (info(nspin*nkp*nc))
1231 CALL dbcsr_set(denmat(ispin, ic)%matrix, 0.0_dp)
1235 my_kpgrp = (ik >= kpoint%kp_range(1) .AND. ik <= kpoint%kp_range(2))
1237 ikk = ik - kpoint%kp_range(1) + 1
1239 kp => kpoint%kp_aux_env(ikk)%kpoint_env
1241 kp => kpoint%kp_env(ikk)%kpoint_env
1247 cpassert(
SIZE(fmwork) >= nc)
1289 kpsym => kpoint%kp_sym(ik)%kpoint_sym
1290 cpassert(
ASSOCIATED(
kpsym))
1292 IF (
kpsym%apply_symmetry)
THEN
1293 wkpx = wkp(ik)/real(
kpsym%nwght, kind=
dp)
1294 DO is = 1,
kpsym%nwght
1295 ir = abs(
kpsym%rotp(is))
1297 DO jr = 1,
SIZE(kpoint%ibrot)
1298 IF (ir == kpoint%ibrot(jr)) ira = jr
1301 kind_rot => kpoint%kind_rotmat(ira, :)
1303 CALL symtrans(srpmat, rpmat, kind_rot,
kpsym%rot(1:3, 1:3, is), &
1304 kpsym%f0(:, is), kpoint%atype, symmetric=.true.)
1306 CALL symtrans(srpmat, rpmat, kind_rot,
kpsym%rot(1:3, 1:3, is), &
1307 kpsym%f0(:, is), kpoint%atype, symmetric=.true.)
1308 CALL symtrans(scpmat, cpmat, kind_rot,
kpsym%rot(1:3, 1:3, is), &
1309 kpsym%f0(:, is), kpoint%atype, antisymmetric=.true.)
1311 CALL transform_dmat(denmat, srpmat, scpmat, ispin, real_only, sab_nl, &
1312 cell_to_index,
kpsym%xkp(1:3, is), wkpx)
1316 CALL transform_dmat(denmat, rpmat, cpmat, ispin, real_only, sab_nl, &
1317 cell_to_index, xkp(1:3, ik), wkp(ik))
1326 my_kpgrp = (ik >= kpoint%kp_range(1) .AND. ik <= kpoint%kp_range(2))
1328 ikk = ik - kpoint%kp_range(1) + 1
1330 kp => kpoint%kp_aux_env(ikk)%kpoint_env
1332 kp => kpoint%kp_env(ikk)%kpoint_env
1352 IF (.NOT. kpoint%full_grid)
THEN
1357 CALL timestop(handle)
1373 SUBROUTINE transform_dmat(denmat, rpmat, cpmat, ispin, real_only, sab_nl, cell_to_index, xkp, wkp)
1377 INTEGER,
INTENT(IN) :: ispin
1378 LOGICAL,
INTENT(IN) :: real_only
1381 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
1382 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xkp
1383 REAL(kind=
dp),
INTENT(IN) :: wkp
1385 CHARACTER(LEN=*),
PARAMETER :: routinen =
'transform_dmat'
1387 INTEGER :: handle, iatom, icell, icol, irow, jatom, &
1389 INTEGER,
DIMENSION(3) :: cell
1390 LOGICAL :: do_symmetric, found
1391 REAL(kind=
dp) :: arg, coskl, fc, sinkl
1392 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: cblock, dblock, rblock
1394 DIMENSION(:),
POINTER :: nl_iterator
1396 CALL timeset(routinen, handle)
1398 nimg =
SIZE(denmat, 2)
1414 IF (do_symmetric .AND. iatom > jatom)
THEN
1420 icell = cell_to_index(cell(1), cell(2), cell(3))
1421 IF (icell < 1 .OR. icell > nimg) cycle
1423 arg = real(cell(1),
dp)*xkp(1) + real(cell(2),
dp)*xkp(2) + real(cell(3),
dp)*xkp(3)
1424 coskl = wkp*cos(
twopi*arg)
1425 sinkl = wkp*fc*sin(
twopi*arg)
1427 CALL dbcsr_get_block_p(matrix=denmat(ispin, icell)%matrix, row=irow, col=icol, &
1428 block=dblock, found=found)
1429 IF (.NOT. found) cycle
1432 CALL dbcsr_get_block_p(matrix=rpmat, row=irow, col=icol, block=rblock, found=found)
1433 IF (.NOT. found) cycle
1434 dblock = dblock + coskl*rblock
1436 CALL dbcsr_get_block_p(matrix=rpmat, row=irow, col=icol, block=rblock, found=found)
1437 IF (.NOT. found) cycle
1438 CALL dbcsr_get_block_p(matrix=cpmat, row=irow, col=icol, block=cblock, found=found)
1439 IF (.NOT. found) cycle
1440 dblock = dblock + coskl*rblock
1441 dblock = dblock + sinkl*cblock
1446 CALL timestop(handle)
1448 END SUBROUTINE transform_dmat
1461 SUBROUTINE symtrans(smat, pmat, kmat, rot, f0, atype, symmetric, antisymmetric)
1464 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: rot
1465 INTEGER,
DIMENSION(:),
INTENT(IN) :: f0, atype
1466 LOGICAL,
INTENT(IN),
OPTIONAL :: symmetric, antisymmetric
1468 CHARACTER(LEN=*),
PARAMETER :: routinen =
'symtrans'
1470 INTEGER :: handle, iatom, icol, ikind, ip, irow, &
1471 jcol, jkind, jp, jrow, natom, numnodes
1472 LOGICAL :: asym, dorot, found, perm, sym, trans
1473 REAL(kind=
dp) :: dr, fsign
1474 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: kroti, krotj, pblock, sblock
1478 CALL timeset(routinen, handle)
1482 IF (
PRESENT(symmetric)) sym = symmetric
1484 IF (
PRESENT(antisymmetric)) asym = antisymmetric
1486 cpassert(.NOT. (sym .AND. asym))
1487 cpassert((sym .OR. asym))
1493 IF (f0(iatom) == iatom) cycle
1500 IF (abs(sum(abs(rot)) - 3.0_dp) > 1.e-12_dp) dorot = .true.
1501 dr = abs(rot(1, 1) - 1.0_dp) + abs(rot(2, 2) - 1.0_dp) + abs(rot(3, 3) - 1.0_dp)
1502 IF (abs(dr) > 1.e-12_dp) dorot = .true.
1505 IF (asym) fsign = -1.0_dp
1507 IF (dorot .OR. perm)
THEN
1508 CALL cp_abort(__location__,
"k-points need FULL_GRID currently. "// &
1509 "Reduced grids not yet working correctly")
1514 IF (numnodes == 1)
THEN
1530 CALL dbcsr_get_block_p(matrix=smat, row=jrow, col=jcol, block=sblock, found=found)
1534 kroti => kmat(ikind)%rmat
1535 krotj => kmat(jkind)%rmat
1538 sblock = fsign*matmul(transpose(krotj), matmul(transpose(pblock), kroti))
1540 sblock = fsign*matmul(transpose(kroti), matmul(pblock, krotj))
1547 CALL cp_abort(__location__,
"k-points need FULL_GRID currently. "// &
1548 "Reduced grids not yet working correctly")
1569 kroti => kmat(ikind)%rmat
1570 krotj => kmat(jkind)%rmat
1573 sblock = fsign*matmul(transpose(krotj), matmul(transpose(sblock), kroti))
1575 sblock = fsign*matmul(transpose(kroti), matmul(sblock, krotj))
1586 CALL timestop(handle)
1588 END SUBROUTINE symtrans
1594 SUBROUTINE matprint(mat)
1597 INTEGER :: i, icol, iounit, irow
1598 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: mblock
1606 IF (iounit > 0)
THEN
1607 WRITE (iounit,
'(A,2I4)')
'BLOCK ', irow, icol
1608 DO i = 1,
SIZE(mblock, 1)
1609 WRITE (iounit,
'(8F12.6)') mblock(i, :)
1616 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