(git:e5b1968)
Loading...
Searching...
No Matches
kpoint_methods.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Routines needed for kpoint calculation
10!> \par History
11!> 2014.07 created [JGH]
12!> 2014.11 unified k-point and gamma-point code [Ole Schuett]
13!> \author JGH
14! **************************************************************************************************
17 USE cell_types, ONLY: cell_type,&
23 USE cp_dbcsr_api, ONLY: &
27 dbcsr_p_type, dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, &
28 dbcsr_type_symmetric
36 USE cp_fm_types, ONLY: &
41 USE cryssym, ONLY: crys_sym_gen,&
42 csym_type,&
47 USE fermi_utils, ONLY: fermikp,&
51 USE kinds, ONLY: dp
52 USE kpoint_types, ONLY: get_kpoint_info,&
60 USE mathconstants, ONLY: twopi
62 USE message_passing, ONLY: mp_cart_type,&
70 USE qs_mo_types, ONLY: allocate_mo_set,&
83 USE util, ONLY: get_limit
84#include "./base/base_uses.f90"
85
86 IMPLICIT NONE
87
88 PRIVATE
89
90 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'kpoint_methods'
91
95 PUBLIC :: rskp_transform
96
97! **************************************************************************************************
98
99CONTAINS
100
101! **************************************************************************************************
102!> \brief Generate the kpoints and initialize the kpoint environment
103!> \param kpoint The kpoint environment
104!> \param particle_set Particle types and coordinates
105!> \param cell Computational cell information
106! **************************************************************************************************
107 SUBROUTINE kpoint_initialize(kpoint, particle_set, cell)
108
109 TYPE(kpoint_type), POINTER :: kpoint
110 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
111 TYPE(cell_type), POINTER :: cell
112
113 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_initialize'
114
115 INTEGER :: handle, i, ic, ik, iounit, ir, ira, is, &
116 j, natom, nkind, nr, ns
117 INTEGER, ALLOCATABLE, DIMENSION(:) :: atype
118 LOGICAL :: spez
119 REAL(kind=dp) :: wsum
120 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: coord, scoord
121 TYPE(csym_type) :: crys_sym
122 TYPE(kpoint_sym_type), POINTER :: kpsym
123
124 CALL timeset(routinen, handle)
125
126 cpassert(ASSOCIATED(kpoint))
127
128 SELECT CASE (kpoint%kp_scheme)
129 CASE ("NONE")
130 ! do nothing
131 CASE ("GAMMA")
132 kpoint%nkp = 1
133 ALLOCATE (kpoint%xkp(3, 1), kpoint%wkp(1))
134 kpoint%xkp(1:3, 1) = 0.0_dp
135 kpoint%wkp(1) = 1.0_dp
136 ALLOCATE (kpoint%kp_sym(1))
137 NULLIFY (kpoint%kp_sym(1)%kpoint_sym)
138 CALL kpoint_sym_create(kpoint%kp_sym(1)%kpoint_sym)
139 CASE ("MONKHORST-PACK", "MACDONALD")
140
141 IF (.NOT. kpoint%symmetry) THEN
142 ! we set up a random molecule to avoid any possible symmetry
143 natom = 10
144 ALLOCATE (coord(3, natom), scoord(3, natom), atype(natom))
145 DO i = 1, natom
146 atype(i) = i
147 coord(1, i) = sin(i*0.12345_dp)
148 coord(2, i) = cos(i*0.23456_dp)
149 coord(3, i) = sin(i*0.34567_dp)
150 CALL real_to_scaled(scoord(1:3, i), coord(1:3, i), cell)
151 END DO
152 ELSE
153 natom = SIZE(particle_set)
154 ALLOCATE (scoord(3, natom), atype(natom))
155 DO i = 1, natom
156 CALL get_atomic_kind(atomic_kind=particle_set(i)%atomic_kind, kind_number=atype(i))
157 CALL real_to_scaled(scoord(1:3, i), particle_set(i)%r(1:3), cell)
158 END DO
159 END IF
160 IF (kpoint%verbose) THEN
162 ELSE
163 iounit = -1
164 END IF
165 ! kind type list
166 ALLOCATE (kpoint%atype(natom))
167 kpoint%atype = atype
168
169 CALL crys_sym_gen(crys_sym, scoord, atype, cell%hmat, delta=kpoint%eps_geo, iounit=iounit)
170 CALL kpoint_gen(crys_sym, kpoint%nkp_grid, symm=kpoint%symmetry, shift=kpoint%kp_shift, &
171 full_grid=kpoint%full_grid)
172 kpoint%nkp = crys_sym%nkpoint
173 ALLOCATE (kpoint%xkp(3, kpoint%nkp), kpoint%wkp(kpoint%nkp))
174 wsum = sum(crys_sym%wkpoint)
175 DO ik = 1, kpoint%nkp
176 kpoint%xkp(1:3, ik) = crys_sym%xkpoint(1:3, ik)
177 kpoint%wkp(ik) = crys_sym%wkpoint(ik)/wsum
178 END DO
179
180 ! print output
181 IF (kpoint%symmetry) CALL print_crys_symmetry(crys_sym)
182 IF (kpoint%symmetry) CALL print_kp_symmetry(crys_sym)
183
184 ! transfer symmetry information
185 ALLOCATE (kpoint%kp_sym(kpoint%nkp))
186 DO ik = 1, kpoint%nkp
187 NULLIFY (kpoint%kp_sym(ik)%kpoint_sym)
188 CALL kpoint_sym_create(kpoint%kp_sym(ik)%kpoint_sym)
189 kpsym => kpoint%kp_sym(ik)%kpoint_sym
190 IF (crys_sym%symlib .AND. .NOT. crys_sym%fullgrid .AND. crys_sym%istriz == 1) THEN
191 ! set up the symmetrization information
192 kpsym%nwght = nint(crys_sym%wkpoint(ik))
193 ns = kpsym%nwght
194 !
195 IF (ns > 1) THEN
196 kpsym%apply_symmetry = .true.
197 natom = SIZE(particle_set)
198 ALLOCATE (kpsym%rot(3, 3, ns))
199 ALLOCATE (kpsym%xkp(3, ns))
200 ALLOCATE (kpsym%rotp(ns))
201 ALLOCATE (kpsym%f0(natom, ns))
202 nr = 0
203 DO is = 1, SIZE(crys_sym%kplink, 2)
204 IF (crys_sym%kplink(2, is) == ik) THEN
205 nr = nr + 1
206 ir = crys_sym%kpop(is)
207 ira = abs(ir)
208 kpsym%rotp(nr) = ir
209 IF (ir > 0) THEN
210 kpsym%rot(1:3, 1:3, nr) = crys_sym%rt(1:3, 1:3, ira)
211 ELSE
212 kpsym%rot(1:3, 1:3, nr) = -crys_sym%rt(1:3, 1:3, ira)
213 END IF
214 kpsym%xkp(1:3, nr) = crys_sym%kpmesh(1:3, is)
215 DO ic = 1, crys_sym%nrtot
216 IF (crys_sym%ibrot(ic) == ira) THEN
217 kpsym%f0(1:natom, nr) = crys_sym%f0(1:natom, ic)
218 EXIT
219 END IF
220 END DO
221 END IF
222 END DO
223 ! Reduce inversion?
224 kpsym%nwred = nr
225 END IF
226 END IF
227 END DO
228 IF (kpoint%symmetry) THEN
229 nkind = maxval(atype)
230 ns = crys_sym%nrtot
231 ALLOCATE (kpoint%kind_rotmat(ns, nkind))
232 DO i = 1, ns
233 DO j = 1, nkind
234 NULLIFY (kpoint%kind_rotmat(i, j)%rmat)
235 END DO
236 END DO
237 ALLOCATE (kpoint%ibrot(ns))
238 kpoint%ibrot(1:ns) = crys_sym%ibrot(1:ns)
239 END IF
240
241 CALL release_csym_type(crys_sym)
242 DEALLOCATE (scoord, atype)
243
244 CASE ("GENERAL")
245 ! default: no symmetry settings
246 ALLOCATE (kpoint%kp_sym(kpoint%nkp))
247 DO i = 1, kpoint%nkp
248 NULLIFY (kpoint%kp_sym(i)%kpoint_sym)
249 CALL kpoint_sym_create(kpoint%kp_sym(i)%kpoint_sym)
250 END DO
251 CASE DEFAULT
252 cpassert(.false.)
253 END SELECT
254
255 ! check for consistency of options
256 SELECT CASE (kpoint%kp_scheme)
257 CASE ("NONE")
258 ! don't use k-point code
259 CASE ("GAMMA")
260 cpassert(kpoint%nkp == 1)
261 cpassert(sum(abs(kpoint%xkp)) <= 1.e-12_dp)
262 cpassert(kpoint%wkp(1) == 1.0_dp)
263 cpassert(.NOT. kpoint%symmetry)
264 CASE ("GENERAL")
265 cpassert(.NOT. kpoint%symmetry)
266 cpassert(kpoint%nkp >= 1)
267 CASE ("MONKHORST-PACK", "MACDONALD")
268 cpassert(kpoint%nkp >= 1)
269 END SELECT
270 IF (kpoint%use_real_wfn) THEN
271 ! what about inversion symmetry?
272 ikloop: DO ik = 1, kpoint%nkp
273 DO i = 1, 3
274 spez = (kpoint%xkp(i, ik) == 0.0_dp .OR. kpoint%xkp(i, ik) == 0.5_dp)
275 IF (.NOT. spez) EXIT ikloop
276 END DO
277 END DO ikloop
278 IF (.NOT. spez) THEN
279 ! Warning: real wfn might be wrong for this system
280 CALL cp_warn(__location__, &
281 "A calculation using real wavefunctions is requested. "// &
282 "We could not determine if the symmetry of the system allows real wavefunctions. ")
283 END IF
284 END IF
285
286 CALL timestop(handle)
287
288 END SUBROUTINE kpoint_initialize
289
290! **************************************************************************************************
291!> \brief Initialize the kpoint environment
292!> \param kpoint Kpoint environment
293!> \param para_env ...
294!> \param blacs_env ...
295!> \param with_aux_fit ...
296! **************************************************************************************************
297 SUBROUTINE kpoint_env_initialize(kpoint, para_env, blacs_env, with_aux_fit)
298
299 TYPE(kpoint_type), INTENT(INOUT) :: kpoint
300 TYPE(mp_para_env_type), INTENT(IN), TARGET :: para_env
301 TYPE(cp_blacs_env_type), INTENT(IN), TARGET :: blacs_env
302 LOGICAL, INTENT(IN), OPTIONAL :: with_aux_fit
303
304 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_env_initialize'
305
306 INTEGER :: handle, igr, ik, ikk, ngr, niogrp, nkp, &
307 nkp_grp, nkp_loc, npe, unit_nr
308 INTEGER, DIMENSION(2) :: dims, pos
309 LOGICAL :: aux_fit
310 TYPE(kpoint_env_p_type), DIMENSION(:), POINTER :: kp_aux_env, kp_env
311 TYPE(kpoint_env_type), POINTER :: kp
312 TYPE(mp_cart_type) :: comm_cart
313 TYPE(mp_para_env_type), POINTER :: para_env_inter_kp, para_env_kp
314
315 CALL timeset(routinen, handle)
316
317 IF (PRESENT(with_aux_fit)) THEN
318 aux_fit = with_aux_fit
319 ELSE
320 aux_fit = .false.
321 END IF
322
323 kpoint%para_env => para_env
324 CALL kpoint%para_env%retain()
325 kpoint%blacs_env_all => blacs_env
326 CALL kpoint%blacs_env_all%retain()
327
328 cpassert(.NOT. ASSOCIATED(kpoint%kp_env))
329 IF (aux_fit) THEN
330 cpassert(.NOT. ASSOCIATED(kpoint%kp_aux_env))
331 END IF
332
333 NULLIFY (kp_env, kp_aux_env)
334 nkp = kpoint%nkp
335 npe = para_env%num_pe
336 IF (npe == 1) THEN
337 ! only one process available -> owns all kpoints
338 ALLOCATE (kp_env(nkp))
339 DO ik = 1, nkp
340 NULLIFY (kp_env(ik)%kpoint_env)
341 CALL kpoint_env_create(kp_env(ik)%kpoint_env)
342 kp => kp_env(ik)%kpoint_env
343 kp%nkpoint = ik
344 kp%wkp = kpoint%wkp(ik)
345 kp%xkp(1:3) = kpoint%xkp(1:3, ik)
346 kp%is_local = .true.
347 END DO
348 kpoint%kp_env => kp_env
349
350 IF (aux_fit) THEN
351 ALLOCATE (kp_aux_env(nkp))
352 DO ik = 1, nkp
353 NULLIFY (kp_aux_env(ik)%kpoint_env)
354 CALL kpoint_env_create(kp_aux_env(ik)%kpoint_env)
355 kp => kp_aux_env(ik)%kpoint_env
356 kp%nkpoint = ik
357 kp%wkp = kpoint%wkp(ik)
358 kp%xkp(1:3) = kpoint%xkp(1:3, ik)
359 kp%is_local = .true.
360 END DO
361
362 kpoint%kp_aux_env => kp_aux_env
363 END IF
364
365 ALLOCATE (kpoint%kp_dist(2, 1))
366 kpoint%kp_dist(1, 1) = 1
367 kpoint%kp_dist(2, 1) = nkp
368 kpoint%kp_range(1) = 1
369 kpoint%kp_range(2) = nkp
370
371 ! parallel environments
372 kpoint%para_env_kp => para_env
373 CALL kpoint%para_env_kp%retain()
374 kpoint%para_env_inter_kp => para_env
375 CALL kpoint%para_env_inter_kp%retain()
376 kpoint%iogrp = .true.
377 kpoint%nkp_groups = 1
378 ELSE
379 IF (kpoint%parallel_group_size == -1) THEN
380 ! maximum parallelization over kpoints
381 ! making sure that the group size divides the npe and the nkp_grp the nkp
382 ! in the worst case, there will be no parallelism over kpoints.
383 DO igr = npe, 1, -1
384 IF (mod(npe, igr) .NE. 0) cycle
385 nkp_grp = npe/igr
386 IF (mod(nkp, nkp_grp) .NE. 0) cycle
387 ngr = igr
388 END DO
389 ELSE IF (kpoint%parallel_group_size == 0) THEN
390 ! no parallelization over kpoints
391 ngr = npe
392 ELSE IF (kpoint%parallel_group_size > 0) THEN
393 ngr = min(kpoint%parallel_group_size, npe)
394 ELSE
395 cpassert(.false.)
396 END IF
397 nkp_grp = npe/ngr
398 ! processor dimensions
399 dims(1) = ngr
400 dims(2) = nkp_grp
401 cpassert(mod(nkp, nkp_grp) == 0)
402 nkp_loc = nkp/nkp_grp
403
404 IF ((dims(1)*dims(2) /= npe)) THEN
405 cpabort("Number of processors is not divisible by the kpoint group size.")
406 END IF
407
408 ! Create the subgroups, one for each k-point group and one interconnecting group
409 CALL comm_cart%create(comm_old=para_env, ndims=2, dims=dims)
410 pos = comm_cart%mepos_cart
411 ALLOCATE (para_env_kp)
412 CALL para_env_kp%from_split(comm_cart, pos(2))
413 ALLOCATE (para_env_inter_kp)
414 CALL para_env_inter_kp%from_split(comm_cart, pos(1))
415 CALL comm_cart%free()
416
417 niogrp = 0
418 IF (para_env%is_source()) niogrp = 1
419 CALL para_env_kp%sum(niogrp)
420 kpoint%iogrp = (niogrp == 1)
421
422 ! parallel groups
423 kpoint%para_env_kp => para_env_kp
424 kpoint%para_env_inter_kp => para_env_inter_kp
425
426 ! distribution of kpoints
427 ALLOCATE (kpoint%kp_dist(2, nkp_grp))
428 DO igr = 1, nkp_grp
429 kpoint%kp_dist(1:2, igr) = get_limit(nkp, nkp_grp, igr - 1)
430 END DO
431 ! local kpoints
432 kpoint%kp_range(1:2) = kpoint%kp_dist(1:2, para_env_inter_kp%mepos + 1)
433
434 ALLOCATE (kp_env(nkp_loc))
435 DO ik = 1, nkp_loc
436 NULLIFY (kp_env(ik)%kpoint_env)
437 ikk = kpoint%kp_range(1) + ik - 1
438 CALL kpoint_env_create(kp_env(ik)%kpoint_env)
439 kp => kp_env(ik)%kpoint_env
440 kp%nkpoint = ikk
441 kp%wkp = kpoint%wkp(ikk)
442 kp%xkp(1:3) = kpoint%xkp(1:3, ikk)
443 kp%is_local = (ngr == 1)
444 END DO
445 kpoint%kp_env => kp_env
446
447 IF (aux_fit) THEN
448 ALLOCATE (kp_aux_env(nkp_loc))
449 DO ik = 1, nkp_loc
450 NULLIFY (kp_aux_env(ik)%kpoint_env)
451 ikk = kpoint%kp_range(1) + ik - 1
452 CALL kpoint_env_create(kp_aux_env(ik)%kpoint_env)
453 kp => kp_aux_env(ik)%kpoint_env
454 kp%nkpoint = ikk
455 kp%wkp = kpoint%wkp(ikk)
456 kp%xkp(1:3) = kpoint%xkp(1:3, ikk)
457 kp%is_local = (ngr == 1)
458 END DO
459 kpoint%kp_aux_env => kp_aux_env
460 END IF
461
463
464 IF (unit_nr > 0 .AND. kpoint%verbose) THEN
465 WRITE (unit_nr, *)
466 WRITE (unit_nr, fmt="(T2,A,T71,I10)") "KPOINTS| Number of kpoint groups ", nkp_grp
467 WRITE (unit_nr, fmt="(T2,A,T71,I10)") "KPOINTS| Size of each kpoint group", ngr
468 WRITE (unit_nr, fmt="(T2,A,T71,I10)") "KPOINTS| Number of kpoints per group", nkp_loc
469 END IF
470 kpoint%nkp_groups = nkp_grp
471
472 END IF
473
474 CALL timestop(handle)
475
476 END SUBROUTINE kpoint_env_initialize
477
478! **************************************************************************************************
479!> \brief Initialize a set of MOs and density matrix for each kpoint (kpoint group)
480!> \param kpoint Kpoint environment
481!> \param mos Reference MOs (global)
482!> \param added_mos ...
483!> \param for_aux_fit ...
484! **************************************************************************************************
485 SUBROUTINE kpoint_initialize_mos(kpoint, mos, added_mos, for_aux_fit)
486
487 TYPE(kpoint_type), POINTER :: kpoint
488 TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
489 INTEGER, INTENT(IN), OPTIONAL :: added_mos
490 LOGICAL, OPTIONAL :: for_aux_fit
491
492 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_initialize_mos'
493
494 INTEGER :: handle, ic, ik, is, nadd, nao, nc, &
495 nelectron, nkp_loc, nmo, nmorig(2), &
496 nspin
497 LOGICAL :: aux_fit
498 REAL(kind=dp) :: flexible_electron_count, maxocc, n_el_f
499 TYPE(cp_blacs_env_type), POINTER :: blacs_env
500 TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools
501 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
502 TYPE(cp_fm_type), POINTER :: fmlocal
503 TYPE(kpoint_env_type), POINTER :: kp
504 TYPE(qs_matrix_pools_type), POINTER :: mpools
505
506 CALL timeset(routinen, handle)
507
508 IF (PRESENT(for_aux_fit)) THEN
509 aux_fit = for_aux_fit
510 ELSE
511 aux_fit = .false.
512 END IF
513
514 cpassert(ASSOCIATED(kpoint))
515
516 IF (.true. .OR. ASSOCIATED(mos(1)%mo_coeff)) THEN
517 IF (aux_fit) THEN
518 cpassert(ASSOCIATED(kpoint%kp_aux_env))
519 END IF
520
521 IF (PRESENT(added_mos)) THEN
522 nadd = added_mos
523 ELSE
524 nadd = 0
525 END IF
526
527 IF (kpoint%use_real_wfn) THEN
528 nc = 1
529 ELSE
530 nc = 2
531 END IF
532 nspin = SIZE(mos, 1)
533 nkp_loc = kpoint%kp_range(2) - kpoint%kp_range(1) + 1
534 IF (nkp_loc > 0) THEN
535 IF (aux_fit) THEN
536 cpassert(SIZE(kpoint%kp_aux_env) == nkp_loc)
537 ELSE
538 cpassert(SIZE(kpoint%kp_env) == nkp_loc)
539 END IF
540 ! allocate the mo sets, correct number of kpoints (local), real/complex, spin
541 DO ik = 1, nkp_loc
542 IF (aux_fit) THEN
543 kp => kpoint%kp_aux_env(ik)%kpoint_env
544 ELSE
545 kp => kpoint%kp_env(ik)%kpoint_env
546 END IF
547 ALLOCATE (kp%mos(nc, nspin))
548 DO is = 1, nspin
549 CALL get_mo_set(mos(is), nao=nao, nmo=nmo, nelectron=nelectron, &
550 n_el_f=n_el_f, maxocc=maxocc, flexible_electron_count=flexible_electron_count)
551 nmo = min(nao, nmo + nadd)
552 DO ic = 1, nc
553 CALL allocate_mo_set(kp%mos(ic, is), nao, nmo, nelectron, n_el_f, maxocc, &
554 flexible_electron_count)
555 END DO
556 END DO
557 END DO
558
559 ! generate the blacs environment for the kpoint group
560 ! we generate a blacs env for each kpoint group in parallel
561 ! we assume here that the group para_env_inter_kp will connect
562 ! equivalent parts of fm matrices, i.e. no reshuffeling of processors
563 NULLIFY (blacs_env)
564 IF (ASSOCIATED(kpoint%blacs_env)) THEN
565 blacs_env => kpoint%blacs_env
566 ELSE
567 CALL cp_blacs_env_create(blacs_env=blacs_env, para_env=kpoint%para_env_kp)
568 kpoint%blacs_env => blacs_env
569 END IF
570
571 ! set possible new number of MOs
572 DO is = 1, nspin
573 CALL get_mo_set(mos(is), nmo=nmorig(is))
574 nmo = min(nao, nmorig(is) + nadd)
575 CALL set_mo_set(mos(is), nmo=nmo)
576 END DO
577 ! matrix pools for the kpoint group, information on MOs is transferred using
578 ! generic mos structure
579 NULLIFY (mpools)
580 CALL mpools_create(mpools=mpools)
581 CALL mpools_rebuild_fm_pools(mpools=mpools, mos=mos, &
582 blacs_env=blacs_env, para_env=kpoint%para_env_kp)
583
584 IF (aux_fit) THEN
585 kpoint%mpools_aux_fit => mpools
586 ELSE
587 kpoint%mpools => mpools
588 END IF
589
590 ! reset old number of MOs
591 DO is = 1, nspin
592 CALL set_mo_set(mos(is), nmo=nmorig(is))
593 END DO
594
595 ! allocate density matrices
596 CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
597 ALLOCATE (fmlocal)
598 CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmlocal)
599 CALL cp_fm_get_info(fmlocal, matrix_struct=matrix_struct)
600 DO ik = 1, nkp_loc
601 IF (aux_fit) THEN
602 kp => kpoint%kp_aux_env(ik)%kpoint_env
603 ELSE
604 kp => kpoint%kp_env(ik)%kpoint_env
605 END IF
606 ! density matrix
607 CALL cp_fm_release(kp%pmat)
608 ALLOCATE (kp%pmat(nc, nspin))
609 DO is = 1, nspin
610 DO ic = 1, nc
611 CALL cp_fm_create(kp%pmat(ic, is), matrix_struct)
612 END DO
613 END DO
614 ! energy weighted density matrix
615 CALL cp_fm_release(kp%wmat)
616 ALLOCATE (kp%wmat(nc, nspin))
617 DO is = 1, nspin
618 DO ic = 1, nc
619 CALL cp_fm_create(kp%wmat(ic, is), matrix_struct)
620 END DO
621 END DO
622 END DO
623 CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmlocal)
624 DEALLOCATE (fmlocal)
625
626 END IF
627
628 END IF
629
630 CALL timestop(handle)
631
632 END SUBROUTINE kpoint_initialize_mos
633
634! **************************************************************************************************
635!> \brief ...
636!> \param kpoint ...
637! **************************************************************************************************
638 SUBROUTINE kpoint_initialize_mo_set(kpoint)
639 TYPE(kpoint_type), POINTER :: kpoint
640
641 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_initialize_mo_set'
642
643 INTEGER :: handle, ic, ik, ikk, ispin
644 TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_mo_fm_pools
645 TYPE(cp_fm_type), POINTER :: mo_coeff
646 TYPE(mo_set_type), DIMENSION(:, :), POINTER :: moskp
647
648 CALL timeset(routinen, handle)
649
650 DO ik = 1, SIZE(kpoint%kp_env)
651 CALL mpools_get(kpoint%mpools, ao_mo_fm_pools=ao_mo_fm_pools)
652 moskp => kpoint%kp_env(ik)%kpoint_env%mos
653 ikk = kpoint%kp_range(1) + ik - 1
654 cpassert(ASSOCIATED(moskp))
655 DO ispin = 1, SIZE(moskp, 2)
656 DO ic = 1, SIZE(moskp, 1)
657 CALL get_mo_set(moskp(ic, ispin), mo_coeff=mo_coeff)
658 IF (.NOT. ASSOCIATED(mo_coeff)) THEN
659 CALL init_mo_set(moskp(ic, ispin), &
660 fm_pool=ao_mo_fm_pools(ispin)%pool, name="kpoints")
661 END IF
662 END DO
663 END DO
664 END DO
665
666 CALL timestop(handle)
667
668 END SUBROUTINE kpoint_initialize_mo_set
669
670! **************************************************************************************************
671!> \brief Generates the mapping of cell indices and linear RS index
672!> CELL (0,0,0) is always mapped to index 1
673!> \param kpoint Kpoint environment
674!> \param sab_nl Defining neighbour list
675!> \param para_env Parallel environment
676!> \param dft_control ...
677! **************************************************************************************************
678 SUBROUTINE kpoint_init_cell_index(kpoint, sab_nl, para_env, dft_control)
679
680 TYPE(kpoint_type), POINTER :: kpoint
681 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
682 POINTER :: sab_nl
683 TYPE(mp_para_env_type), POINTER :: para_env
684 TYPE(dft_control_type), POINTER :: dft_control
685
686 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_init_cell_index'
687
688 INTEGER :: handle, i1, i2, i3, ic, icount, it, &
689 ncount
690 INTEGER, DIMENSION(3) :: cell, itm
691 INTEGER, DIMENSION(:, :), POINTER :: index_to_cell, list
692 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index, cti
693 LOGICAL :: new
695 DIMENSION(:), POINTER :: nl_iterator
696
697 NULLIFY (cell_to_index, index_to_cell)
698
699 CALL timeset(routinen, handle)
700
701 cpassert(ASSOCIATED(kpoint))
702
703 ALLOCATE (list(3, 125))
704 list = 0
705 icount = 1
706
707 CALL neighbor_list_iterator_create(nl_iterator, sab_nl)
708 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
709 CALL get_iterator_info(nl_iterator, cell=cell)
710
711 new = .true.
712 DO ic = 1, icount
713 IF (cell(1) == list(1, ic) .AND. cell(2) == list(2, ic) .AND. &
714 cell(3) == list(3, ic)) THEN
715 new = .false.
716 EXIT
717 END IF
718 END DO
719 IF (new) THEN
720 icount = icount + 1
721 IF (icount > SIZE(list, 2)) THEN
722 CALL reallocate(list, 1, 3, 1, 2*SIZE(list, 2))
723 END IF
724 list(1:3, icount) = cell(1:3)
725 END IF
726
727 END DO
728 CALL neighbor_list_iterator_release(nl_iterator)
729
730 itm(1) = maxval(abs(list(1, 1:icount)))
731 itm(2) = maxval(abs(list(2, 1:icount)))
732 itm(3) = maxval(abs(list(3, 1:icount)))
733 CALL para_env%max(itm)
734 it = maxval(itm(1:3))
735 IF (ASSOCIATED(kpoint%cell_to_index)) THEN
736 DEALLOCATE (kpoint%cell_to_index)
737 END IF
738 ALLOCATE (kpoint%cell_to_index(-itm(1):itm(1), -itm(2):itm(2), -itm(3):itm(3)))
739 cell_to_index => kpoint%cell_to_index
740 cti => cell_to_index
741 cti(:, :, :) = 0
742 DO ic = 1, icount
743 i1 = list(1, ic)
744 i2 = list(2, ic)
745 i3 = list(3, ic)
746 cti(i1, i2, i3) = ic
747 END DO
748 CALL para_env%sum(cti)
749 ncount = 0
750 DO i1 = -itm(1), itm(1)
751 DO i2 = -itm(2), itm(2)
752 DO i3 = -itm(3), itm(3)
753 IF (cti(i1, i2, i3) == 0) THEN
754 cti(i1, i2, i3) = 1000000
755 ELSE
756 ncount = ncount + 1
757 cti(i1, i2, i3) = (abs(i1) + abs(i2) + abs(i3))*1000 + abs(i3)*100 + abs(i2)*10 + abs(i1)
758 cti(i1, i2, i3) = cti(i1, i2, i3) + (i1 + i2 + i3)
759 END IF
760 END DO
761 END DO
762 END DO
763
764 IF (ASSOCIATED(kpoint%index_to_cell)) THEN
765 DEALLOCATE (kpoint%index_to_cell)
766 END IF
767 ALLOCATE (kpoint%index_to_cell(3, ncount))
768 index_to_cell => kpoint%index_to_cell
769 DO ic = 1, ncount
770 cell = minloc(cti)
771 i1 = cell(1) - 1 - itm(1)
772 i2 = cell(2) - 1 - itm(2)
773 i3 = cell(3) - 1 - itm(3)
774 cti(i1, i2, i3) = 1000000
775 index_to_cell(1, ic) = i1
776 index_to_cell(2, ic) = i2
777 index_to_cell(3, ic) = i3
778 END DO
779 cti(:, :, :) = 0
780 DO ic = 1, ncount
781 i1 = index_to_cell(1, ic)
782 i2 = index_to_cell(2, ic)
783 i3 = index_to_cell(3, ic)
784 cti(i1, i2, i3) = ic
785 END DO
786
787 ! keep pointer to this neighborlist
788 kpoint%sab_nl => sab_nl
789
790 ! set number of images
791 dft_control%nimages = SIZE(index_to_cell, 2)
792
793 DEALLOCATE (list)
794
795 CALL timestop(handle)
796 END SUBROUTINE kpoint_init_cell_index
797
798! **************************************************************************************************
799!> \brief Transformation of real space matrices to a kpoint
800!> \param rmatrix Real part of kpoint matrix
801!> \param cmatrix Complex part of kpoint matrix (optional)
802!> \param rsmat Real space matrices
803!> \param ispin Spin index
804!> \param xkp Kpoint coordinates
805!> \param cell_to_index mapping of cell indices to RS index
806!> \param sab_nl Defining neighbor list
807!> \param is_complex Matrix to be transformed is imaginary
808!> \param rs_sign Matrix to be transformed is csaled by rs_sign
809! **************************************************************************************************
810 SUBROUTINE rskp_transform(rmatrix, cmatrix, rsmat, ispin, &
811 xkp, cell_to_index, sab_nl, is_complex, rs_sign)
812
813 TYPE(dbcsr_type) :: rmatrix
814 TYPE(dbcsr_type), OPTIONAL :: cmatrix
815 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rsmat
816 INTEGER, INTENT(IN) :: ispin
817 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: xkp
818 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
819 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
820 POINTER :: sab_nl
821 LOGICAL, INTENT(IN), OPTIONAL :: is_complex
822 REAL(kind=dp), INTENT(IN), OPTIONAL :: rs_sign
823
824 CHARACTER(LEN=*), PARAMETER :: routinen = 'rskp_transform'
825
826 INTEGER :: handle, iatom, ic, icol, irow, jatom, &
827 nimg
828 INTEGER, DIMENSION(3) :: cell
829 LOGICAL :: do_symmetric, found, my_complex, &
830 wfn_real_only
831 REAL(kind=dp) :: arg, coskl, fsign, fsym, sinkl
832 REAL(kind=dp), DIMENSION(:, :), POINTER :: cblock, rblock, rsblock
834 DIMENSION(:), POINTER :: nl_iterator
835
836 CALL timeset(routinen, handle)
837
838 my_complex = .false.
839 IF (PRESENT(is_complex)) my_complex = is_complex
840
841 fsign = 1.0_dp
842 IF (PRESENT(rs_sign)) fsign = rs_sign
843
844 wfn_real_only = .true.
845 IF (PRESENT(cmatrix)) wfn_real_only = .false.
846
847 nimg = SIZE(rsmat, 2)
848
849 CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
850
851 CALL neighbor_list_iterator_create(nl_iterator, sab_nl)
852 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
853 CALL get_iterator_info(nl_iterator, iatom=iatom, jatom=jatom, cell=cell)
854
855 ! fsym = +- 1 is due to real space matrices being non-symmetric (although in a symmtric type)
856 ! with the link S_mu^0,nu^b = S_nu^0,mu^-b, and the KP matrices beeing Hermitian
857 fsym = 1.0_dp
858 irow = iatom
859 icol = jatom
860 IF (do_symmetric .AND. (iatom > jatom)) THEN
861 irow = jatom
862 icol = iatom
863 fsym = -1.0_dp
864 END IF
865
866 ic = cell_to_index(cell(1), cell(2), cell(3))
867 IF (ic < 1 .OR. ic > nimg) cycle
868
869 arg = real(cell(1), dp)*xkp(1) + real(cell(2), dp)*xkp(2) + real(cell(3), dp)*xkp(3)
870 IF (my_complex) THEN
871 coskl = fsign*fsym*cos(twopi*arg)
872 sinkl = fsign*sin(twopi*arg)
873 ELSE
874 coskl = fsign*cos(twopi*arg)
875 sinkl = fsign*fsym*sin(twopi*arg)
876 END IF
877
878 CALL dbcsr_get_block_p(matrix=rsmat(ispin, ic)%matrix, row=irow, col=icol, &
879 block=rsblock, found=found)
880 IF (.NOT. found) cycle
881
882 IF (wfn_real_only) THEN
883 CALL dbcsr_get_block_p(matrix=rmatrix, row=irow, col=icol, &
884 block=rblock, found=found)
885 IF (.NOT. found) cycle
886 rblock = rblock + coskl*rsblock
887 ELSE
888 CALL dbcsr_get_block_p(matrix=rmatrix, row=irow, col=icol, &
889 block=rblock, found=found)
890 IF (.NOT. found) cycle
891 CALL dbcsr_get_block_p(matrix=cmatrix, row=irow, col=icol, &
892 block=cblock, found=found)
893 IF (.NOT. found) cycle
894 rblock = rblock + coskl*rsblock
895 cblock = cblock + sinkl*rsblock
896 END IF
897
898 END DO
899 CALL neighbor_list_iterator_release(nl_iterator)
900
901 CALL timestop(handle)
902
903 END SUBROUTINE rskp_transform
904
905! **************************************************************************************************
906!> \brief Given the eigenvalues of all kpoints, calculates the occupation numbers
907!> \param kpoint Kpoint environment
908!> \param smear Smearing information
909!> \param probe ...
910! **************************************************************************************************
911 SUBROUTINE kpoint_set_mo_occupation(kpoint, smear, probe)
912
913 TYPE(kpoint_type), POINTER :: kpoint
914 TYPE(smear_type), POINTER :: smear
915 TYPE(hairy_probes_type), DIMENSION(:), OPTIONAL, &
916 POINTER :: probe
917
918 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_set_mo_occupation'
919
920 INTEGER :: handle, ik, ikpgr, ispin, kplocal, nao, &
921 nb, ncol_global, ne_a, ne_b, &
922 nelectron, nkp, nmo, nrow_global, nspin
923 INTEGER, DIMENSION(2) :: kp_range
924 REAL(kind=dp) :: kts, mu, mus(2), nel
925 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: smatrix
926 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: weig, wocc
927 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: icoeff, rcoeff
928 REAL(kind=dp), DIMENSION(:), POINTER :: eigenvalues, occupation, wkp
929 TYPE(cp_fm_type), POINTER :: mo_coeff
930 TYPE(kpoint_env_type), POINTER :: kp
931 TYPE(mo_set_type), POINTER :: mo_set
932 TYPE(mp_para_env_type), POINTER :: para_env_inter_kp
933
934 CALL timeset(routinen, handle)
935
936 ! first collect all the eigenvalues
937 CALL get_kpoint_info(kpoint, nkp=nkp)
938 kp => kpoint%kp_env(1)%kpoint_env
939 nspin = SIZE(kp%mos, 2)
940 mo_set => kp%mos(1, 1)
941 CALL get_mo_set(mo_set, nmo=nmo, nao=nao, nelectron=nelectron)
942 ne_a = nelectron
943 IF (nspin == 2) THEN
944 CALL get_mo_set(kp%mos(1, 2), nmo=nb, nelectron=ne_b)
945 cpassert(nmo == nb)
946 END IF
947 ALLOCATE (weig(nmo, nkp, nspin), wocc(nmo, nkp, nspin))
948 weig = 0.0_dp
949 wocc = 0.0_dp
950 IF (PRESENT(probe)) THEN
951 ALLOCATE (rcoeff(nao, nmo, nkp, nspin), icoeff(nao, nmo, nkp, nspin))
952 rcoeff = 0.0_dp !coeff, real part
953 icoeff = 0.0_dp !coeff, imaginary part
954 END IF
955 CALL get_kpoint_info(kpoint, kp_range=kp_range)
956 kplocal = kp_range(2) - kp_range(1) + 1
957 DO ikpgr = 1, kplocal
958 ik = kp_range(1) + ikpgr - 1
959 kp => kpoint%kp_env(ikpgr)%kpoint_env
960 DO ispin = 1, nspin
961 mo_set => kp%mos(1, ispin)
962 CALL get_mo_set(mo_set, eigenvalues=eigenvalues)
963 weig(1:nmo, ik, ispin) = eigenvalues(1:nmo)
964 IF (PRESENT(probe)) THEN
965 CALL get_mo_set(mo_set, mo_coeff=mo_coeff)
966 CALL cp_fm_get_info(mo_coeff, &
967 nrow_global=nrow_global, &
968 ncol_global=ncol_global)
969 ALLOCATE (smatrix(nrow_global, ncol_global))
970 CALL cp_fm_get_submatrix(mo_coeff, smatrix)
971
972 rcoeff(1:nao, 1:nmo, ik, ispin) = smatrix(1:nrow_global, 1:ncol_global)
973
974 DEALLOCATE (smatrix)
975
976 mo_set => kp%mos(2, ispin)
977
978 CALL get_mo_set(mo_set, mo_coeff=mo_coeff)
979 CALL cp_fm_get_info(mo_coeff, &
980 nrow_global=nrow_global, &
981 ncol_global=ncol_global)
982 ALLOCATE (smatrix(nrow_global, ncol_global))
983 CALL cp_fm_get_submatrix(mo_coeff, smatrix)
984
985 icoeff(1:nao, 1:nmo, ik, ispin) = smatrix(1:nrow_global, 1:ncol_global)
986
987 mo_set => kp%mos(1, ispin)
988
989 DEALLOCATE (smatrix)
990 END IF
991 END DO
992 END DO
993 CALL get_kpoint_info(kpoint, para_env_inter_kp=para_env_inter_kp)
994 CALL para_env_inter_kp%sum(weig)
995
996 IF (PRESENT(probe)) THEN
997 CALL para_env_inter_kp%sum(rcoeff)
998 CALL para_env_inter_kp%sum(icoeff)
999 END IF
1000
1001 CALL get_kpoint_info(kpoint, wkp=wkp)
1002
1003!calling of HP module HERE, before smear
1004 IF (PRESENT(probe)) THEN
1005 smear%do_smear = .false. !ensures smearing is switched off
1006
1007 IF (nspin == 1) THEN
1008 nel = real(nelectron, kind=dp)
1009 CALL probe_occupancy_kp(wocc(:, :, :), mus(1), kts, weig(:, :, :), rcoeff(:, :, :, :), icoeff(:, :, :, :), 2.0d0, &
1010 probe, nel, wkp)
1011 ELSE
1012 nel = real(ne_a, kind=dp) + real(ne_b, kind=dp)
1013 CALL probe_occupancy_kp(wocc(:, :, :), mu, kts, weig(:, :, :), rcoeff(:, :, :, :), icoeff(:, :, :, :), 1.0d0, &
1014 probe, nel, wkp)
1015 kts = kts/2._dp
1016 mus(1:2) = mu
1017 END IF
1018
1019 DO ikpgr = 1, kplocal
1020 ik = kp_range(1) + ikpgr - 1
1021 kp => kpoint%kp_env(ikpgr)%kpoint_env
1022 DO ispin = 1, nspin
1023 mo_set => kp%mos(1, ispin)
1024 CALL get_mo_set(mo_set, eigenvalues=eigenvalues, occupation_numbers=occupation)
1025 eigenvalues(1:nmo) = weig(1:nmo, ik, ispin)
1026 occupation(1:nmo) = wocc(1:nmo, ik, ispin)
1027 mo_set%kTS = kts
1028 mo_set%mu = mus(ispin)
1029
1030 CALL get_mo_set(mo_set, mo_coeff=mo_coeff)
1031 !get smatrix for kpoint_env ikp
1032 CALL cp_fm_get_info(mo_coeff, &
1033 nrow_global=nrow_global, &
1034 ncol_global=ncol_global)
1035 ALLOCATE (smatrix(nrow_global, ncol_global))
1036 CALL cp_fm_get_submatrix(mo_coeff, smatrix)
1037
1038 smatrix(1:nrow_global, 1:ncol_global) = rcoeff(1:nao, 1:nmo, ik, ispin)
1039 DEALLOCATE (smatrix)
1040
1041 mo_set => kp%mos(2, ispin)
1042
1043 CALL get_mo_set(mo_set, mo_coeff=mo_coeff)
1044 !get smatrix for kpoint_env ikp
1045 CALL cp_fm_get_info(mo_coeff, &
1046 nrow_global=nrow_global, &
1047 ncol_global=ncol_global)
1048 ALLOCATE (smatrix(nrow_global, ncol_global))
1049 CALL cp_fm_get_submatrix(mo_coeff, smatrix)
1050
1051 smatrix(1:nrow_global, 1:ncol_global) = icoeff(1:nao, 1:nmo, ik, ispin)
1052 DEALLOCATE (smatrix)
1053
1054 mo_set => kp%mos(1, ispin)
1055
1056 END DO
1057 END DO
1058
1059 DEALLOCATE (weig, wocc, rcoeff, icoeff)
1060
1061 END IF
1062
1063 IF (PRESENT(probe) .EQV. .false.) THEN
1064 IF (smear%do_smear) THEN
1065 ! finite electronic temperature
1066 SELECT CASE (smear%method)
1067 CASE (smear_fermi_dirac)
1068 IF (nspin == 1) THEN
1069 nel = real(nelectron, kind=dp)
1070 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, &
1071 smear%electronic_temperature, 2.0_dp)
1072 ELSE IF (smear%fixed_mag_mom > 0.0_dp) THEN
1073 nel = real(ne_a, kind=dp)
1074 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, &
1075 smear%electronic_temperature, 1.0_dp)
1076 nel = real(ne_b, kind=dp)
1077 CALL fermikp(wocc(:, :, 2), mus(2), kts, weig(:, :, 2), nel, wkp, &
1078 smear%electronic_temperature, 1.0_dp)
1079 ELSE
1080 nel = real(ne_a, kind=dp) + real(ne_b, kind=dp)
1081 CALL fermikp2(wocc(:, :, :), mu, kts, weig(:, :, :), nel, wkp, &
1082 smear%electronic_temperature)
1083 kts = kts/2._dp
1084 mus(1:2) = mu
1085 END IF
1086 CASE DEFAULT
1087 cpabort("kpoints: Selected smearing not (yet) supported")
1088 END SELECT
1089 ELSE
1090 ! fixed occupations (2/1)
1091 IF (nspin == 1) THEN
1092 nel = real(nelectron, kind=dp)
1093 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, 0.0_dp, 2.0_dp)
1094 ELSE
1095 nel = real(ne_a, kind=dp)
1096 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, 0.0_dp, 1.0_dp)
1097 nel = real(ne_b, kind=dp)
1098 CALL fermikp(wocc(:, :, 2), mus(2), kts, weig(:, :, 2), nel, wkp, 0.0_dp, 1.0_dp)
1099 END IF
1100 END IF
1101 DO ikpgr = 1, kplocal
1102 ik = kp_range(1) + ikpgr - 1
1103 kp => kpoint%kp_env(ikpgr)%kpoint_env
1104 DO ispin = 1, nspin
1105 mo_set => kp%mos(1, ispin)
1106 CALL get_mo_set(mo_set, eigenvalues=eigenvalues, occupation_numbers=occupation)
1107 eigenvalues(1:nmo) = weig(1:nmo, ik, ispin)
1108 occupation(1:nmo) = wocc(1:nmo, ik, ispin)
1109 mo_set%kTS = kts
1110 mo_set%mu = mus(ispin)
1111 END DO
1112 END DO
1113
1114 DEALLOCATE (weig, wocc)
1115
1116 END IF
1117
1118 CALL timestop(handle)
1119
1120 END SUBROUTINE kpoint_set_mo_occupation
1121
1122! **************************************************************************************************
1123!> \brief Calculate kpoint density matrices (rho(k), owned by kpoint groups)
1124!> \param kpoint kpoint environment
1125!> \param energy_weighted calculate energy weighted density matrix
1126!> \param for_aux_fit ...
1127! **************************************************************************************************
1128 SUBROUTINE kpoint_density_matrices(kpoint, energy_weighted, for_aux_fit)
1129
1130 TYPE(kpoint_type), POINTER :: kpoint
1131 LOGICAL, OPTIONAL :: energy_weighted, for_aux_fit
1132
1133 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_density_matrices'
1134
1135 INTEGER :: handle, ikpgr, ispin, kplocal, nao, nmo, &
1136 nspin
1137 INTEGER, DIMENSION(2) :: kp_range
1138 LOGICAL :: aux_fit, wtype
1139 REAL(kind=dp), DIMENSION(:), POINTER :: eigenvalues, occupation
1140 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
1141 TYPE(cp_fm_type) :: fwork
1142 TYPE(cp_fm_type), POINTER :: cpmat, pmat, rpmat
1143 TYPE(kpoint_env_type), POINTER :: kp
1144 TYPE(mo_set_type), POINTER :: mo_set
1145
1146 CALL timeset(routinen, handle)
1147
1148 IF (PRESENT(energy_weighted)) THEN
1149 wtype = energy_weighted
1150 ELSE
1151 ! default is normal density matrix
1152 wtype = .false.
1153 END IF
1154
1155 IF (PRESENT(for_aux_fit)) THEN
1156 aux_fit = for_aux_fit
1157 ELSE
1158 aux_fit = .false.
1159 END IF
1160
1161 IF (aux_fit) THEN
1162 cpassert(ASSOCIATED(kpoint%kp_aux_env))
1163 END IF
1164
1165 ! work matrix
1166 IF (aux_fit) THEN
1167 mo_set => kpoint%kp_aux_env(1)%kpoint_env%mos(1, 1)
1168 ELSE
1169 mo_set => kpoint%kp_env(1)%kpoint_env%mos(1, 1)
1170 END IF
1171 CALL get_mo_set(mo_set, nao=nao, nmo=nmo)
1172 CALL cp_fm_get_info(mo_set%mo_coeff, matrix_struct=matrix_struct)
1173 CALL cp_fm_create(fwork, matrix_struct)
1174
1175 CALL get_kpoint_info(kpoint, kp_range=kp_range)
1176 kplocal = kp_range(2) - kp_range(1) + 1
1177 DO ikpgr = 1, kplocal
1178 IF (aux_fit) THEN
1179 kp => kpoint%kp_aux_env(ikpgr)%kpoint_env
1180 ELSE
1181 kp => kpoint%kp_env(ikpgr)%kpoint_env
1182 END IF
1183 nspin = SIZE(kp%mos, 2)
1184 DO ispin = 1, nspin
1185 mo_set => kp%mos(1, ispin)
1186 IF (wtype) THEN
1187 CALL get_mo_set(mo_set, eigenvalues=eigenvalues)
1188 END IF
1189 IF (kpoint%use_real_wfn) THEN
1190 IF (wtype) THEN
1191 pmat => kp%wmat(1, ispin)
1192 ELSE
1193 pmat => kp%pmat(1, ispin)
1194 END IF
1195 CALL get_mo_set(mo_set, occupation_numbers=occupation)
1196 CALL cp_fm_to_fm(mo_set%mo_coeff, fwork)
1197 CALL cp_fm_column_scale(fwork, occupation)
1198 IF (wtype) THEN
1199 CALL cp_fm_column_scale(fwork, eigenvalues)
1200 END IF
1201 CALL parallel_gemm("N", "T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, pmat)
1202 ELSE
1203 IF (wtype) THEN
1204 rpmat => kp%wmat(1, ispin)
1205 cpmat => kp%wmat(2, ispin)
1206 ELSE
1207 rpmat => kp%pmat(1, ispin)
1208 cpmat => kp%pmat(2, ispin)
1209 END IF
1210 CALL get_mo_set(mo_set, occupation_numbers=occupation)
1211 CALL cp_fm_to_fm(mo_set%mo_coeff, fwork)
1212 CALL cp_fm_column_scale(fwork, occupation)
1213 IF (wtype) THEN
1214 CALL cp_fm_column_scale(fwork, eigenvalues)
1215 END IF
1216 ! Re(c)*Re(c)
1217 CALL parallel_gemm("N", "T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, rpmat)
1218 mo_set => kp%mos(2, ispin)
1219 ! Im(c)*Re(c)
1220 CALL parallel_gemm("N", "T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, cpmat)
1221 ! Re(c)*Im(c)
1222 CALL parallel_gemm("N", "T", nao, nao, nmo, -1.0_dp, fwork, mo_set%mo_coeff, 1.0_dp, cpmat)
1223 CALL cp_fm_to_fm(mo_set%mo_coeff, fwork)
1224 CALL cp_fm_column_scale(fwork, occupation)
1225 IF (wtype) THEN
1226 CALL cp_fm_column_scale(fwork, eigenvalues)
1227 END IF
1228 ! Im(c)*Im(c)
1229 CALL parallel_gemm("N", "T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 1.0_dp, rpmat)
1230 END IF
1231 END DO
1232 END DO
1233
1234 CALL cp_fm_release(fwork)
1235
1236 CALL timestop(handle)
1237
1238 END SUBROUTINE kpoint_density_matrices
1239
1240! **************************************************************************************************
1241!> \brief generate real space density matrices in DBCSR format
1242!> \param kpoint Kpoint environment
1243!> \param denmat Real space (DBCSR) density matrices
1244!> \param wtype True = energy weighted density matrix
1245!> False = normal density matrix
1246!> \param tempmat DBCSR matrix to be used as template
1247!> \param sab_nl ...
1248!> \param fmwork FM work matrices (kpoint group)
1249!> \param for_aux_fit ...
1250!> \param pmat_ext ...
1251! **************************************************************************************************
1252 SUBROUTINE kpoint_density_transform(kpoint, denmat, wtype, tempmat, sab_nl, fmwork, for_aux_fit, pmat_ext)
1253
1254 TYPE(kpoint_type), POINTER :: kpoint
1255 TYPE(dbcsr_p_type), DIMENSION(:, :) :: denmat
1256 LOGICAL, INTENT(IN) :: wtype
1257 TYPE(dbcsr_type), POINTER :: tempmat
1258 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1259 POINTER :: sab_nl
1260 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fmwork
1261 LOGICAL, OPTIONAL :: for_aux_fit
1262 TYPE(cp_fm_type), DIMENSION(:, :, :), INTENT(IN), &
1263 OPTIONAL :: pmat_ext
1264
1265 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_density_transform'
1266
1267 INTEGER :: handle, ic, ik, ikk, indx, ir, ira, is, &
1268 ispin, jr, nc, nimg, nkp, nspin
1269 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
1270 LOGICAL :: aux_fit, do_ext, do_symmetric, my_kpgrp, &
1271 real_only
1272 REAL(kind=dp) :: wkpx
1273 REAL(kind=dp), DIMENSION(:), POINTER :: wkp
1274 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp
1275 TYPE(copy_info_type), ALLOCATABLE, DIMENSION(:) :: info
1276 TYPE(cp_fm_type) :: fmdummy
1277 TYPE(dbcsr_type), POINTER :: cpmat, rpmat, scpmat, srpmat
1278 TYPE(kind_rotmat_type), DIMENSION(:), POINTER :: kind_rot
1279 TYPE(kpoint_env_type), POINTER :: kp
1280 TYPE(kpoint_sym_type), POINTER :: kpsym
1281 TYPE(mp_para_env_type), POINTER :: para_env
1282
1283 CALL timeset(routinen, handle)
1284
1285 CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
1286
1287 IF (PRESENT(for_aux_fit)) THEN
1288 aux_fit = for_aux_fit
1289 ELSE
1290 aux_fit = .false.
1291 END IF
1292
1293 do_ext = .false.
1294 IF (PRESENT(pmat_ext)) do_ext = .true.
1295
1296 IF (aux_fit) THEN
1297 cpassert(ASSOCIATED(kpoint%kp_aux_env))
1298 END IF
1299
1300 ! work storage
1301 ALLOCATE (rpmat)
1302 CALL dbcsr_create(rpmat, template=tempmat, &
1303 matrix_type=merge(dbcsr_type_symmetric, dbcsr_type_no_symmetry, do_symmetric))
1304 CALL cp_dbcsr_alloc_block_from_nbl(rpmat, sab_nl)
1305 CALL dbcsr_set(rpmat, 0.0_dp)
1306 ALLOCATE (cpmat)
1307 CALL dbcsr_create(cpmat, template=tempmat, &
1308 matrix_type=merge(dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, do_symmetric))
1309 CALL cp_dbcsr_alloc_block_from_nbl(cpmat, sab_nl)
1310 CALL dbcsr_set(cpmat, 0.0_dp)
1311 IF (.NOT. kpoint%full_grid) THEN
1312 ALLOCATE (srpmat)
1313 CALL dbcsr_create(srpmat, template=rpmat)
1314 CALL cp_dbcsr_alloc_block_from_nbl(srpmat, sab_nl)
1315 CALL dbcsr_set(srpmat, 0.0_dp)
1316 ALLOCATE (scpmat)
1317 CALL dbcsr_create(scpmat, template=cpmat)
1318 CALL cp_dbcsr_alloc_block_from_nbl(scpmat, sab_nl)
1319 CALL dbcsr_set(scpmat, 0.0_dp)
1320 END IF
1321
1322 CALL get_kpoint_info(kpoint, nkp=nkp, xkp=xkp, wkp=wkp, &
1323 cell_to_index=cell_to_index)
1324 ! initialize real space density matrices
1325 IF (aux_fit) THEN
1326 kp => kpoint%kp_aux_env(1)%kpoint_env
1327 ELSE
1328 kp => kpoint%kp_env(1)%kpoint_env
1329 END IF
1330 nspin = SIZE(kp%mos, 2)
1331 nc = SIZE(kp%mos, 1)
1332 nimg = SIZE(denmat, 2)
1333 real_only = (nc == 1)
1334
1335 para_env => kpoint%blacs_env_all%para_env
1336 ALLOCATE (info(nspin*nkp*nc))
1337
1338 ! Start all the communication
1339 indx = 0
1340 DO ispin = 1, nspin
1341 DO ic = 1, nimg
1342 CALL dbcsr_set(denmat(ispin, ic)%matrix, 0.0_dp)
1343 END DO
1344 !
1345 DO ik = 1, nkp
1346 my_kpgrp = (ik >= kpoint%kp_range(1) .AND. ik <= kpoint%kp_range(2))
1347 IF (my_kpgrp) THEN
1348 ikk = ik - kpoint%kp_range(1) + 1
1349 IF (aux_fit) THEN
1350 kp => kpoint%kp_aux_env(ikk)%kpoint_env
1351 ELSE
1352 kp => kpoint%kp_env(ikk)%kpoint_env
1353 END IF
1354 ELSE
1355 NULLIFY (kp)
1356 END IF
1357 ! collect this density matrix on all processors
1358 cpassert(SIZE(fmwork) >= nc)
1359
1360 IF (my_kpgrp) THEN
1361 DO ic = 1, nc
1362 indx = indx + 1
1363 IF (do_ext) THEN
1364 CALL cp_fm_start_copy_general(pmat_ext(ikk, ic, ispin), fmwork(ic), para_env, info(indx))
1365 ELSE
1366 IF (wtype) THEN
1367 CALL cp_fm_start_copy_general(kp%wmat(ic, ispin), fmwork(ic), para_env, info(indx))
1368 ELSE
1369 CALL cp_fm_start_copy_general(kp%pmat(ic, ispin), fmwork(ic), para_env, info(indx))
1370 END IF
1371 END IF
1372 END DO
1373 ELSE
1374 DO ic = 1, nc
1375 indx = indx + 1
1376 CALL cp_fm_start_copy_general(fmdummy, fmwork(ic), para_env, info(indx))
1377 END DO
1378 END IF
1379 END DO
1380 END DO
1381
1382 ! Finish communication and transform the received matrices
1383 indx = 0
1384 DO ispin = 1, nspin
1385 DO ik = 1, nkp
1386 DO ic = 1, nc
1387 indx = indx + 1
1388 CALL cp_fm_finish_copy_general(fmwork(ic), info(indx))
1389 END DO
1390
1391 ! reduce to dbcsr storage
1392 IF (real_only) THEN
1393 CALL copy_fm_to_dbcsr(fmwork(1), rpmat, keep_sparsity=.true.)
1394 ELSE
1395 CALL copy_fm_to_dbcsr(fmwork(1), rpmat, keep_sparsity=.true.)
1396 CALL copy_fm_to_dbcsr(fmwork(2), cpmat, keep_sparsity=.true.)
1397 END IF
1398
1399 ! symmetrization
1400 kpsym => kpoint%kp_sym(ik)%kpoint_sym
1401 cpassert(ASSOCIATED(kpsym))
1402
1403 IF (kpsym%apply_symmetry) THEN
1404 wkpx = wkp(ik)/real(kpsym%nwght, kind=dp)
1405 DO is = 1, kpsym%nwght
1406 ir = abs(kpsym%rotp(is))
1407 ira = 0
1408 DO jr = 1, SIZE(kpoint%ibrot)
1409 IF (ir == kpoint%ibrot(jr)) ira = jr
1410 END DO
1411 cpassert(ira > 0)
1412 kind_rot => kpoint%kind_rotmat(ira, :)
1413 IF (real_only) THEN
1414 CALL symtrans(srpmat, rpmat, kind_rot, kpsym%rot(1:3, 1:3, is), &
1415 kpsym%f0(:, is), kpoint%atype, symmetric=.true.)
1416 ELSE
1417 CALL symtrans(srpmat, rpmat, kind_rot, kpsym%rot(1:3, 1:3, is), &
1418 kpsym%f0(:, is), kpoint%atype, symmetric=.true.)
1419 CALL symtrans(scpmat, cpmat, kind_rot, kpsym%rot(1:3, 1:3, is), &
1420 kpsym%f0(:, is), kpoint%atype, antisymmetric=.true.)
1421 END IF
1422 CALL transform_dmat(denmat, srpmat, scpmat, ispin, real_only, sab_nl, &
1423 cell_to_index, kpsym%xkp(1:3, is), wkpx)
1424 END DO
1425 ELSE
1426 ! transformation
1427 CALL transform_dmat(denmat, rpmat, cpmat, ispin, real_only, sab_nl, &
1428 cell_to_index, xkp(1:3, ik), wkp(ik))
1429 END IF
1430 END DO
1431 END DO
1432
1433 ! Clean up communication
1434 indx = 0
1435 DO ispin = 1, nspin
1436 DO ik = 1, nkp
1437 my_kpgrp = (ik >= kpoint%kp_range(1) .AND. ik <= kpoint%kp_range(2))
1438 IF (my_kpgrp) THEN
1439 ikk = ik - kpoint%kp_range(1) + 1
1440 IF (aux_fit) THEN
1441 kp => kpoint%kp_aux_env(ikk)%kpoint_env
1442 ELSE
1443 kp => kpoint%kp_env(ikk)%kpoint_env
1444 END IF
1445
1446 DO ic = 1, nc
1447 indx = indx + 1
1448 CALL cp_fm_cleanup_copy_general(info(indx))
1449 END DO
1450 ELSE
1451 ! calls with dummy arguments, so not included
1452 ! therefore just increment counter by trip count
1453 indx = indx + nc
1454 END IF
1455 END DO
1456 END DO
1457
1458 ! All done
1459 DEALLOCATE (info)
1460
1461 CALL dbcsr_deallocate_matrix(rpmat)
1462 CALL dbcsr_deallocate_matrix(cpmat)
1463 IF (.NOT. kpoint%full_grid) THEN
1464 CALL dbcsr_deallocate_matrix(srpmat)
1465 CALL dbcsr_deallocate_matrix(scpmat)
1466 END IF
1467
1468 CALL timestop(handle)
1469
1470 END SUBROUTINE kpoint_density_transform
1471
1472! **************************************************************************************************
1473!> \brief real space density matrices in DBCSR format
1474!> \param denmat Real space (DBCSR) density matrix
1475!> \param rpmat ...
1476!> \param cpmat ...
1477!> \param ispin ...
1478!> \param real_only ...
1479!> \param sab_nl ...
1480!> \param cell_to_index ...
1481!> \param xkp ...
1482!> \param wkp ...
1483! **************************************************************************************************
1484 SUBROUTINE transform_dmat(denmat, rpmat, cpmat, ispin, real_only, sab_nl, cell_to_index, xkp, wkp)
1485
1486 TYPE(dbcsr_p_type), DIMENSION(:, :) :: denmat
1487 TYPE(dbcsr_type), POINTER :: rpmat, cpmat
1488 INTEGER, INTENT(IN) :: ispin
1489 LOGICAL, INTENT(IN) :: real_only
1490 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1491 POINTER :: sab_nl
1492 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
1493 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: xkp
1494 REAL(kind=dp), INTENT(IN) :: wkp
1495
1496 CHARACTER(LEN=*), PARAMETER :: routinen = 'transform_dmat'
1497
1498 INTEGER :: handle, iatom, icell, icol, irow, jatom, &
1499 nimg
1500 INTEGER, DIMENSION(3) :: cell
1501 LOGICAL :: do_symmetric, found
1502 REAL(kind=dp) :: arg, coskl, fc, sinkl
1503 REAL(kind=dp), DIMENSION(:, :), POINTER :: cblock, dblock, rblock
1505 DIMENSION(:), POINTER :: nl_iterator
1506
1507 CALL timeset(routinen, handle)
1508
1509 nimg = SIZE(denmat, 2)
1510
1511 ! transformation
1512 CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
1513 CALL neighbor_list_iterator_create(nl_iterator, sab_nl)
1514 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
1515 CALL get_iterator_info(nl_iterator, iatom=iatom, jatom=jatom, cell=cell)
1516
1517 !We have a FT from KP to real-space: S(R) = sum_k S(k)*exp(-i*k*R), with S(k) a complex number
1518 !Therefore, we have: S(R) = sum_k Re(S(k))*cos(k*R) -i^2*Im(S(k))*sin(k*R)
1519 ! = sum_k Re(S(k))*cos(k*R) + Im(S(k))*sin(k*R)
1520 !fc = +- 1 is due to the usual non-symmetric real-space matrices stored as symmetric ones
1521
1522 irow = iatom
1523 icol = jatom
1524 fc = 1.0_dp
1525 IF (do_symmetric .AND. iatom > jatom) THEN
1526 irow = jatom
1527 icol = iatom
1528 fc = -1.0_dp
1529 END IF
1530
1531 icell = cell_to_index(cell(1), cell(2), cell(3))
1532 IF (icell < 1 .OR. icell > nimg) cycle
1533
1534 arg = real(cell(1), dp)*xkp(1) + real(cell(2), dp)*xkp(2) + real(cell(3), dp)*xkp(3)
1535 coskl = wkp*cos(twopi*arg)
1536 sinkl = wkp*fc*sin(twopi*arg)
1537
1538 CALL dbcsr_get_block_p(matrix=denmat(ispin, icell)%matrix, row=irow, col=icol, &
1539 block=dblock, found=found)
1540 IF (.NOT. found) cycle
1541
1542 IF (real_only) THEN
1543 CALL dbcsr_get_block_p(matrix=rpmat, row=irow, col=icol, block=rblock, found=found)
1544 IF (.NOT. found) cycle
1545 dblock = dblock + coskl*rblock
1546 ELSE
1547 CALL dbcsr_get_block_p(matrix=rpmat, row=irow, col=icol, block=rblock, found=found)
1548 IF (.NOT. found) cycle
1549 CALL dbcsr_get_block_p(matrix=cpmat, row=irow, col=icol, block=cblock, found=found)
1550 IF (.NOT. found) cycle
1551 dblock = dblock + coskl*rblock
1552 dblock = dblock + sinkl*cblock
1553 END IF
1554 END DO
1555 CALL neighbor_list_iterator_release(nl_iterator)
1556
1557 CALL timestop(handle)
1558
1559 END SUBROUTINE transform_dmat
1560
1561! **************************************************************************************************
1562!> \brief Symmetrization of density matrix - transform to new k-point
1563!> \param smat density matrix at new kpoint
1564!> \param pmat reference density matrix
1565!> \param kmat Kind type rotation matrix
1566!> \param rot Rotation matrix
1567!> \param f0 Permutation of atoms under transformation
1568!> \param atype Atom to kind pointer
1569!> \param symmetric Symmetric matrix
1570!> \param antisymmetric Anti-Symmetric matrix
1571! **************************************************************************************************
1572 SUBROUTINE symtrans(smat, pmat, kmat, rot, f0, atype, symmetric, antisymmetric)
1573 TYPE(dbcsr_type), POINTER :: smat, pmat
1574 TYPE(kind_rotmat_type), DIMENSION(:), POINTER :: kmat
1575 REAL(kind=dp), DIMENSION(3, 3), INTENT(IN) :: rot
1576 INTEGER, DIMENSION(:), INTENT(IN) :: f0, atype
1577 LOGICAL, INTENT(IN), OPTIONAL :: symmetric, antisymmetric
1578
1579 CHARACTER(LEN=*), PARAMETER :: routinen = 'symtrans'
1580
1581 INTEGER :: handle, iatom, icol, ikind, ip, irow, &
1582 jcol, jkind, jp, jrow, natom, numnodes
1583 LOGICAL :: asym, dorot, found, perm, sym, trans
1584 REAL(kind=dp) :: dr, fsign
1585 REAL(kind=dp), DIMENSION(:, :), POINTER :: kroti, krotj, pblock, sblock
1586 TYPE(dbcsr_distribution_type) :: dist
1587 TYPE(dbcsr_iterator_type) :: iter
1588
1589 CALL timeset(routinen, handle)
1590
1591 ! check symmetry options
1592 sym = .false.
1593 IF (PRESENT(symmetric)) sym = symmetric
1594 asym = .false.
1595 IF (PRESENT(antisymmetric)) asym = antisymmetric
1596
1597 cpassert(.NOT. (sym .AND. asym))
1598 cpassert((sym .OR. asym))
1599
1600 ! do we have permutation of atoms
1601 natom = SIZE(f0)
1602 perm = .false.
1603 DO iatom = 1, natom
1604 IF (f0(iatom) == iatom) cycle
1605 perm = .true.
1606 EXIT
1607 END DO
1608
1609 ! do we have a real rotation
1610 dorot = .false.
1611 IF (abs(sum(abs(rot)) - 3.0_dp) > 1.e-12_dp) dorot = .true.
1612 dr = abs(rot(1, 1) - 1.0_dp) + abs(rot(2, 2) - 1.0_dp) + abs(rot(3, 3) - 1.0_dp)
1613 IF (abs(dr) > 1.e-12_dp) dorot = .true.
1614
1615 fsign = 1.0_dp
1616 IF (asym) fsign = -1.0_dp
1617
1618 IF (dorot .OR. perm) THEN
1619 CALL cp_abort(__location__, "k-points need FULL_GRID currently. "// &
1620 "Reduced grids not yet working correctly")
1621 CALL dbcsr_set(smat, 0.0_dp)
1622 IF (perm) THEN
1623 CALL dbcsr_get_info(pmat, distribution=dist)
1624 CALL dbcsr_distribution_get(dist, numnodes=numnodes)
1625 IF (numnodes == 1) THEN
1626 ! the matrices are local to this process
1627 CALL dbcsr_iterator_start(iter, pmat)
1628 DO WHILE (dbcsr_iterator_blocks_left(iter))
1629 CALL dbcsr_iterator_next_block(iter, irow, icol, pblock)
1630 ip = f0(irow)
1631 jp = f0(icol)
1632 IF (ip <= jp) THEN
1633 jrow = ip
1634 jcol = jp
1635 trans = .false.
1636 ELSE
1637 jrow = jp
1638 jcol = ip
1639 trans = .true.
1640 END IF
1641 CALL dbcsr_get_block_p(matrix=smat, row=jrow, col=jcol, block=sblock, found=found)
1642 cpassert(found)
1643 ikind = atype(irow)
1644 jkind = atype(icol)
1645 kroti => kmat(ikind)%rmat
1646 krotj => kmat(jkind)%rmat
1647 ! rotation
1648 IF (trans) THEN
1649 sblock = fsign*matmul(transpose(krotj), matmul(transpose(pblock), kroti))
1650 ELSE
1651 sblock = fsign*matmul(transpose(kroti), matmul(pblock, krotj))
1652 END IF
1653 END DO
1654 CALL dbcsr_iterator_stop(iter)
1655 !
1656 ELSE
1657 ! distributed matrices, most general code needed
1658 CALL cp_abort(__location__, "k-points need FULL_GRID currently. "// &
1659 "Reduced grids not yet working correctly")
1660 END IF
1661 ELSE
1662 ! no atom permutations, this is always local
1663 CALL dbcsr_copy(smat, pmat)
1664 CALL dbcsr_iterator_start(iter, smat)
1665 DO WHILE (dbcsr_iterator_blocks_left(iter))
1666 CALL dbcsr_iterator_next_block(iter, irow, icol, sblock)
1667 ip = f0(irow)
1668 jp = f0(icol)
1669 IF (ip <= jp) THEN
1670 jrow = ip
1671 jcol = jp
1672 trans = .false.
1673 ELSE
1674 jrow = jp
1675 jcol = ip
1676 trans = .true.
1677 END IF
1678 ikind = atype(irow)
1679 jkind = atype(icol)
1680 kroti => kmat(ikind)%rmat
1681 krotj => kmat(jkind)%rmat
1682 ! rotation
1683 IF (trans) THEN
1684 sblock = fsign*matmul(transpose(krotj), matmul(transpose(sblock), kroti))
1685 ELSE
1686 sblock = fsign*matmul(transpose(kroti), matmul(sblock, krotj))
1687 END IF
1688 END DO
1689 CALL dbcsr_iterator_stop(iter)
1690 !
1691 END IF
1692 ELSE
1693 ! this is the identity operation, just copy the matrix
1694 CALL dbcsr_copy(smat, pmat)
1695 END IF
1696
1697 CALL timestop(handle)
1698
1699 END SUBROUTINE symtrans
1700
1701! **************************************************************************************************
1702!> \brief ...
1703!> \param mat ...
1704! **************************************************************************************************
1705 SUBROUTINE matprint(mat)
1706 TYPE(dbcsr_type), POINTER :: mat
1707
1708 INTEGER :: i, icol, iounit, irow
1709 REAL(kind=dp), DIMENSION(:, :), POINTER :: mblock
1710 TYPE(dbcsr_iterator_type) :: iter
1711
1713 CALL dbcsr_iterator_start(iter, mat)
1714 DO WHILE (dbcsr_iterator_blocks_left(iter))
1715 CALL dbcsr_iterator_next_block(iter, irow, icol, mblock)
1716 !
1717 IF (iounit > 0) THEN
1718 WRITE (iounit, '(A,2I4)') 'BLOCK ', irow, icol
1719 DO i = 1, SIZE(mblock, 1)
1720 WRITE (iounit, '(8F12.6)') mblock(i, :)
1721 END DO
1722 END IF
1723 !
1724 END DO
1725 CALL dbcsr_iterator_stop(iter)
1726
1727 END SUBROUTINE matprint
1728! **************************************************************************************************
1729
1730END MODULE kpoint_methods
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.
Definition cell_types.F:15
subroutine, public real_to_scaled(s, r, cell)
Transform real to scaled cell coordinates. s=h_inv*r.
Definition cell_types.F:486
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)
...
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
Definition cp_fm_types.F:15
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_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
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.
Definition cryssym.F:12
subroutine, public print_crys_symmetry(csym)
...
Definition cryssym.F:579
subroutine, public crys_sym_gen(csym, scoor, types, hmat, delta, iounit)
...
Definition cryssym.F:129
subroutine, public release_csym_type(csym)
Release the CSYM type.
Definition cryssym.F:84
subroutine, public kpoint_gen(csym, nk, symm, shift, full_grid)
...
Definition cryssym.F:224
subroutine, public print_kp_symmetry(csym)
...
Definition cryssym.F:612
deal with the Fermi distribution, compute it, fix mu, get derivs
Definition fermi_utils.F:13
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)
subroutine, public probe_occupancy_kp(occ, fermi, kts, energies, rcoeff, icoeff, maxocc, probe, n, wk)
subroutine to calculate occupation number and 'Fermi' level using the
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public smear_fermi_dirac
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
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, probe)
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.
Definition kpsym.F:28
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition list.F:24
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.
Definition qs_mo_types.F:22
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.
Definition util.F:14
pure integer function, dimension(2), public get_limit(m, n, me)
divide m entries into n parts, return size of part me
Definition util.F:333
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
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.
represent a full matrix
CSM type.
Definition cryssym.F:42
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