(git:419edc0)
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,&
22 USE cp_dbcsr_api, ONLY: &
26 dbcsr_p_type, dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, &
27 dbcsr_type_symmetric
35 USE cp_fm_types, ONLY: &
39 USE cryssym, ONLY: crys_sym_gen,&
40 csym_type,&
45 USE fermi_utils, ONLY: fermikp,&
48 USE kinds, ONLY: dp
49 USE kpoint_types, ONLY: get_kpoint_info,&
57 USE mathconstants, ONLY: twopi
59 USE message_passing, ONLY: mp_cart_type,&
67 USE qs_mo_types, ONLY: allocate_mo_set,&
80 USE util, ONLY: get_limit
81#include "./base/base_uses.f90"
82
83 IMPLICIT NONE
84
85 PRIVATE
86
87 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'kpoint_methods'
88
92 PUBLIC :: rskp_transform
93
94! **************************************************************************************************
95
96CONTAINS
97
98! **************************************************************************************************
99!> \brief Generate the kpoints and initialize the kpoint environment
100!> \param kpoint The kpoint environment
101!> \param particle_set Particle types and coordinates
102!> \param cell Computational cell information
103! **************************************************************************************************
104 SUBROUTINE kpoint_initialize(kpoint, particle_set, cell)
105
106 TYPE(kpoint_type), POINTER :: kpoint
107 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
108 TYPE(cell_type), POINTER :: cell
109
110 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_initialize'
111
112 INTEGER :: handle, i, ic, ik, iounit, ir, ira, is, &
113 j, natom, nkind, nr, ns
114 INTEGER, ALLOCATABLE, DIMENSION(:) :: atype
115 LOGICAL :: spez
116 REAL(kind=dp) :: wsum
117 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: coord, scoord
118 TYPE(csym_type) :: crys_sym
119 TYPE(kpoint_sym_type), POINTER :: kpsym
120
121 CALL timeset(routinen, handle)
122
123 cpassert(ASSOCIATED(kpoint))
124
125 SELECT CASE (kpoint%kp_scheme)
126 CASE ("NONE")
127 ! do nothing
128 CASE ("GAMMA")
129 kpoint%nkp = 1
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)
135 CALL kpoint_sym_create(kpoint%kp_sym(1)%kpoint_sym)
136 CASE ("MONKHORST-PACK", "MACDONALD")
137
138 IF (.NOT. kpoint%symmetry) THEN
139 ! we set up a random molecule to avoid any possible symmetry
140 natom = 10
141 ALLOCATE (coord(3, natom), scoord(3, natom), atype(natom))
142 DO i = 1, natom
143 atype(i) = i
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)
147 CALL real_to_scaled(scoord(1:3, i), coord(1:3, i), cell)
148 END DO
149 ELSE
150 natom = SIZE(particle_set)
151 ALLOCATE (scoord(3, natom), atype(natom))
152 DO i = 1, natom
153 CALL get_atomic_kind(atomic_kind=particle_set(i)%atomic_kind, kind_number=atype(i))
154 CALL real_to_scaled(scoord(1:3, i), particle_set(i)%r(1:3), cell)
155 END DO
156 END IF
157 IF (kpoint%verbose) THEN
159 ELSE
160 iounit = -1
161 END IF
162 ! kind type list
163 ALLOCATE (kpoint%atype(natom))
164 kpoint%atype = atype
165
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
175 END DO
176
177 ! print output
178 IF (kpoint%symmetry) CALL print_crys_symmetry(crys_sym)
179 IF (kpoint%symmetry) CALL print_kp_symmetry(crys_sym)
180
181 ! transfer symmetry information
182 ALLOCATE (kpoint%kp_sym(kpoint%nkp))
183 DO ik = 1, kpoint%nkp
184 NULLIFY (kpoint%kp_sym(ik)%kpoint_sym)
185 CALL kpoint_sym_create(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
188 ! set up the symmetrization information
189 kpsym%nwght = nint(crys_sym%wkpoint(ik))
190 ns = kpsym%nwght
191 !
192 IF (ns > 1) THEN
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))
199 nr = 0
200 DO is = 1, SIZE(crys_sym%kplink, 2)
201 IF (crys_sym%kplink(2, is) == ik) THEN
202 nr = nr + 1
203 ir = crys_sym%kpop(is)
204 ira = abs(ir)
205 kpsym%rotp(nr) = ir
206 IF (ir > 0) THEN
207 kpsym%rot(1:3, 1:3, nr) = crys_sym%rt(1:3, 1:3, ira)
208 ELSE
209 kpsym%rot(1:3, 1:3, nr) = -crys_sym%rt(1:3, 1:3, ira)
210 END IF
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)
215 EXIT
216 END IF
217 END DO
218 END IF
219 END DO
220 ! Reduce inversion?
221 kpsym%nwred = nr
222 END IF
223 END IF
224 END DO
225 IF (kpoint%symmetry) THEN
226 nkind = maxval(atype)
227 ns = crys_sym%nrtot
228 ALLOCATE (kpoint%kind_rotmat(ns, nkind))
229 DO i = 1, ns
230 DO j = 1, nkind
231 NULLIFY (kpoint%kind_rotmat(i, j)%rmat)
232 END DO
233 END DO
234 ALLOCATE (kpoint%ibrot(ns))
235 kpoint%ibrot(1:ns) = crys_sym%ibrot(1:ns)
236 END IF
237
238 CALL release_csym_type(crys_sym)
239 DEALLOCATE (scoord, atype)
240
241 CASE ("GENERAL")
242 ! default: no symmetry settings
243 ALLOCATE (kpoint%kp_sym(kpoint%nkp))
244 DO i = 1, kpoint%nkp
245 NULLIFY (kpoint%kp_sym(i)%kpoint_sym)
246 CALL kpoint_sym_create(kpoint%kp_sym(i)%kpoint_sym)
247 END DO
248 CASE DEFAULT
249 cpassert(.false.)
250 END SELECT
251
252 ! check for consistency of options
253 SELECT CASE (kpoint%kp_scheme)
254 CASE ("NONE")
255 ! don't use k-point code
256 CASE ("GAMMA")
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)
261 CASE ("GENERAL")
262 cpassert(.NOT. kpoint%symmetry)
263 cpassert(kpoint%nkp >= 1)
264 CASE ("MONKHORST-PACK", "MACDONALD")
265 cpassert(kpoint%nkp >= 1)
266 END SELECT
267 IF (kpoint%use_real_wfn) THEN
268 ! what about inversion symmetry?
269 ikloop: DO ik = 1, kpoint%nkp
270 DO i = 1, 3
271 spez = (kpoint%xkp(i, ik) == 0.0_dp .OR. kpoint%xkp(i, ik) == 0.5_dp)
272 IF (.NOT. spez) EXIT ikloop
273 END DO
274 END DO ikloop
275 IF (.NOT. spez) THEN
276 ! Warning: real wfn might be wrong for this system
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. ")
280 END IF
281 END IF
282
283 CALL timestop(handle)
284
285 END SUBROUTINE kpoint_initialize
286
287! **************************************************************************************************
288!> \brief Initialize the kpoint environment
289!> \param kpoint Kpoint environment
290!> \param para_env ...
291!> \param blacs_env ...
292!> \param with_aux_fit ...
293! **************************************************************************************************
294 SUBROUTINE kpoint_env_initialize(kpoint, para_env, blacs_env, with_aux_fit)
295
296 TYPE(kpoint_type), INTENT(INOUT) :: kpoint
297 TYPE(mp_para_env_type), INTENT(IN), TARGET :: para_env
298 TYPE(cp_blacs_env_type), INTENT(IN), TARGET :: blacs_env
299 LOGICAL, INTENT(IN), OPTIONAL :: with_aux_fit
300
301 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_env_initialize'
302
303 INTEGER :: handle, igr, ik, ikk, ngr, niogrp, nkp, &
304 nkp_grp, nkp_loc, npe, unit_nr
305 INTEGER, DIMENSION(2) :: dims, pos
306 LOGICAL :: aux_fit
307 TYPE(kpoint_env_p_type), DIMENSION(:), POINTER :: kp_aux_env, kp_env
308 TYPE(kpoint_env_type), POINTER :: kp
309 TYPE(mp_cart_type) :: comm_cart
310 TYPE(mp_para_env_type), POINTER :: para_env_inter_kp, para_env_kp
311
312 CALL timeset(routinen, handle)
313
314 IF (PRESENT(with_aux_fit)) THEN
315 aux_fit = with_aux_fit
316 ELSE
317 aux_fit = .false.
318 END IF
319
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()
324
325 cpassert(.NOT. ASSOCIATED(kpoint%kp_env))
326 IF (aux_fit) THEN
327 cpassert(.NOT. ASSOCIATED(kpoint%kp_aux_env))
328 END IF
329
330 NULLIFY (kp_env, kp_aux_env)
331 nkp = kpoint%nkp
332 npe = para_env%num_pe
333 IF (npe == 1) THEN
334 ! only one process available -> owns all kpoints
335 ALLOCATE (kp_env(nkp))
336 DO ik = 1, nkp
337 NULLIFY (kp_env(ik)%kpoint_env)
338 CALL kpoint_env_create(kp_env(ik)%kpoint_env)
339 kp => kp_env(ik)%kpoint_env
340 kp%nkpoint = ik
341 kp%wkp = kpoint%wkp(ik)
342 kp%xkp(1:3) = kpoint%xkp(1:3, ik)
343 kp%is_local = .true.
344 END DO
345 kpoint%kp_env => kp_env
346
347 IF (aux_fit) THEN
348 ALLOCATE (kp_aux_env(nkp))
349 DO ik = 1, nkp
350 NULLIFY (kp_aux_env(ik)%kpoint_env)
351 CALL kpoint_env_create(kp_aux_env(ik)%kpoint_env)
352 kp => kp_aux_env(ik)%kpoint_env
353 kp%nkpoint = ik
354 kp%wkp = kpoint%wkp(ik)
355 kp%xkp(1:3) = kpoint%xkp(1:3, ik)
356 kp%is_local = .true.
357 END DO
358
359 kpoint%kp_aux_env => kp_aux_env
360 END IF
361
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
367
368 ! parallel environments
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
375 ELSE
376 IF (kpoint%parallel_group_size == -1) THEN
377 ! maximum parallelization over kpoints
378 ! making sure that the group size divides the npe and the nkp_grp the nkp
379 ! in the worst case, there will be no parallelism over kpoints.
380 DO igr = npe, 1, -1
381 IF (mod(npe, igr) .NE. 0) cycle
382 nkp_grp = npe/igr
383 IF (mod(nkp, nkp_grp) .NE. 0) cycle
384 ngr = igr
385 END DO
386 ELSE IF (kpoint%parallel_group_size == 0) THEN
387 ! no parallelization over kpoints
388 ngr = npe
389 ELSE IF (kpoint%parallel_group_size > 0) THEN
390 ngr = min(kpoint%parallel_group_size, npe)
391 ELSE
392 cpassert(.false.)
393 END IF
394 nkp_grp = npe/ngr
395 ! processor dimensions
396 dims(1) = ngr
397 dims(2) = nkp_grp
398 cpassert(mod(nkp, nkp_grp) == 0)
399 nkp_loc = nkp/nkp_grp
400
401 IF ((dims(1)*dims(2) /= npe)) THEN
402 cpabort("Number of processors is not divisible by the kpoint group size.")
403 END IF
404
405 ! Create the subgroups, one for each k-point group and one interconnecting group
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()
413
414 niogrp = 0
415 IF (para_env%is_source()) niogrp = 1
416 CALL para_env_kp%sum(niogrp)
417 kpoint%iogrp = (niogrp == 1)
418
419 ! parallel groups
420 kpoint%para_env_kp => para_env_kp
421 kpoint%para_env_inter_kp => para_env_inter_kp
422
423 ! distribution of kpoints
424 ALLOCATE (kpoint%kp_dist(2, nkp_grp))
425 DO igr = 1, nkp_grp
426 kpoint%kp_dist(1:2, igr) = get_limit(nkp, nkp_grp, igr - 1)
427 END DO
428 ! local kpoints
429 kpoint%kp_range(1:2) = kpoint%kp_dist(1:2, para_env_inter_kp%mepos + 1)
430
431 ALLOCATE (kp_env(nkp_loc))
432 DO ik = 1, nkp_loc
433 NULLIFY (kp_env(ik)%kpoint_env)
434 ikk = kpoint%kp_range(1) + ik - 1
435 CALL kpoint_env_create(kp_env(ik)%kpoint_env)
436 kp => kp_env(ik)%kpoint_env
437 kp%nkpoint = ikk
438 kp%wkp = kpoint%wkp(ikk)
439 kp%xkp(1:3) = kpoint%xkp(1:3, ikk)
440 kp%is_local = (ngr == 1)
441 END DO
442 kpoint%kp_env => kp_env
443
444 IF (aux_fit) THEN
445 ALLOCATE (kp_aux_env(nkp_loc))
446 DO ik = 1, nkp_loc
447 NULLIFY (kp_aux_env(ik)%kpoint_env)
448 ikk = kpoint%kp_range(1) + ik - 1
449 CALL kpoint_env_create(kp_aux_env(ik)%kpoint_env)
450 kp => kp_aux_env(ik)%kpoint_env
451 kp%nkpoint = ikk
452 kp%wkp = kpoint%wkp(ikk)
453 kp%xkp(1:3) = kpoint%xkp(1:3, ikk)
454 kp%is_local = (ngr == 1)
455 END DO
456 kpoint%kp_aux_env => kp_aux_env
457 END IF
458
460
461 IF (unit_nr > 0 .AND. kpoint%verbose) THEN
462 WRITE (unit_nr, *)
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
466 END IF
467 kpoint%nkp_groups = nkp_grp
468
469 END IF
470
471 CALL timestop(handle)
472
473 END SUBROUTINE kpoint_env_initialize
474
475! **************************************************************************************************
476!> \brief Initialize a set of MOs and density matrix for each kpoint (kpoint group)
477!> \param kpoint Kpoint environment
478!> \param mos Reference MOs (global)
479!> \param added_mos ...
480!> \param for_aux_fit ...
481! **************************************************************************************************
482 SUBROUTINE kpoint_initialize_mos(kpoint, mos, added_mos, for_aux_fit)
483
484 TYPE(kpoint_type), POINTER :: kpoint
485 TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
486 INTEGER, INTENT(IN), OPTIONAL :: added_mos
487 LOGICAL, OPTIONAL :: for_aux_fit
488
489 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_initialize_mos'
490
491 INTEGER :: handle, ic, ik, is, nadd, nao, nc, &
492 nelectron, nkp_loc, nmo, nmorig(2), &
493 nspin
494 LOGICAL :: aux_fit
495 REAL(kind=dp) :: flexible_electron_count, maxocc, n_el_f
496 TYPE(cp_blacs_env_type), POINTER :: blacs_env
497 TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools
498 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
499 TYPE(cp_fm_type), POINTER :: fmlocal
500 TYPE(kpoint_env_type), POINTER :: kp
501 TYPE(qs_matrix_pools_type), POINTER :: mpools
502
503 CALL timeset(routinen, handle)
504
505 IF (PRESENT(for_aux_fit)) THEN
506 aux_fit = for_aux_fit
507 ELSE
508 aux_fit = .false.
509 END IF
510
511 cpassert(ASSOCIATED(kpoint))
512
513 IF (.true. .OR. ASSOCIATED(mos(1)%mo_coeff)) THEN
514 IF (aux_fit) THEN
515 cpassert(ASSOCIATED(kpoint%kp_aux_env))
516 END IF
517
518 IF (PRESENT(added_mos)) THEN
519 nadd = added_mos
520 ELSE
521 nadd = 0
522 END IF
523
524 IF (kpoint%use_real_wfn) THEN
525 nc = 1
526 ELSE
527 nc = 2
528 END IF
529 nspin = SIZE(mos, 1)
530 nkp_loc = kpoint%kp_range(2) - kpoint%kp_range(1) + 1
531 IF (nkp_loc > 0) THEN
532 IF (aux_fit) THEN
533 cpassert(SIZE(kpoint%kp_aux_env) == nkp_loc)
534 ELSE
535 cpassert(SIZE(kpoint%kp_env) == nkp_loc)
536 END IF
537 ! allocate the mo sets, correct number of kpoints (local), real/complex, spin
538 DO ik = 1, nkp_loc
539 IF (aux_fit) THEN
540 kp => kpoint%kp_aux_env(ik)%kpoint_env
541 ELSE
542 kp => kpoint%kp_env(ik)%kpoint_env
543 END IF
544 ALLOCATE (kp%mos(nc, nspin))
545 DO is = 1, 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)
549 DO ic = 1, nc
550 CALL allocate_mo_set(kp%mos(ic, is), nao, nmo, nelectron, n_el_f, maxocc, &
551 flexible_electron_count)
552 END DO
553 END DO
554 END DO
555
556 ! generate the blacs environment for the kpoint group
557 ! we generate a blacs env for each kpoint group in parallel
558 ! we assume here that the group para_env_inter_kp will connect
559 ! equivalent parts of fm matrices, i.e. no reshuffeling of processors
560 NULLIFY (blacs_env)
561 IF (ASSOCIATED(kpoint%blacs_env)) THEN
562 blacs_env => kpoint%blacs_env
563 ELSE
564 CALL cp_blacs_env_create(blacs_env=blacs_env, para_env=kpoint%para_env_kp)
565 kpoint%blacs_env => blacs_env
566 END IF
567
568 ! set possible new number of MOs
569 DO is = 1, nspin
570 CALL get_mo_set(mos(is), nmo=nmorig(is))
571 nmo = min(nao, nmorig(is) + nadd)
572 CALL set_mo_set(mos(is), nmo=nmo)
573 END DO
574 ! matrix pools for the kpoint group, information on MOs is transferred using
575 ! generic mos structure
576 NULLIFY (mpools)
577 CALL mpools_create(mpools=mpools)
578 CALL mpools_rebuild_fm_pools(mpools=mpools, mos=mos, &
579 blacs_env=blacs_env, para_env=kpoint%para_env_kp)
580
581 IF (aux_fit) THEN
582 kpoint%mpools_aux_fit => mpools
583 ELSE
584 kpoint%mpools => mpools
585 END IF
586
587 ! reset old number of MOs
588 DO is = 1, nspin
589 CALL set_mo_set(mos(is), nmo=nmorig(is))
590 END DO
591
592 ! allocate density matrices
593 CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
594 ALLOCATE (fmlocal)
595 CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmlocal)
596 CALL cp_fm_get_info(fmlocal, matrix_struct=matrix_struct)
597 DO ik = 1, nkp_loc
598 IF (aux_fit) THEN
599 kp => kpoint%kp_aux_env(ik)%kpoint_env
600 ELSE
601 kp => kpoint%kp_env(ik)%kpoint_env
602 END IF
603 ! density matrix
604 CALL cp_fm_release(kp%pmat)
605 ALLOCATE (kp%pmat(nc, nspin))
606 DO is = 1, nspin
607 DO ic = 1, nc
608 CALL cp_fm_create(kp%pmat(ic, is), matrix_struct)
609 END DO
610 END DO
611 ! energy weighted density matrix
612 CALL cp_fm_release(kp%wmat)
613 ALLOCATE (kp%wmat(nc, nspin))
614 DO is = 1, nspin
615 DO ic = 1, nc
616 CALL cp_fm_create(kp%wmat(ic, is), matrix_struct)
617 END DO
618 END DO
619 END DO
620 CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmlocal)
621 DEALLOCATE (fmlocal)
622
623 END IF
624
625 END IF
626
627 CALL timestop(handle)
628
629 END SUBROUTINE kpoint_initialize_mos
630
631! **************************************************************************************************
632!> \brief ...
633!> \param kpoint ...
634! **************************************************************************************************
635 SUBROUTINE kpoint_initialize_mo_set(kpoint)
636 TYPE(kpoint_type), POINTER :: kpoint
637
638 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_initialize_mo_set'
639
640 INTEGER :: handle, ic, ik, ikk, ispin
641 TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_mo_fm_pools
642 TYPE(cp_fm_type), POINTER :: mo_coeff
643 TYPE(mo_set_type), DIMENSION(:, :), POINTER :: moskp
644
645 CALL timeset(routinen, handle)
646
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
656 CALL init_mo_set(moskp(ic, ispin), &
657 fm_pool=ao_mo_fm_pools(ispin)%pool, name="kpoints")
658 END IF
659 END DO
660 END DO
661 END DO
662
663 CALL timestop(handle)
664
665 END SUBROUTINE kpoint_initialize_mo_set
666
667! **************************************************************************************************
668!> \brief Generates the mapping of cell indices and linear RS index
669!> CELL (0,0,0) is always mapped to index 1
670!> \param kpoint Kpoint environment
671!> \param sab_nl Defining neighbour list
672!> \param para_env Parallel environment
673!> \param dft_control ...
674! **************************************************************************************************
675 SUBROUTINE kpoint_init_cell_index(kpoint, sab_nl, para_env, dft_control)
676
677 TYPE(kpoint_type), POINTER :: kpoint
678 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
679 POINTER :: sab_nl
680 TYPE(mp_para_env_type), POINTER :: para_env
681 TYPE(dft_control_type), POINTER :: dft_control
682
683 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_init_cell_index'
684
685 INTEGER :: handle, i1, i2, i3, ic, icount, it, &
686 ncount
687 INTEGER, DIMENSION(3) :: cell, itm
688 INTEGER, DIMENSION(:, :), POINTER :: index_to_cell, list
689 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index, cti
690 LOGICAL :: new
692 DIMENSION(:), POINTER :: nl_iterator
693
694 NULLIFY (cell_to_index, index_to_cell)
695
696 CALL timeset(routinen, handle)
697
698 cpassert(ASSOCIATED(kpoint))
699
700 ALLOCATE (list(3, 125))
701 list = 0
702 icount = 1
703
704 CALL neighbor_list_iterator_create(nl_iterator, sab_nl)
705 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
706 CALL get_iterator_info(nl_iterator, cell=cell)
707
708 new = .true.
709 DO ic = 1, icount
710 IF (cell(1) == list(1, ic) .AND. cell(2) == list(2, ic) .AND. &
711 cell(3) == list(3, ic)) THEN
712 new = .false.
713 EXIT
714 END IF
715 END DO
716 IF (new) THEN
717 icount = icount + 1
718 IF (icount > SIZE(list, 2)) THEN
719 CALL reallocate(list, 1, 3, 1, 2*SIZE(list, 2))
720 END IF
721 list(1:3, icount) = cell(1:3)
722 END IF
723
724 END DO
725 CALL neighbor_list_iterator_release(nl_iterator)
726
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)
734 END IF
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
737 cti => cell_to_index
738 cti(:, :, :) = 0
739 DO ic = 1, icount
740 i1 = list(1, ic)
741 i2 = list(2, ic)
742 i3 = list(3, ic)
743 cti(i1, i2, i3) = ic
744 END DO
745 CALL para_env%sum(cti)
746 ncount = 0
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
752 ELSE
753 ncount = ncount + 1
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)
756 END IF
757 END DO
758 END DO
759 END DO
760
761 IF (ASSOCIATED(kpoint%index_to_cell)) THEN
762 DEALLOCATE (kpoint%index_to_cell)
763 END IF
764 ALLOCATE (kpoint%index_to_cell(3, ncount))
765 index_to_cell => kpoint%index_to_cell
766 DO ic = 1, ncount
767 cell = minloc(cti)
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
775 END DO
776 cti(:, :, :) = 0
777 DO ic = 1, ncount
778 i1 = index_to_cell(1, ic)
779 i2 = index_to_cell(2, ic)
780 i3 = index_to_cell(3, ic)
781 cti(i1, i2, i3) = ic
782 END DO
783
784 ! keep pointer to this neighborlist
785 kpoint%sab_nl => sab_nl
786
787 ! set number of images
788 dft_control%nimages = SIZE(index_to_cell, 2)
789
790 DEALLOCATE (list)
791
792 CALL timestop(handle)
793 END SUBROUTINE kpoint_init_cell_index
794
795! **************************************************************************************************
796!> \brief Transformation of real space matrices to a kpoint
797!> \param rmatrix Real part of kpoint matrix
798!> \param cmatrix Complex part of kpoint matrix (optional)
799!> \param rsmat Real space matrices
800!> \param ispin Spin index
801!> \param xkp Kpoint coordinates
802!> \param cell_to_index mapping of cell indices to RS index
803!> \param sab_nl Defining neighbor list
804!> \param is_complex Matrix to be transformed is imaginary
805!> \param rs_sign Matrix to be transformed is csaled by rs_sign
806! **************************************************************************************************
807 SUBROUTINE rskp_transform(rmatrix, cmatrix, rsmat, ispin, &
808 xkp, cell_to_index, sab_nl, is_complex, rs_sign)
809
810 TYPE(dbcsr_type) :: rmatrix
811 TYPE(dbcsr_type), OPTIONAL :: cmatrix
812 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rsmat
813 INTEGER, INTENT(IN) :: ispin
814 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: xkp
815 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
816 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
817 POINTER :: sab_nl
818 LOGICAL, INTENT(IN), OPTIONAL :: is_complex
819 REAL(kind=dp), INTENT(IN), OPTIONAL :: rs_sign
820
821 CHARACTER(LEN=*), PARAMETER :: routinen = 'rskp_transform'
822
823 INTEGER :: handle, iatom, ic, icol, irow, jatom, &
824 nimg
825 INTEGER, DIMENSION(3) :: cell
826 LOGICAL :: do_symmetric, found, my_complex, &
827 wfn_real_only
828 REAL(kind=dp) :: arg, coskl, fsign, fsym, sinkl
829 REAL(kind=dp), DIMENSION(:, :), POINTER :: cblock, rblock, rsblock
831 DIMENSION(:), POINTER :: nl_iterator
832
833 CALL timeset(routinen, handle)
834
835 my_complex = .false.
836 IF (PRESENT(is_complex)) my_complex = is_complex
837
838 fsign = 1.0_dp
839 IF (PRESENT(rs_sign)) fsign = rs_sign
840
841 wfn_real_only = .true.
842 IF (PRESENT(cmatrix)) wfn_real_only = .false.
843
844 nimg = SIZE(rsmat, 2)
845
846 CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
847
848 CALL neighbor_list_iterator_create(nl_iterator, sab_nl)
849 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
850 CALL get_iterator_info(nl_iterator, iatom=iatom, jatom=jatom, cell=cell)
851
852 ! fsym = +- 1 is due to real space matrices being non-symmetric (although in a symmtric type)
853 ! with the link S_mu^0,nu^b = S_nu^0,mu^-b, and the KP matrices beeing Hermitian
854 fsym = 1.0_dp
855 irow = iatom
856 icol = jatom
857 IF (do_symmetric .AND. (iatom > jatom)) THEN
858 irow = jatom
859 icol = iatom
860 fsym = -1.0_dp
861 END IF
862
863 ic = cell_to_index(cell(1), cell(2), cell(3))
864 IF (ic < 1 .OR. ic > nimg) cycle
865
866 arg = real(cell(1), dp)*xkp(1) + real(cell(2), dp)*xkp(2) + real(cell(3), dp)*xkp(3)
867 IF (my_complex) THEN
868 coskl = fsign*fsym*cos(twopi*arg)
869 sinkl = fsign*sin(twopi*arg)
870 ELSE
871 coskl = fsign*cos(twopi*arg)
872 sinkl = fsign*fsym*sin(twopi*arg)
873 END IF
874
875 CALL dbcsr_get_block_p(matrix=rsmat(ispin, ic)%matrix, row=irow, col=icol, &
876 block=rsblock, found=found)
877 IF (.NOT. found) cycle
878
879 IF (wfn_real_only) THEN
880 CALL dbcsr_get_block_p(matrix=rmatrix, row=irow, col=icol, &
881 block=rblock, found=found)
882 IF (.NOT. found) cycle
883 rblock = rblock + coskl*rsblock
884 ELSE
885 CALL dbcsr_get_block_p(matrix=rmatrix, row=irow, col=icol, &
886 block=rblock, found=found)
887 IF (.NOT. found) cycle
888 CALL dbcsr_get_block_p(matrix=cmatrix, row=irow, col=icol, &
889 block=cblock, found=found)
890 IF (.NOT. found) cycle
891 rblock = rblock + coskl*rsblock
892 cblock = cblock + sinkl*rsblock
893 END IF
894
895 END DO
896 CALL neighbor_list_iterator_release(nl_iterator)
897
898 CALL timestop(handle)
899
900 END SUBROUTINE rskp_transform
901
902! **************************************************************************************************
903!> \brief Given the eigenvalues of all kpoints, calculates the occupation numbers
904!> \param kpoint Kpoint environment
905!> \param smear Smearing information
906! **************************************************************************************************
907 SUBROUTINE kpoint_set_mo_occupation(kpoint, smear)
908
909 TYPE(kpoint_type), POINTER :: kpoint
910 TYPE(smear_type), POINTER :: smear
911
912 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_set_mo_occupation'
913
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
920 TYPE(kpoint_env_type), POINTER :: kp
921 TYPE(mo_set_type), POINTER :: mo_set
922 TYPE(mp_para_env_type), POINTER :: para_env_inter_kp
923
924 CALL timeset(routinen, handle)
925
926 ! first collect all the eigenvalues
927 CALL get_kpoint_info(kpoint, nkp=nkp)
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)
932 ne_a = nelectron
933 IF (nspin == 2) THEN
934 CALL get_mo_set(kp%mos(1, 2), nmo=nb, nelectron=ne_b)
935 cpassert(nmo == nb)
936 END IF
937 ALLOCATE (weig(nmo, nkp, nspin), wocc(nmo, nkp, nspin))
938 weig = 0.0_dp
939 wocc = 0.0_dp
940 CALL get_kpoint_info(kpoint, kp_range=kp_range)
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
945 DO ispin = 1, nspin
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)
949 END DO
950 END DO
951 CALL get_kpoint_info(kpoint, para_env_inter_kp=para_env_inter_kp)
952 CALL para_env_inter_kp%sum(weig)
953
954 CALL get_kpoint_info(kpoint, wkp=wkp)
955 IF (smear%do_smear) THEN
956 ! finite electronic temperature
957 SELECT CASE (smear%method)
958 CASE (smear_fermi_dirac)
959 IF (nspin == 1) THEN
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)
970 ELSE
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)
974 kts = kts/2._dp
975 mus(1:2) = mu
976 END IF
977 CASE DEFAULT
978 cpabort("kpoints: Selected smearing not (yet) supported")
979 END SELECT
980 ELSE
981 ! fixed occupations (2/1)
982 IF (nspin == 1) THEN
983 nel = real(nelectron, kind=dp)
984 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, 0.0_dp, 2.0_dp)
985 ELSE
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)
990 END IF
991 END IF
992 DO ikpgr = 1, kplocal
993 ik = kp_range(1) + ikpgr - 1
994 kp => kpoint%kp_env(ikpgr)%kpoint_env
995 DO ispin = 1, nspin
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)
1000 mo_set%kTS = kts
1001 mo_set%mu = mus(ispin)
1002 END DO
1003 END DO
1004
1005 DEALLOCATE (weig, wocc)
1006
1007 CALL timestop(handle)
1008
1009 END SUBROUTINE kpoint_set_mo_occupation
1010
1011! **************************************************************************************************
1012!> \brief Calculate kpoint density matrices (rho(k), owned by kpoint groups)
1013!> \param kpoint kpoint environment
1014!> \param energy_weighted calculate energy weighted density matrix
1015!> \param for_aux_fit ...
1016! **************************************************************************************************
1017 SUBROUTINE kpoint_density_matrices(kpoint, energy_weighted, for_aux_fit)
1018
1019 TYPE(kpoint_type), POINTER :: kpoint
1020 LOGICAL, OPTIONAL :: energy_weighted, for_aux_fit
1021
1022 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_density_matrices'
1023
1024 INTEGER :: handle, ikpgr, ispin, kplocal, nao, nmo, &
1025 nspin
1026 INTEGER, DIMENSION(2) :: kp_range
1027 LOGICAL :: aux_fit, wtype
1028 REAL(kind=dp), DIMENSION(:), POINTER :: eigenvalues, occupation
1029 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
1030 TYPE(cp_fm_type) :: fwork
1031 TYPE(cp_fm_type), POINTER :: cpmat, pmat, rpmat
1032 TYPE(kpoint_env_type), POINTER :: kp
1033 TYPE(mo_set_type), POINTER :: mo_set
1034
1035 CALL timeset(routinen, handle)
1036
1037 IF (PRESENT(energy_weighted)) THEN
1038 wtype = energy_weighted
1039 ELSE
1040 ! default is normal density matrix
1041 wtype = .false.
1042 END IF
1043
1044 IF (PRESENT(for_aux_fit)) THEN
1045 aux_fit = for_aux_fit
1046 ELSE
1047 aux_fit = .false.
1048 END IF
1049
1050 IF (aux_fit) THEN
1051 cpassert(ASSOCIATED(kpoint%kp_aux_env))
1052 END IF
1053
1054 ! work matrix
1055 IF (aux_fit) THEN
1056 mo_set => kpoint%kp_aux_env(1)%kpoint_env%mos(1, 1)
1057 ELSE
1058 mo_set => kpoint%kp_env(1)%kpoint_env%mos(1, 1)
1059 END IF
1060 CALL get_mo_set(mo_set, nao=nao, nmo=nmo)
1061 CALL cp_fm_get_info(mo_set%mo_coeff, matrix_struct=matrix_struct)
1062 CALL cp_fm_create(fwork, matrix_struct)
1063
1064 CALL get_kpoint_info(kpoint, kp_range=kp_range)
1065 kplocal = kp_range(2) - kp_range(1) + 1
1066 DO ikpgr = 1, kplocal
1067 IF (aux_fit) THEN
1068 kp => kpoint%kp_aux_env(ikpgr)%kpoint_env
1069 ELSE
1070 kp => kpoint%kp_env(ikpgr)%kpoint_env
1071 END IF
1072 nspin = SIZE(kp%mos, 2)
1073 DO ispin = 1, nspin
1074 mo_set => kp%mos(1, ispin)
1075 IF (wtype) THEN
1076 CALL get_mo_set(mo_set, eigenvalues=eigenvalues)
1077 END IF
1078 IF (kpoint%use_real_wfn) THEN
1079 IF (wtype) THEN
1080 pmat => kp%wmat(1, ispin)
1081 ELSE
1082 pmat => kp%pmat(1, ispin)
1083 END IF
1084 CALL get_mo_set(mo_set, occupation_numbers=occupation)
1085 CALL cp_fm_to_fm(mo_set%mo_coeff, fwork)
1086 CALL cp_fm_column_scale(fwork, occupation)
1087 IF (wtype) THEN
1088 CALL cp_fm_column_scale(fwork, eigenvalues)
1089 END IF
1090 CALL parallel_gemm("N", "T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, pmat)
1091 ELSE
1092 IF (wtype) THEN
1093 rpmat => kp%wmat(1, ispin)
1094 cpmat => kp%wmat(2, ispin)
1095 ELSE
1096 rpmat => kp%pmat(1, ispin)
1097 cpmat => kp%pmat(2, ispin)
1098 END IF
1099 CALL get_mo_set(mo_set, occupation_numbers=occupation)
1100 CALL cp_fm_to_fm(mo_set%mo_coeff, fwork)
1101 CALL cp_fm_column_scale(fwork, occupation)
1102 IF (wtype) THEN
1103 CALL cp_fm_column_scale(fwork, eigenvalues)
1104 END IF
1105 ! Re(c)*Re(c)
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)
1108 ! Im(c)*Re(c)
1109 CALL parallel_gemm("N", "T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, cpmat)
1110 ! Re(c)*Im(c)
1111 CALL parallel_gemm("N", "T", nao, nao, nmo, -1.0_dp, fwork, mo_set%mo_coeff, 1.0_dp, cpmat)
1112 CALL cp_fm_to_fm(mo_set%mo_coeff, fwork)
1113 CALL cp_fm_column_scale(fwork, occupation)
1114 IF (wtype) THEN
1115 CALL cp_fm_column_scale(fwork, eigenvalues)
1116 END IF
1117 ! Im(c)*Im(c)
1118 CALL parallel_gemm("N", "T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 1.0_dp, rpmat)
1119 END IF
1120 END DO
1121 END DO
1122
1123 CALL cp_fm_release(fwork)
1124
1125 CALL timestop(handle)
1126
1127 END SUBROUTINE kpoint_density_matrices
1128
1129! **************************************************************************************************
1130!> \brief generate real space density matrices in DBCSR format
1131!> \param kpoint Kpoint environment
1132!> \param denmat Real space (DBCSR) density matrices
1133!> \param wtype True = energy weighted density matrix
1134!> False = normal density matrix
1135!> \param tempmat DBCSR matrix to be used as template
1136!> \param sab_nl ...
1137!> \param fmwork FM work matrices (kpoint group)
1138!> \param for_aux_fit ...
1139!> \param pmat_ext ...
1140! **************************************************************************************************
1141 SUBROUTINE kpoint_density_transform(kpoint, denmat, wtype, tempmat, sab_nl, fmwork, for_aux_fit, pmat_ext)
1142
1143 TYPE(kpoint_type), POINTER :: kpoint
1144 TYPE(dbcsr_p_type), DIMENSION(:, :) :: denmat
1145 LOGICAL, INTENT(IN) :: wtype
1146 TYPE(dbcsr_type), POINTER :: tempmat
1147 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1148 POINTER :: sab_nl
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
1153
1154 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_density_transform'
1155
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, &
1160 real_only
1161 REAL(kind=dp) :: wkpx
1162 REAL(kind=dp), DIMENSION(:), POINTER :: wkp
1163 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp
1164 TYPE(copy_info_type), ALLOCATABLE, DIMENSION(:) :: info
1165 TYPE(cp_fm_type) :: fmdummy
1166 TYPE(dbcsr_type), POINTER :: cpmat, rpmat, scpmat, srpmat
1167 TYPE(kind_rotmat_type), DIMENSION(:), POINTER :: kind_rot
1168 TYPE(kpoint_env_type), POINTER :: kp
1169 TYPE(kpoint_sym_type), POINTER :: kpsym
1170 TYPE(mp_para_env_type), POINTER :: para_env
1171
1172 CALL timeset(routinen, handle)
1173
1174 CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
1175
1176 IF (PRESENT(for_aux_fit)) THEN
1177 aux_fit = for_aux_fit
1178 ELSE
1179 aux_fit = .false.
1180 END IF
1181
1182 do_ext = .false.
1183 IF (PRESENT(pmat_ext)) do_ext = .true.
1184
1185 IF (aux_fit) THEN
1186 cpassert(ASSOCIATED(kpoint%kp_aux_env))
1187 END IF
1188
1189 ! work storage
1190 ALLOCATE (rpmat)
1191 CALL dbcsr_create(rpmat, template=tempmat, &
1192 matrix_type=merge(dbcsr_type_symmetric, dbcsr_type_no_symmetry, do_symmetric))
1193 CALL cp_dbcsr_alloc_block_from_nbl(rpmat, sab_nl)
1194 CALL dbcsr_set(rpmat, 0.0_dp)
1195 ALLOCATE (cpmat)
1196 CALL dbcsr_create(cpmat, template=tempmat, &
1197 matrix_type=merge(dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, do_symmetric))
1198 CALL cp_dbcsr_alloc_block_from_nbl(cpmat, sab_nl)
1199 CALL dbcsr_set(cpmat, 0.0_dp)
1200 IF (.NOT. kpoint%full_grid) THEN
1201 ALLOCATE (srpmat)
1202 CALL dbcsr_create(srpmat, template=rpmat)
1203 CALL cp_dbcsr_alloc_block_from_nbl(srpmat, sab_nl)
1204 CALL dbcsr_set(srpmat, 0.0_dp)
1205 ALLOCATE (scpmat)
1206 CALL dbcsr_create(scpmat, template=cpmat)
1207 CALL cp_dbcsr_alloc_block_from_nbl(scpmat, sab_nl)
1208 CALL dbcsr_set(scpmat, 0.0_dp)
1209 END IF
1210
1211 CALL get_kpoint_info(kpoint, nkp=nkp, xkp=xkp, wkp=wkp, &
1212 cell_to_index=cell_to_index)
1213 ! initialize real space density matrices
1214 IF (aux_fit) THEN
1215 kp => kpoint%kp_aux_env(1)%kpoint_env
1216 ELSE
1217 kp => kpoint%kp_env(1)%kpoint_env
1218 END IF
1219 nspin = SIZE(kp%mos, 2)
1220 nc = SIZE(kp%mos, 1)
1221 nimg = SIZE(denmat, 2)
1222 real_only = (nc == 1)
1223
1224 para_env => kpoint%blacs_env_all%para_env
1225 ALLOCATE (info(nspin*nkp*nc))
1226
1227 ! Start all the communication
1228 indx = 0
1229 DO ispin = 1, nspin
1230 DO ic = 1, nimg
1231 CALL dbcsr_set(denmat(ispin, ic)%matrix, 0.0_dp)
1232 END DO
1233 !
1234 DO ik = 1, nkp
1235 my_kpgrp = (ik >= kpoint%kp_range(1) .AND. ik <= kpoint%kp_range(2))
1236 IF (my_kpgrp) THEN
1237 ikk = ik - kpoint%kp_range(1) + 1
1238 IF (aux_fit) THEN
1239 kp => kpoint%kp_aux_env(ikk)%kpoint_env
1240 ELSE
1241 kp => kpoint%kp_env(ikk)%kpoint_env
1242 END IF
1243 ELSE
1244 NULLIFY (kp)
1245 END IF
1246 ! collect this density matrix on all processors
1247 cpassert(SIZE(fmwork) >= nc)
1248
1249 IF (my_kpgrp) THEN
1250 DO ic = 1, nc
1251 indx = indx + 1
1252 IF (do_ext) THEN
1253 CALL cp_fm_start_copy_general(pmat_ext(ikk, ic, ispin), fmwork(ic), para_env, info(indx))
1254 ELSE
1255 IF (wtype) THEN
1256 CALL cp_fm_start_copy_general(kp%wmat(ic, ispin), fmwork(ic), para_env, info(indx))
1257 ELSE
1258 CALL cp_fm_start_copy_general(kp%pmat(ic, ispin), fmwork(ic), para_env, info(indx))
1259 END IF
1260 END IF
1261 END DO
1262 ELSE
1263 DO ic = 1, nc
1264 indx = indx + 1
1265 CALL cp_fm_start_copy_general(fmdummy, fmwork(ic), para_env, info(indx))
1266 END DO
1267 END IF
1268 END DO
1269 END DO
1270
1271 ! Finish communication and transform the received matrices
1272 indx = 0
1273 DO ispin = 1, nspin
1274 DO ik = 1, nkp
1275 DO ic = 1, nc
1276 indx = indx + 1
1277 CALL cp_fm_finish_copy_general(fmwork(ic), info(indx))
1278 END DO
1279
1280 ! reduce to dbcsr storage
1281 IF (real_only) THEN
1282 CALL copy_fm_to_dbcsr(fmwork(1), rpmat, keep_sparsity=.true.)
1283 ELSE
1284 CALL copy_fm_to_dbcsr(fmwork(1), rpmat, keep_sparsity=.true.)
1285 CALL copy_fm_to_dbcsr(fmwork(2), cpmat, keep_sparsity=.true.)
1286 END IF
1287
1288 ! symmetrization
1289 kpsym => kpoint%kp_sym(ik)%kpoint_sym
1290 cpassert(ASSOCIATED(kpsym))
1291
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))
1296 ira = 0
1297 DO jr = 1, SIZE(kpoint%ibrot)
1298 IF (ir == kpoint%ibrot(jr)) ira = jr
1299 END DO
1300 cpassert(ira > 0)
1301 kind_rot => kpoint%kind_rotmat(ira, :)
1302 IF (real_only) THEN
1303 CALL symtrans(srpmat, rpmat, kind_rot, kpsym%rot(1:3, 1:3, is), &
1304 kpsym%f0(:, is), kpoint%atype, symmetric=.true.)
1305 ELSE
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.)
1310 END IF
1311 CALL transform_dmat(denmat, srpmat, scpmat, ispin, real_only, sab_nl, &
1312 cell_to_index, kpsym%xkp(1:3, is), wkpx)
1313 END DO
1314 ELSE
1315 ! transformation
1316 CALL transform_dmat(denmat, rpmat, cpmat, ispin, real_only, sab_nl, &
1317 cell_to_index, xkp(1:3, ik), wkp(ik))
1318 END IF
1319 END DO
1320 END DO
1321
1322 ! Clean up communication
1323 indx = 0
1324 DO ispin = 1, nspin
1325 DO ik = 1, nkp
1326 my_kpgrp = (ik >= kpoint%kp_range(1) .AND. ik <= kpoint%kp_range(2))
1327 IF (my_kpgrp) THEN
1328 ikk = ik - kpoint%kp_range(1) + 1
1329 IF (aux_fit) THEN
1330 kp => kpoint%kp_aux_env(ikk)%kpoint_env
1331 ELSE
1332 kp => kpoint%kp_env(ikk)%kpoint_env
1333 END IF
1334
1335 DO ic = 1, nc
1336 indx = indx + 1
1337 CALL cp_fm_cleanup_copy_general(info(indx))
1338 END DO
1339 ELSE
1340 ! calls with dummy arguments, so not included
1341 ! therefore just increment counter by trip count
1342 indx = indx + nc
1343 END IF
1344 END DO
1345 END DO
1346
1347 ! All done
1348 DEALLOCATE (info)
1349
1350 CALL dbcsr_deallocate_matrix(rpmat)
1351 CALL dbcsr_deallocate_matrix(cpmat)
1352 IF (.NOT. kpoint%full_grid) THEN
1353 CALL dbcsr_deallocate_matrix(srpmat)
1354 CALL dbcsr_deallocate_matrix(scpmat)
1355 END IF
1356
1357 CALL timestop(handle)
1358
1359 END SUBROUTINE kpoint_density_transform
1360
1361! **************************************************************************************************
1362!> \brief real space density matrices in DBCSR format
1363!> \param denmat Real space (DBCSR) density matrix
1364!> \param rpmat ...
1365!> \param cpmat ...
1366!> \param ispin ...
1367!> \param real_only ...
1368!> \param sab_nl ...
1369!> \param cell_to_index ...
1370!> \param xkp ...
1371!> \param wkp ...
1372! **************************************************************************************************
1373 SUBROUTINE transform_dmat(denmat, rpmat, cpmat, ispin, real_only, sab_nl, cell_to_index, xkp, wkp)
1374
1375 TYPE(dbcsr_p_type), DIMENSION(:, :) :: denmat
1376 TYPE(dbcsr_type), POINTER :: rpmat, cpmat
1377 INTEGER, INTENT(IN) :: ispin
1378 LOGICAL, INTENT(IN) :: real_only
1379 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1380 POINTER :: sab_nl
1381 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
1382 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: xkp
1383 REAL(kind=dp), INTENT(IN) :: wkp
1384
1385 CHARACTER(LEN=*), PARAMETER :: routinen = 'transform_dmat'
1386
1387 INTEGER :: handle, iatom, icell, icol, irow, jatom, &
1388 nimg
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
1395
1396 CALL timeset(routinen, handle)
1397
1398 nimg = SIZE(denmat, 2)
1399
1400 ! transformation
1401 CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
1402 CALL neighbor_list_iterator_create(nl_iterator, sab_nl)
1403 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
1404 CALL get_iterator_info(nl_iterator, iatom=iatom, jatom=jatom, cell=cell)
1405
1406 !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
1407 !Therefore, we have: S(R) = sum_k Re(S(k))*cos(k*R) -i^2*Im(S(k))*sin(k*R)
1408 ! = sum_k Re(S(k))*cos(k*R) + Im(S(k))*sin(k*R)
1409 !fc = +- 1 is due to the usual non-symmetric real-space matrices stored as symmetric ones
1410
1411 irow = iatom
1412 icol = jatom
1413 fc = 1.0_dp
1414 IF (do_symmetric .AND. iatom > jatom) THEN
1415 irow = jatom
1416 icol = iatom
1417 fc = -1.0_dp
1418 END IF
1419
1420 icell = cell_to_index(cell(1), cell(2), cell(3))
1421 IF (icell < 1 .OR. icell > nimg) cycle
1422
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)
1426
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
1430
1431 IF (real_only) THEN
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
1435 ELSE
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
1442 END IF
1443 END DO
1444 CALL neighbor_list_iterator_release(nl_iterator)
1445
1446 CALL timestop(handle)
1447
1448 END SUBROUTINE transform_dmat
1449
1450! **************************************************************************************************
1451!> \brief Symmetrization of density matrix - transform to new k-point
1452!> \param smat density matrix at new kpoint
1453!> \param pmat reference density matrix
1454!> \param kmat Kind type rotation matrix
1455!> \param rot Rotation matrix
1456!> \param f0 Permutation of atoms under transformation
1457!> \param atype Atom to kind pointer
1458!> \param symmetric Symmetric matrix
1459!> \param antisymmetric Anti-Symmetric matrix
1460! **************************************************************************************************
1461 SUBROUTINE symtrans(smat, pmat, kmat, rot, f0, atype, symmetric, antisymmetric)
1462 TYPE(dbcsr_type), POINTER :: smat, pmat
1463 TYPE(kind_rotmat_type), DIMENSION(:), POINTER :: kmat
1464 REAL(kind=dp), DIMENSION(3, 3), INTENT(IN) :: rot
1465 INTEGER, DIMENSION(:), INTENT(IN) :: f0, atype
1466 LOGICAL, INTENT(IN), OPTIONAL :: symmetric, antisymmetric
1467
1468 CHARACTER(LEN=*), PARAMETER :: routinen = 'symtrans'
1469
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
1475 TYPE(dbcsr_distribution_type) :: dist
1476 TYPE(dbcsr_iterator_type) :: iter
1477
1478 CALL timeset(routinen, handle)
1479
1480 ! check symmetry options
1481 sym = .false.
1482 IF (PRESENT(symmetric)) sym = symmetric
1483 asym = .false.
1484 IF (PRESENT(antisymmetric)) asym = antisymmetric
1485
1486 cpassert(.NOT. (sym .AND. asym))
1487 cpassert((sym .OR. asym))
1488
1489 ! do we have permutation of atoms
1490 natom = SIZE(f0)
1491 perm = .false.
1492 DO iatom = 1, natom
1493 IF (f0(iatom) == iatom) cycle
1494 perm = .true.
1495 EXIT
1496 END DO
1497
1498 ! do we have a real rotation
1499 dorot = .false.
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.
1503
1504 fsign = 1.0_dp
1505 IF (asym) fsign = -1.0_dp
1506
1507 IF (dorot .OR. perm) THEN
1508 CALL cp_abort(__location__, "k-points need FULL_GRID currently. "// &
1509 "Reduced grids not yet working correctly")
1510 CALL dbcsr_set(smat, 0.0_dp)
1511 IF (perm) THEN
1512 CALL dbcsr_get_info(pmat, distribution=dist)
1513 CALL dbcsr_distribution_get(dist, numnodes=numnodes)
1514 IF (numnodes == 1) THEN
1515 ! the matrices are local to this process
1516 CALL dbcsr_iterator_start(iter, pmat)
1517 DO WHILE (dbcsr_iterator_blocks_left(iter))
1518 CALL dbcsr_iterator_next_block(iter, irow, icol, pblock)
1519 ip = f0(irow)
1520 jp = f0(icol)
1521 IF (ip <= jp) THEN
1522 jrow = ip
1523 jcol = jp
1524 trans = .false.
1525 ELSE
1526 jrow = jp
1527 jcol = ip
1528 trans = .true.
1529 END IF
1530 CALL dbcsr_get_block_p(matrix=smat, row=jrow, col=jcol, block=sblock, found=found)
1531 cpassert(found)
1532 ikind = atype(irow)
1533 jkind = atype(icol)
1534 kroti => kmat(ikind)%rmat
1535 krotj => kmat(jkind)%rmat
1536 ! rotation
1537 IF (trans) THEN
1538 sblock = fsign*matmul(transpose(krotj), matmul(transpose(pblock), kroti))
1539 ELSE
1540 sblock = fsign*matmul(transpose(kroti), matmul(pblock, krotj))
1541 END IF
1542 END DO
1543 CALL dbcsr_iterator_stop(iter)
1544 !
1545 ELSE
1546 ! distributed matrices, most general code needed
1547 CALL cp_abort(__location__, "k-points need FULL_GRID currently. "// &
1548 "Reduced grids not yet working correctly")
1549 END IF
1550 ELSE
1551 ! no atom permutations, this is always local
1552 CALL dbcsr_copy(smat, pmat)
1553 CALL dbcsr_iterator_start(iter, smat)
1554 DO WHILE (dbcsr_iterator_blocks_left(iter))
1555 CALL dbcsr_iterator_next_block(iter, irow, icol, sblock)
1556 ip = f0(irow)
1557 jp = f0(icol)
1558 IF (ip <= jp) THEN
1559 jrow = ip
1560 jcol = jp
1561 trans = .false.
1562 ELSE
1563 jrow = jp
1564 jcol = ip
1565 trans = .true.
1566 END IF
1567 ikind = atype(irow)
1568 jkind = atype(icol)
1569 kroti => kmat(ikind)%rmat
1570 krotj => kmat(jkind)%rmat
1571 ! rotation
1572 IF (trans) THEN
1573 sblock = fsign*matmul(transpose(krotj), matmul(transpose(sblock), kroti))
1574 ELSE
1575 sblock = fsign*matmul(transpose(kroti), matmul(sblock, krotj))
1576 END IF
1577 END DO
1578 CALL dbcsr_iterator_stop(iter)
1579 !
1580 END IF
1581 ELSE
1582 ! this is the identity operation, just copy the matrix
1583 CALL dbcsr_copy(smat, pmat)
1584 END IF
1585
1586 CALL timestop(handle)
1587
1588 END SUBROUTINE symtrans
1589
1590! **************************************************************************************************
1591!> \brief ...
1592!> \param mat ...
1593! **************************************************************************************************
1594 SUBROUTINE matprint(mat)
1595 TYPE(dbcsr_type), POINTER :: mat
1596
1597 INTEGER :: i, icol, iounit, irow
1598 REAL(kind=dp), DIMENSION(:, :), POINTER :: mblock
1599 TYPE(dbcsr_iterator_type) :: iter
1600
1602 CALL dbcsr_iterator_start(iter, mat)
1603 DO WHILE (dbcsr_iterator_blocks_left(iter))
1604 CALL dbcsr_iterator_next_block(iter, irow, icol, mblock)
1605 !
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, :)
1610 END DO
1611 END IF
1612 !
1613 END DO
1614 CALL dbcsr_iterator_stop(iter)
1615
1616 END SUBROUTINE matprint
1617! **************************************************************************************************
1618
1619END 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_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)
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)
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