(git:d18deda)
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 cpabort("kpoints: Smearing with fixed magnetic moments not (yet) supported")
965 nel = real(ne_a, kind=dp)
966 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, &
967 smear%electronic_temperature, 1.0_dp)
968 nel = real(ne_b, kind=dp)
969 CALL fermikp(wocc(:, :, 2), mus(2), kts, weig(:, :, 2), nel, wkp, &
970 smear%electronic_temperature, 1.0_dp)
971 ELSE
972 nel = real(ne_a, kind=dp) + real(ne_b, kind=dp)
973 CALL fermikp2(wocc(:, :, :), mu, kts, weig(:, :, :), nel, wkp, &
974 smear%electronic_temperature)
975 kts = kts/2._dp
976 mus(1:2) = mu
977 END IF
978 CASE DEFAULT
979 cpabort("kpoints: Selected smearing not (yet) supported")
980 END SELECT
981 ELSE
982 ! fixed occupations (2/1)
983 IF (nspin == 1) THEN
984 nel = real(nelectron, kind=dp)
985 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, 0.0_dp, 2.0_dp)
986 ELSE
987 nel = real(ne_a, kind=dp)
988 CALL fermikp(wocc(:, :, 1), mus(1), kts, weig(:, :, 1), nel, wkp, 0.0_dp, 1.0_dp)
989 nel = real(ne_b, kind=dp)
990 CALL fermikp(wocc(:, :, 2), mus(2), kts, weig(:, :, 2), nel, wkp, 0.0_dp, 1.0_dp)
991 END IF
992 END IF
993 DO ikpgr = 1, kplocal
994 ik = kp_range(1) + ikpgr - 1
995 kp => kpoint%kp_env(ikpgr)%kpoint_env
996 DO ispin = 1, nspin
997 mo_set => kp%mos(1, ispin)
998 CALL get_mo_set(mo_set, eigenvalues=eigenvalues, occupation_numbers=occupation)
999 eigenvalues(1:nmo) = weig(1:nmo, ik, ispin)
1000 occupation(1:nmo) = wocc(1:nmo, ik, ispin)
1001 mo_set%kTS = kts
1002 mo_set%mu = mus(ispin)
1003 END DO
1004 END DO
1005
1006 DEALLOCATE (weig, wocc)
1007
1008 CALL timestop(handle)
1009
1010 END SUBROUTINE kpoint_set_mo_occupation
1011
1012! **************************************************************************************************
1013!> \brief Calculate kpoint density matrices (rho(k), owned by kpoint groups)
1014!> \param kpoint kpoint environment
1015!> \param energy_weighted calculate energy weighted density matrix
1016!> \param for_aux_fit ...
1017! **************************************************************************************************
1018 SUBROUTINE kpoint_density_matrices(kpoint, energy_weighted, for_aux_fit)
1019
1020 TYPE(kpoint_type), POINTER :: kpoint
1021 LOGICAL, OPTIONAL :: energy_weighted, for_aux_fit
1022
1023 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_density_matrices'
1024
1025 INTEGER :: handle, ikpgr, ispin, kplocal, nao, nmo, &
1026 nspin
1027 INTEGER, DIMENSION(2) :: kp_range
1028 LOGICAL :: aux_fit, wtype
1029 REAL(kind=dp), DIMENSION(:), POINTER :: eigenvalues, occupation
1030 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
1031 TYPE(cp_fm_type) :: fwork
1032 TYPE(cp_fm_type), POINTER :: cpmat, pmat, rpmat
1033 TYPE(kpoint_env_type), POINTER :: kp
1034 TYPE(mo_set_type), POINTER :: mo_set
1035
1036 CALL timeset(routinen, handle)
1037
1038 IF (PRESENT(energy_weighted)) THEN
1039 wtype = energy_weighted
1040 ELSE
1041 ! default is normal density matrix
1042 wtype = .false.
1043 END IF
1044
1045 IF (PRESENT(for_aux_fit)) THEN
1046 aux_fit = for_aux_fit
1047 ELSE
1048 aux_fit = .false.
1049 END IF
1050
1051 IF (aux_fit) THEN
1052 cpassert(ASSOCIATED(kpoint%kp_aux_env))
1053 END IF
1054
1055 ! work matrix
1056 IF (aux_fit) THEN
1057 mo_set => kpoint%kp_aux_env(1)%kpoint_env%mos(1, 1)
1058 ELSE
1059 mo_set => kpoint%kp_env(1)%kpoint_env%mos(1, 1)
1060 END IF
1061 CALL get_mo_set(mo_set, nao=nao, nmo=nmo)
1062 CALL cp_fm_get_info(mo_set%mo_coeff, matrix_struct=matrix_struct)
1063 CALL cp_fm_create(fwork, matrix_struct)
1064
1065 CALL get_kpoint_info(kpoint, kp_range=kp_range)
1066 kplocal = kp_range(2) - kp_range(1) + 1
1067 DO ikpgr = 1, kplocal
1068 IF (aux_fit) THEN
1069 kp => kpoint%kp_aux_env(ikpgr)%kpoint_env
1070 ELSE
1071 kp => kpoint%kp_env(ikpgr)%kpoint_env
1072 END IF
1073 nspin = SIZE(kp%mos, 2)
1074 DO ispin = 1, nspin
1075 mo_set => kp%mos(1, ispin)
1076 IF (wtype) THEN
1077 CALL get_mo_set(mo_set, eigenvalues=eigenvalues)
1078 END IF
1079 IF (kpoint%use_real_wfn) THEN
1080 IF (wtype) THEN
1081 pmat => kp%wmat(1, ispin)
1082 ELSE
1083 pmat => kp%pmat(1, ispin)
1084 END IF
1085 CALL get_mo_set(mo_set, occupation_numbers=occupation)
1086 CALL cp_fm_to_fm(mo_set%mo_coeff, fwork)
1087 CALL cp_fm_column_scale(fwork, occupation)
1088 IF (wtype) THEN
1089 CALL cp_fm_column_scale(fwork, eigenvalues)
1090 END IF
1091 CALL parallel_gemm("N", "T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, pmat)
1092 ELSE
1093 IF (wtype) THEN
1094 rpmat => kp%wmat(1, ispin)
1095 cpmat => kp%wmat(2, ispin)
1096 ELSE
1097 rpmat => kp%pmat(1, ispin)
1098 cpmat => kp%pmat(2, ispin)
1099 END IF
1100 CALL get_mo_set(mo_set, occupation_numbers=occupation)
1101 CALL cp_fm_to_fm(mo_set%mo_coeff, fwork)
1102 CALL cp_fm_column_scale(fwork, occupation)
1103 IF (wtype) THEN
1104 CALL cp_fm_column_scale(fwork, eigenvalues)
1105 END IF
1106 ! Re(c)*Re(c)
1107 CALL parallel_gemm("N", "T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, rpmat)
1108 mo_set => kp%mos(2, ispin)
1109 ! Im(c)*Re(c)
1110 CALL parallel_gemm("N", "T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 0.0_dp, cpmat)
1111 ! Re(c)*Im(c)
1112 CALL parallel_gemm("N", "T", nao, nao, nmo, -1.0_dp, fwork, mo_set%mo_coeff, 1.0_dp, cpmat)
1113 CALL cp_fm_to_fm(mo_set%mo_coeff, fwork)
1114 CALL cp_fm_column_scale(fwork, occupation)
1115 IF (wtype) THEN
1116 CALL cp_fm_column_scale(fwork, eigenvalues)
1117 END IF
1118 ! Im(c)*Im(c)
1119 CALL parallel_gemm("N", "T", nao, nao, nmo, 1.0_dp, mo_set%mo_coeff, fwork, 1.0_dp, rpmat)
1120 END IF
1121 END DO
1122 END DO
1123
1124 CALL cp_fm_release(fwork)
1125
1126 CALL timestop(handle)
1127
1128 END SUBROUTINE kpoint_density_matrices
1129
1130! **************************************************************************************************
1131!> \brief generate real space density matrices in DBCSR format
1132!> \param kpoint Kpoint environment
1133!> \param denmat Real space (DBCSR) density matrices
1134!> \param wtype True = energy weighted density matrix
1135!> False = normal density matrix
1136!> \param tempmat DBCSR matrix to be used as template
1137!> \param sab_nl ...
1138!> \param fmwork FM work matrices (kpoint group)
1139!> \param for_aux_fit ...
1140!> \param pmat_ext ...
1141! **************************************************************************************************
1142 SUBROUTINE kpoint_density_transform(kpoint, denmat, wtype, tempmat, sab_nl, fmwork, for_aux_fit, pmat_ext)
1143
1144 TYPE(kpoint_type), POINTER :: kpoint
1145 TYPE(dbcsr_p_type), DIMENSION(:, :) :: denmat
1146 LOGICAL, INTENT(IN) :: wtype
1147 TYPE(dbcsr_type), POINTER :: tempmat
1148 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1149 POINTER :: sab_nl
1150 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fmwork
1151 LOGICAL, OPTIONAL :: for_aux_fit
1152 TYPE(cp_fm_type), DIMENSION(:, :, :), INTENT(IN), &
1153 OPTIONAL :: pmat_ext
1154
1155 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_density_transform'
1156
1157 INTEGER :: handle, ic, ik, ikk, indx, ir, ira, is, &
1158 ispin, jr, nc, nimg, nkp, nspin
1159 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
1160 LOGICAL :: aux_fit, do_ext, do_symmetric, my_kpgrp, &
1161 real_only
1162 REAL(kind=dp) :: wkpx
1163 REAL(kind=dp), DIMENSION(:), POINTER :: wkp
1164 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp
1165 TYPE(copy_info_type), ALLOCATABLE, DIMENSION(:) :: info
1166 TYPE(cp_fm_type) :: fmdummy
1167 TYPE(dbcsr_type), POINTER :: cpmat, rpmat, scpmat, srpmat
1168 TYPE(kind_rotmat_type), DIMENSION(:), POINTER :: kind_rot
1169 TYPE(kpoint_env_type), POINTER :: kp
1170 TYPE(kpoint_sym_type), POINTER :: kpsym
1171 TYPE(mp_para_env_type), POINTER :: para_env
1172
1173 CALL timeset(routinen, handle)
1174
1175 CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
1176
1177 IF (PRESENT(for_aux_fit)) THEN
1178 aux_fit = for_aux_fit
1179 ELSE
1180 aux_fit = .false.
1181 END IF
1182
1183 do_ext = .false.
1184 IF (PRESENT(pmat_ext)) do_ext = .true.
1185
1186 IF (aux_fit) THEN
1187 cpassert(ASSOCIATED(kpoint%kp_aux_env))
1188 END IF
1189
1190 ! work storage
1191 ALLOCATE (rpmat)
1192 CALL dbcsr_create(rpmat, template=tempmat, &
1193 matrix_type=merge(dbcsr_type_symmetric, dbcsr_type_no_symmetry, do_symmetric))
1194 CALL cp_dbcsr_alloc_block_from_nbl(rpmat, sab_nl)
1195 CALL dbcsr_set(rpmat, 0.0_dp)
1196 ALLOCATE (cpmat)
1197 CALL dbcsr_create(cpmat, template=tempmat, &
1198 matrix_type=merge(dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, do_symmetric))
1199 CALL cp_dbcsr_alloc_block_from_nbl(cpmat, sab_nl)
1200 CALL dbcsr_set(cpmat, 0.0_dp)
1201 IF (.NOT. kpoint%full_grid) THEN
1202 ALLOCATE (srpmat)
1203 CALL dbcsr_create(srpmat, template=rpmat)
1204 CALL cp_dbcsr_alloc_block_from_nbl(srpmat, sab_nl)
1205 CALL dbcsr_set(srpmat, 0.0_dp)
1206 ALLOCATE (scpmat)
1207 CALL dbcsr_create(scpmat, template=cpmat)
1208 CALL cp_dbcsr_alloc_block_from_nbl(scpmat, sab_nl)
1209 CALL dbcsr_set(scpmat, 0.0_dp)
1210 END IF
1211
1212 CALL get_kpoint_info(kpoint, nkp=nkp, xkp=xkp, wkp=wkp, &
1213 cell_to_index=cell_to_index)
1214 ! initialize real space density matrices
1215 IF (aux_fit) THEN
1216 kp => kpoint%kp_aux_env(1)%kpoint_env
1217 ELSE
1218 kp => kpoint%kp_env(1)%kpoint_env
1219 END IF
1220 nspin = SIZE(kp%mos, 2)
1221 nc = SIZE(kp%mos, 1)
1222 nimg = SIZE(denmat, 2)
1223 real_only = (nc == 1)
1224
1225 para_env => kpoint%blacs_env_all%para_env
1226 ALLOCATE (info(nspin*nkp*nc))
1227
1228 ! Start all the communication
1229 indx = 0
1230 DO ispin = 1, nspin
1231 DO ic = 1, nimg
1232 CALL dbcsr_set(denmat(ispin, ic)%matrix, 0.0_dp)
1233 END DO
1234 !
1235 DO ik = 1, nkp
1236 my_kpgrp = (ik >= kpoint%kp_range(1) .AND. ik <= kpoint%kp_range(2))
1237 IF (my_kpgrp) THEN
1238 ikk = ik - kpoint%kp_range(1) + 1
1239 IF (aux_fit) THEN
1240 kp => kpoint%kp_aux_env(ikk)%kpoint_env
1241 ELSE
1242 kp => kpoint%kp_env(ikk)%kpoint_env
1243 END IF
1244 ELSE
1245 NULLIFY (kp)
1246 END IF
1247 ! collect this density matrix on all processors
1248 cpassert(SIZE(fmwork) >= nc)
1249
1250 IF (my_kpgrp) THEN
1251 DO ic = 1, nc
1252 indx = indx + 1
1253 IF (do_ext) THEN
1254 CALL cp_fm_start_copy_general(pmat_ext(ikk, ic, ispin), fmwork(ic), para_env, info(indx))
1255 ELSE
1256 IF (wtype) THEN
1257 CALL cp_fm_start_copy_general(kp%wmat(ic, ispin), fmwork(ic), para_env, info(indx))
1258 ELSE
1259 CALL cp_fm_start_copy_general(kp%pmat(ic, ispin), fmwork(ic), para_env, info(indx))
1260 END IF
1261 END IF
1262 END DO
1263 ELSE
1264 DO ic = 1, nc
1265 indx = indx + 1
1266 CALL cp_fm_start_copy_general(fmdummy, fmwork(ic), para_env, info(indx))
1267 END DO
1268 END IF
1269 END DO
1270 END DO
1271
1272 ! Finish communication and transform the received matrices
1273 indx = 0
1274 DO ispin = 1, nspin
1275 DO ik = 1, nkp
1276 DO ic = 1, nc
1277 indx = indx + 1
1278 CALL cp_fm_finish_copy_general(fmwork(ic), info(indx))
1279 END DO
1280
1281 ! reduce to dbcsr storage
1282 IF (real_only) THEN
1283 CALL copy_fm_to_dbcsr(fmwork(1), rpmat, keep_sparsity=.true.)
1284 ELSE
1285 CALL copy_fm_to_dbcsr(fmwork(1), rpmat, keep_sparsity=.true.)
1286 CALL copy_fm_to_dbcsr(fmwork(2), cpmat, keep_sparsity=.true.)
1287 END IF
1288
1289 ! symmetrization
1290 kpsym => kpoint%kp_sym(ik)%kpoint_sym
1291 cpassert(ASSOCIATED(kpsym))
1292
1293 IF (kpsym%apply_symmetry) THEN
1294 wkpx = wkp(ik)/real(kpsym%nwght, kind=dp)
1295 DO is = 1, kpsym%nwght
1296 ir = abs(kpsym%rotp(is))
1297 ira = 0
1298 DO jr = 1, SIZE(kpoint%ibrot)
1299 IF (ir == kpoint%ibrot(jr)) ira = jr
1300 END DO
1301 cpassert(ira > 0)
1302 kind_rot => kpoint%kind_rotmat(ira, :)
1303 IF (real_only) THEN
1304 CALL symtrans(srpmat, rpmat, kind_rot, kpsym%rot(1:3, 1:3, is), &
1305 kpsym%f0(:, is), kpoint%atype, symmetric=.true.)
1306 ELSE
1307 CALL symtrans(srpmat, rpmat, kind_rot, kpsym%rot(1:3, 1:3, is), &
1308 kpsym%f0(:, is), kpoint%atype, symmetric=.true.)
1309 CALL symtrans(scpmat, cpmat, kind_rot, kpsym%rot(1:3, 1:3, is), &
1310 kpsym%f0(:, is), kpoint%atype, antisymmetric=.true.)
1311 END IF
1312 CALL transform_dmat(denmat, srpmat, scpmat, ispin, real_only, sab_nl, &
1313 cell_to_index, kpsym%xkp(1:3, is), wkpx)
1314 END DO
1315 ELSE
1316 ! transformation
1317 CALL transform_dmat(denmat, rpmat, cpmat, ispin, real_only, sab_nl, &
1318 cell_to_index, xkp(1:3, ik), wkp(ik))
1319 END IF
1320 END DO
1321 END DO
1322
1323 ! Clean up communication
1324 indx = 0
1325 DO ispin = 1, nspin
1326 DO ik = 1, nkp
1327 my_kpgrp = (ik >= kpoint%kp_range(1) .AND. ik <= kpoint%kp_range(2))
1328 IF (my_kpgrp) THEN
1329 ikk = ik - kpoint%kp_range(1) + 1
1330 IF (aux_fit) THEN
1331 kp => kpoint%kp_aux_env(ikk)%kpoint_env
1332 ELSE
1333 kp => kpoint%kp_env(ikk)%kpoint_env
1334 END IF
1335
1336 DO ic = 1, nc
1337 indx = indx + 1
1338 CALL cp_fm_cleanup_copy_general(info(indx))
1339 END DO
1340 ELSE
1341 ! calls with dummy arguments, so not included
1342 ! therefore just increment counter by trip count
1343 indx = indx + nc
1344 END IF
1345 END DO
1346 END DO
1347
1348 ! All done
1349 DEALLOCATE (info)
1350
1351 CALL dbcsr_deallocate_matrix(rpmat)
1352 CALL dbcsr_deallocate_matrix(cpmat)
1353 IF (.NOT. kpoint%full_grid) THEN
1354 CALL dbcsr_deallocate_matrix(srpmat)
1355 CALL dbcsr_deallocate_matrix(scpmat)
1356 END IF
1357
1358 CALL timestop(handle)
1359
1360 END SUBROUTINE kpoint_density_transform
1361
1362! **************************************************************************************************
1363!> \brief real space density matrices in DBCSR format
1364!> \param denmat Real space (DBCSR) density matrix
1365!> \param rpmat ...
1366!> \param cpmat ...
1367!> \param ispin ...
1368!> \param real_only ...
1369!> \param sab_nl ...
1370!> \param cell_to_index ...
1371!> \param xkp ...
1372!> \param wkp ...
1373! **************************************************************************************************
1374 SUBROUTINE transform_dmat(denmat, rpmat, cpmat, ispin, real_only, sab_nl, cell_to_index, xkp, wkp)
1375
1376 TYPE(dbcsr_p_type), DIMENSION(:, :) :: denmat
1377 TYPE(dbcsr_type), POINTER :: rpmat, cpmat
1378 INTEGER, INTENT(IN) :: ispin
1379 LOGICAL, INTENT(IN) :: real_only
1380 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1381 POINTER :: sab_nl
1382 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
1383 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: xkp
1384 REAL(kind=dp), INTENT(IN) :: wkp
1385
1386 CHARACTER(LEN=*), PARAMETER :: routinen = 'transform_dmat'
1387
1388 INTEGER :: handle, iatom, icell, icol, irow, jatom, &
1389 nimg
1390 INTEGER, DIMENSION(3) :: cell
1391 LOGICAL :: do_symmetric, found
1392 REAL(kind=dp) :: arg, coskl, fc, sinkl
1393 REAL(kind=dp), DIMENSION(:, :), POINTER :: cblock, dblock, rblock
1395 DIMENSION(:), POINTER :: nl_iterator
1396
1397 CALL timeset(routinen, handle)
1398
1399 nimg = SIZE(denmat, 2)
1400
1401 ! transformation
1402 CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
1403 CALL neighbor_list_iterator_create(nl_iterator, sab_nl)
1404 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
1405 CALL get_iterator_info(nl_iterator, iatom=iatom, jatom=jatom, cell=cell)
1406
1407 !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
1408 !Therefore, we have: S(R) = sum_k Re(S(k))*cos(k*R) -i^2*Im(S(k))*sin(k*R)
1409 ! = sum_k Re(S(k))*cos(k*R) + Im(S(k))*sin(k*R)
1410 !fc = +- 1 is due to the usual non-symmetric real-space matrices stored as symmetric ones
1411
1412 irow = iatom
1413 icol = jatom
1414 fc = 1.0_dp
1415 IF (do_symmetric .AND. iatom > jatom) THEN
1416 irow = jatom
1417 icol = iatom
1418 fc = -1.0_dp
1419 END IF
1420
1421 icell = cell_to_index(cell(1), cell(2), cell(3))
1422 IF (icell < 1 .OR. icell > nimg) cycle
1423
1424 arg = real(cell(1), dp)*xkp(1) + real(cell(2), dp)*xkp(2) + real(cell(3), dp)*xkp(3)
1425 coskl = wkp*cos(twopi*arg)
1426 sinkl = wkp*fc*sin(twopi*arg)
1427
1428 CALL dbcsr_get_block_p(matrix=denmat(ispin, icell)%matrix, row=irow, col=icol, &
1429 block=dblock, found=found)
1430 IF (.NOT. found) cycle
1431
1432 IF (real_only) THEN
1433 CALL dbcsr_get_block_p(matrix=rpmat, row=irow, col=icol, block=rblock, found=found)
1434 IF (.NOT. found) cycle
1435 dblock = dblock + coskl*rblock
1436 ELSE
1437 CALL dbcsr_get_block_p(matrix=rpmat, row=irow, col=icol, block=rblock, found=found)
1438 IF (.NOT. found) cycle
1439 CALL dbcsr_get_block_p(matrix=cpmat, row=irow, col=icol, block=cblock, found=found)
1440 IF (.NOT. found) cycle
1441 dblock = dblock + coskl*rblock
1442 dblock = dblock + sinkl*cblock
1443 END IF
1444 END DO
1445 CALL neighbor_list_iterator_release(nl_iterator)
1446
1447 CALL timestop(handle)
1448
1449 END SUBROUTINE transform_dmat
1450
1451! **************************************************************************************************
1452!> \brief Symmetrization of density matrix - transform to new k-point
1453!> \param smat density matrix at new kpoint
1454!> \param pmat reference density matrix
1455!> \param kmat Kind type rotation matrix
1456!> \param rot Rotation matrix
1457!> \param f0 Permutation of atoms under transformation
1458!> \param atype Atom to kind pointer
1459!> \param symmetric Symmetric matrix
1460!> \param antisymmetric Anti-Symmetric matrix
1461! **************************************************************************************************
1462 SUBROUTINE symtrans(smat, pmat, kmat, rot, f0, atype, symmetric, antisymmetric)
1463 TYPE(dbcsr_type), POINTER :: smat, pmat
1464 TYPE(kind_rotmat_type), DIMENSION(:), POINTER :: kmat
1465 REAL(kind=dp), DIMENSION(3, 3), INTENT(IN) :: rot
1466 INTEGER, DIMENSION(:), INTENT(IN) :: f0, atype
1467 LOGICAL, INTENT(IN), OPTIONAL :: symmetric, antisymmetric
1468
1469 CHARACTER(LEN=*), PARAMETER :: routinen = 'symtrans'
1470
1471 INTEGER :: handle, iatom, icol, ikind, ip, irow, &
1472 jcol, jkind, jp, jrow, natom, numnodes
1473 LOGICAL :: asym, dorot, found, perm, sym, trans
1474 REAL(kind=dp) :: dr, fsign
1475 REAL(kind=dp), DIMENSION(:, :), POINTER :: kroti, krotj, pblock, sblock
1476 TYPE(dbcsr_distribution_type) :: dist
1477 TYPE(dbcsr_iterator_type) :: iter
1478
1479 CALL timeset(routinen, handle)
1480
1481 ! check symmetry options
1482 sym = .false.
1483 IF (PRESENT(symmetric)) sym = symmetric
1484 asym = .false.
1485 IF (PRESENT(antisymmetric)) asym = antisymmetric
1486
1487 cpassert(.NOT. (sym .AND. asym))
1488 cpassert((sym .OR. asym))
1489
1490 ! do we have permutation of atoms
1491 natom = SIZE(f0)
1492 perm = .false.
1493 DO iatom = 1, natom
1494 IF (f0(iatom) == iatom) cycle
1495 perm = .true.
1496 EXIT
1497 END DO
1498
1499 ! do we have a real rotation
1500 dorot = .false.
1501 IF (abs(sum(abs(rot)) - 3.0_dp) > 1.e-12_dp) dorot = .true.
1502 dr = abs(rot(1, 1) - 1.0_dp) + abs(rot(2, 2) - 1.0_dp) + abs(rot(3, 3) - 1.0_dp)
1503 IF (abs(dr) > 1.e-12_dp) dorot = .true.
1504
1505 fsign = 1.0_dp
1506 IF (asym) fsign = -1.0_dp
1507
1508 IF (dorot .OR. perm) THEN
1509 CALL cp_abort(__location__, "k-points need FULL_GRID currently. "// &
1510 "Reduced grids not yet working correctly")
1511 CALL dbcsr_set(smat, 0.0_dp)
1512 IF (perm) THEN
1513 CALL dbcsr_get_info(pmat, distribution=dist)
1514 CALL dbcsr_distribution_get(dist, numnodes=numnodes)
1515 IF (numnodes == 1) THEN
1516 ! the matrices are local to this process
1517 CALL dbcsr_iterator_start(iter, pmat)
1518 DO WHILE (dbcsr_iterator_blocks_left(iter))
1519 CALL dbcsr_iterator_next_block(iter, irow, icol, pblock)
1520 ip = f0(irow)
1521 jp = f0(icol)
1522 IF (ip <= jp) THEN
1523 jrow = ip
1524 jcol = jp
1525 trans = .false.
1526 ELSE
1527 jrow = jp
1528 jcol = ip
1529 trans = .true.
1530 END IF
1531 CALL dbcsr_get_block_p(matrix=smat, row=jrow, col=jcol, block=sblock, found=found)
1532 cpassert(found)
1533 ikind = atype(irow)
1534 jkind = atype(icol)
1535 kroti => kmat(ikind)%rmat
1536 krotj => kmat(jkind)%rmat
1537 ! rotation
1538 IF (trans) THEN
1539 sblock = fsign*matmul(transpose(krotj), matmul(transpose(pblock), kroti))
1540 ELSE
1541 sblock = fsign*matmul(transpose(kroti), matmul(pblock, krotj))
1542 END IF
1543 END DO
1544 CALL dbcsr_iterator_stop(iter)
1545 !
1546 ELSE
1547 ! distributed matrices, most general code needed
1548 CALL cp_abort(__location__, "k-points need FULL_GRID currently. "// &
1549 "Reduced grids not yet working correctly")
1550 END IF
1551 ELSE
1552 ! no atom permutations, this is always local
1553 CALL dbcsr_copy(smat, pmat)
1554 CALL dbcsr_iterator_start(iter, smat)
1555 DO WHILE (dbcsr_iterator_blocks_left(iter))
1556 CALL dbcsr_iterator_next_block(iter, irow, icol, sblock)
1557 ip = f0(irow)
1558 jp = f0(icol)
1559 IF (ip <= jp) THEN
1560 jrow = ip
1561 jcol = jp
1562 trans = .false.
1563 ELSE
1564 jrow = jp
1565 jcol = ip
1566 trans = .true.
1567 END IF
1568 ikind = atype(irow)
1569 jkind = atype(icol)
1570 kroti => kmat(ikind)%rmat
1571 krotj => kmat(jkind)%rmat
1572 ! rotation
1573 IF (trans) THEN
1574 sblock = fsign*matmul(transpose(krotj), matmul(transpose(sblock), kroti))
1575 ELSE
1576 sblock = fsign*matmul(transpose(kroti), matmul(sblock, krotj))
1577 END IF
1578 END DO
1579 CALL dbcsr_iterator_stop(iter)
1580 !
1581 END IF
1582 ELSE
1583 ! this is the identity operation, just copy the matrix
1584 CALL dbcsr_copy(smat, pmat)
1585 END IF
1586
1587 CALL timestop(handle)
1588
1589 END SUBROUTINE symtrans
1590
1591! **************************************************************************************************
1592!> \brief ...
1593!> \param mat ...
1594! **************************************************************************************************
1595 SUBROUTINE matprint(mat)
1596 TYPE(dbcsr_type), POINTER :: mat
1597
1598 INTEGER :: i, icol, iounit, irow
1599 REAL(kind=dp), DIMENSION(:, :), POINTER :: mblock
1600 TYPE(dbcsr_iterator_type) :: iter
1601
1603 CALL dbcsr_iterator_start(iter, mat)
1604 DO WHILE (dbcsr_iterator_blocks_left(iter))
1605 CALL dbcsr_iterator_next_block(iter, irow, icol, mblock)
1606 !
1607 IF (iounit > 0) THEN
1608 WRITE (iounit, '(A,2I4)') 'BLOCK ', irow, icol
1609 DO i = 1, SIZE(mblock, 1)
1610 WRITE (iounit, '(8F12.6)') mblock(i, :)
1611 END DO
1612 END IF
1613 !
1614 END DO
1615 CALL dbcsr_iterator_stop(iter)
1616
1617 END SUBROUTINE matprint
1618! **************************************************************************************************
1619
1620END 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