(git:374b731)
Loading...
Searching...
No Matches
hfx_communication.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Routines for data exchange between MPI processes
10!> \par History
11!> 04.2008 created [Manuel Guidon]
12!> \author Manuel Guidon
13! **************************************************************************************************
18 USE dbcsr_api, ONLY: dbcsr_get_block_p,&
19 dbcsr_iterator_blocks_left,&
20 dbcsr_iterator_next_block,&
21 dbcsr_iterator_start,&
22 dbcsr_iterator_stop,&
23 dbcsr_iterator_type,&
24 dbcsr_p_type,&
25 dbcsr_type
26 USE hfx_types, ONLY: hfx_2d_map,&
29 USE kinds, ONLY: dp,&
30 int_8
37#include "./base/base_uses.f90"
38
39 IMPLICIT NONE
40 PRIVATE
41
42 PUBLIC :: get_full_density, &
46 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'hfx_communication'
47
48!***
49
50CONTAINS
51
52! **************************************************************************************************
53!> \brief - Collects full density matrix from all CPUs
54!> \param para_env ...
55!> \param full_density The full Density matrix
56!> \param rho Distributed density
57!> \param number_of_p_entries Maximal buffer size
58!> \param block_offset ...
59!> \param kind_of ...
60!> \param basis_parameter ...
61!> \param get_max_vals_spin ...
62!> \param rho_beta ...
63!> \param antisymmetric ...
64!> \par History
65!> 11.2007 created [Manuel Guidon]
66!> \author Manuel Guidon
67!> \note
68!> - Communication with left/right node only
69!> added a mpi_sync before and after the ring of isendrecv. This *speed up* the
70!> communication, and might protect against idle neighbors flooding a busy node
71!> with messages [Joost]
72! **************************************************************************************************
73 SUBROUTINE get_full_density(para_env, full_density, rho, number_of_p_entries, &
74 block_offset, kind_of, basis_parameter, &
75 get_max_vals_spin, rho_beta, antisymmetric)
76
77 TYPE(mp_para_env_type), POINTER :: para_env
78 REAL(dp), DIMENSION(:) :: full_density
79 TYPE(dbcsr_type), POINTER :: rho
80 INTEGER, INTENT(IN) :: number_of_p_entries
81 INTEGER, DIMENSION(:), POINTER :: block_offset
82 INTEGER :: kind_of(*)
83 TYPE(hfx_basis_type), DIMENSION(:), POINTER :: basis_parameter
84 LOGICAL, INTENT(IN) :: get_max_vals_spin
85 TYPE(dbcsr_type), OPTIONAL, POINTER :: rho_beta
86 LOGICAL, INTENT(IN) :: antisymmetric
87
88 INTEGER :: blk, block_size, data_from, dest, i, iatom, icpu, ikind, iset, jatom, jkind, &
89 jset, mepos, ncpu, nseta, nsetb, pa, pa1, pb, pb1, source, source_cpu
90 INTEGER, DIMENSION(:), POINTER :: nsgfa, nsgfb
91 LOGICAL :: found
92 REAL(dp) :: symmfac
93 REAL(dp), DIMENSION(:), POINTER :: recbuffer, sendbuffer, swapbuffer
94 REAL(dp), DIMENSION(:, :), POINTER :: sparse_block, sparse_block_beta
95 TYPE(dbcsr_iterator_type) :: iter
96 TYPE(mp_request_type), DIMENSION(2) :: req
97
98 full_density = 0.0_dp
99 ALLOCATE (sendbuffer(number_of_p_entries))
100 ALLOCATE (recbuffer(number_of_p_entries))
101
102 i = 1
103 CALL dbcsr_iterator_start(iter, rho, shared=.false.)
104 DO WHILE (dbcsr_iterator_blocks_left(iter))
105 CALL dbcsr_iterator_next_block(iter, iatom, jatom, sparse_block, blk)
106 ! the resulting vector will eb only the upper triangle.
107 ! in case of antisymmetry take care to change signs if a lower block gets copied
108 symmfac = 1.0_dp
109 IF (antisymmetric .AND. iatom > jatom) symmfac = -1.0_dp
110 ikind = kind_of(iatom)
111 nseta = basis_parameter(ikind)%nset
112 nsgfa => basis_parameter(ikind)%nsgf
113 jkind = kind_of(jatom)
114 nsetb = basis_parameter(jkind)%nset
115 nsgfb => basis_parameter(jkind)%nsgf
116 IF (get_max_vals_spin) THEN
117 CALL dbcsr_get_block_p(rho_beta, &
118 row=iatom, col=jatom, block=sparse_block_beta, found=found)
119 pa = 0
120 DO iset = 1, nseta
121 pb = 0
122 DO jset = 1, nsetb
123 DO pa1 = pa + 1, pa + nsgfa(iset)
124 DO pb1 = pb + 1, pb + nsgfb(jset)
125 sendbuffer(i) = max(abs(sparse_block(pa1, pb1)), abs(sparse_block_beta(pa1, pb1)))
126 i = i + 1
127 END DO
128 END DO
129 pb = pb + nsgfb(jset)
130 END DO
131 pa = pa + nsgfa(iset)
132 END DO
133 ELSE
134 pa = 0
135 DO iset = 1, nseta
136 pb = 0
137 DO jset = 1, nsetb
138 DO pa1 = pa + 1, pa + nsgfa(iset)
139 DO pb1 = pb + 1, pb + nsgfb(jset)
140 sendbuffer(i) = sparse_block(pa1, pb1)*symmfac
141 i = i + 1
142 END DO
143 END DO
144 pb = pb + nsgfb(jset)
145 END DO
146 pa = pa + nsgfa(iset)
147 END DO
148 END IF
149 END DO
150 CALL dbcsr_iterator_stop(iter)
151
152 ! sync before/after a ring of isendrecv
153 CALL para_env%sync()
154 ncpu = para_env%num_pe
155 mepos = para_env%mepos
156 dest = modulo(mepos + 1, ncpu)
157 source = modulo(mepos - 1, ncpu)
158 DO icpu = 0, ncpu - 1
159 IF (icpu .NE. ncpu - 1) THEN
160 CALL para_env%isendrecv(sendbuffer, dest, recbuffer, source, &
161 req(1), req(2), 13)
162 END IF
163 data_from = modulo(mepos - icpu, ncpu)
164 source_cpu = modulo(data_from, ncpu) + 1
165 block_size = block_offset(source_cpu + 1) - block_offset(source_cpu)
166 full_density(block_offset(source_cpu):block_offset(source_cpu) + block_size - 1) = sendbuffer(1:block_size)
167
168 IF (icpu .NE. ncpu - 1) THEN
169 CALL mp_waitall(req)
170 END IF
171 swapbuffer => sendbuffer
172 sendbuffer => recbuffer
173 recbuffer => swapbuffer
174 END DO
175 DEALLOCATE (sendbuffer, recbuffer)
176 ! sync before/after a ring of isendrecv
177 CALL para_env%sync()
178
179 END SUBROUTINE get_full_density
180
181! **************************************************************************************************
182!> \brief - Distributes the local full Kohn-Sham matrix to all CPUS
183!> \param para_env ...
184!> \param full_ks The full Kohn-Sham matrix
185!> \param ks_matrix Distributed Kohn-Sham matrix
186!> \param number_of_p_entries Maximal buffer size
187!> \param block_offset ...
188!> \param kind_of ...
189!> \param basis_parameter ...
190!> \param off_diag_fac ...
191!> \param diag_fac ...
192!> \par History
193!> 11.2007 created [Manuel Guidon]
194!> \author Manuel Guidon
195!> \note
196!> - Communication with left/right node only
197! **************************************************************************************************
198 SUBROUTINE distribute_ks_matrix(para_env, full_ks, ks_matrix, number_of_p_entries, &
199 block_offset, kind_of, basis_parameter, &
200 off_diag_fac, diag_fac)
201
202 TYPE(mp_para_env_type), POINTER :: para_env
203 REAL(dp), DIMENSION(:) :: full_ks
204 TYPE(dbcsr_type), POINTER :: ks_matrix
205 INTEGER, INTENT(IN) :: number_of_p_entries
206 INTEGER, DIMENSION(:), POINTER :: block_offset
207 INTEGER :: kind_of(*)
208 TYPE(hfx_basis_type), DIMENSION(:), POINTER :: basis_parameter
209 REAL(dp), INTENT(IN), OPTIONAL :: off_diag_fac, diag_fac
210
211 INTEGER :: blk, block_size, data_to, dest, dest_cpu, i, iatom, icpu, ikind, iset, jatom, &
212 jkind, jset, mepos, ncpu, nseta, nsetb, pa, pa1, pb, pb1, source
213 INTEGER, DIMENSION(:), POINTER :: nsgfa, nsgfb
214 REAL(dp) :: my_fac, myd_fac
215 REAL(dp), DIMENSION(:), POINTER :: recbuffer, sendbuffer, swapbuffer
216 REAL(dp), DIMENSION(:, :), POINTER :: sparse_block
217 TYPE(dbcsr_iterator_type) :: iter
218 TYPE(mp_request_type), DIMENSION(2) :: req
219
220 my_fac = 1.0_dp; myd_fac = 1.0_dp
221 IF (PRESENT(off_diag_fac)) my_fac = off_diag_fac
222 IF (PRESENT(diag_fac)) myd_fac = diag_fac
223
224 ALLOCATE (sendbuffer(number_of_p_entries))
225 sendbuffer = 0.0_dp
226 ALLOCATE (recbuffer(number_of_p_entries))
227 recbuffer = 0.0_dp
228
229 ncpu = para_env%num_pe
230 mepos = para_env%mepos
231 dest = modulo(mepos + 1, ncpu)
232 source = modulo(mepos - 1, ncpu)
233
234 ! sync before/after a ring of isendrecv
235 CALL para_env%sync()
236 DO icpu = 1, ncpu
237 i = 1
238 data_to = mepos - icpu
239 dest_cpu = modulo(data_to, ncpu) + 1
240 block_size = block_offset(dest_cpu + 1) - block_offset(dest_cpu)
241 sendbuffer(1:block_size) = sendbuffer(1:block_size) + full_ks(block_offset(dest_cpu):block_offset(dest_cpu) + block_size - 1)
242 IF (icpu .EQ. ncpu) EXIT
243 CALL para_env%isendrecv(sendbuffer, dest, recbuffer, source, &
244 req(1), req(2), 13)
245
246 CALL mp_waitall(req)
247 swapbuffer => sendbuffer
248 sendbuffer => recbuffer
249 recbuffer => swapbuffer
250 END DO
251 ! sync before/after a ring of isendrecv
252 CALL para_env%sync()
253
254 i = 1
255 CALL dbcsr_iterator_start(iter, ks_matrix, shared=.false.)
256 DO WHILE (dbcsr_iterator_blocks_left(iter))
257 CALL dbcsr_iterator_next_block(iter, iatom, jatom, sparse_block, blk)
258
259 ikind = kind_of(iatom)
260 nseta = basis_parameter(ikind)%nset
261 nsgfa => basis_parameter(ikind)%nsgf
262 jkind = kind_of(jatom)
263 nsetb = basis_parameter(jkind)%nset
264 nsgfb => basis_parameter(jkind)%nsgf
265 pa = 0
266 DO iset = 1, nseta
267 pb = 0
268 DO jset = 1, nsetb
269 DO pa1 = pa + 1, pa + nsgfa(iset)
270 DO pb1 = pb + 1, pb + nsgfb(jset)
271 IF (iatom == jatom .AND. pa1 == pb1) THEN
272 sparse_block(pa1, pb1) = sendbuffer(i)*myd_fac + sparse_block(pa1, pb1)
273 ELSE
274 sparse_block(pa1, pb1) = sendbuffer(i)*my_fac + sparse_block(pa1, pb1)
275 END IF
276 i = i + 1
277 END DO
278 END DO
279 pb = pb + nsgfb(jset)
280 END DO
281 pa = pa + nsgfa(iset)
282 END DO
283 END DO
284 CALL dbcsr_iterator_stop(iter)
285
286 DEALLOCATE (sendbuffer, recbuffer)
287
288 END SUBROUTINE distribute_ks_matrix
289
290! **************************************************************************************************
291!> \brief - Distributes the local full Kohn-Sham matrix to all CPUS. Is called in
292!> case of adiabatic rescaling. This is just a refactored version of
293!> distribute_ks_matrix
294!> \param para_env ...
295!> \param qs_env ...
296!> \param ks_matrix Distributed Kohn-Sham matrix
297!> \param irep ...
298!> \param scaling_factor ...
299!> \par History
300!> 11.2007 created [Manuel Guidon]
301!> \author Manuel Guidon
302!> \note
303!> - Communication with left/right node only
304! **************************************************************************************************
305 SUBROUTINE scale_and_add_fock_to_ks_matrix(para_env, qs_env, ks_matrix, irep, &
306 scaling_factor)
307
308 TYPE(mp_para_env_type), POINTER :: para_env
309 TYPE(qs_environment_type), POINTER :: qs_env
310 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: ks_matrix
311 INTEGER, INTENT(IN) :: irep
312 REAL(dp), INTENT(IN) :: scaling_factor
313
314 INTEGER :: iatom, ikind, img, natom, nimages, nspins
315 INTEGER, ALLOCATABLE, DIMENSION(:) :: kind_of, last_sgf_global
316 REAL(dp), DIMENSION(:, :), POINTER :: full_ks
317 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
318 TYPE(dft_control_type), POINTER :: dft_control
319 TYPE(hfx_basis_type), DIMENSION(:), POINTER :: basis_parameter
320 TYPE(hfx_type), POINTER :: actual_x_data
321 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
322
323!! All shared data is saved in i_thread = 1!
324
325 NULLIFY (dft_control)
326 actual_x_data => qs_env%x_data(irep, 1)
327 basis_parameter => actual_x_data%basis_parameter
328
329 CALL get_qs_env(qs_env=qs_env, &
330 atomic_kind_set=atomic_kind_set, &
331 particle_set=particle_set, &
332 dft_control=dft_control)
333
334 nspins = dft_control%nspins
335 nimages = dft_control%nimages
336 cpassert(nimages == 1)
337
338 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, kind_of=kind_of)
339
340 natom = SIZE(particle_set, 1)
341 ALLOCATE (last_sgf_global(0:natom))
342 last_sgf_global(0) = 0
343 DO iatom = 1, natom
344 ikind = kind_of(iatom)
345 last_sgf_global(iatom) = last_sgf_global(iatom - 1) + basis_parameter(ikind)%nsgf_total
346 END DO
347 full_ks => actual_x_data%full_ks_alpha
348 IF (scaling_factor /= 1.0_dp) THEN
349 full_ks = full_ks*scaling_factor
350 END IF
351 DO img = 1, nimages
352 CALL distribute_ks_matrix(para_env, full_ks(:, img), ks_matrix(1, img)%matrix, actual_x_data%number_of_p_entries, &
353 actual_x_data%block_offset, kind_of, basis_parameter, &
354 off_diag_fac=0.5_dp)
355 END DO
356 DEALLOCATE (actual_x_data%full_ks_alpha)
357
358 IF (nspins == 2) THEN
359 full_ks => actual_x_data%full_ks_beta
360 IF (scaling_factor /= 1.0_dp) THEN
361 full_ks = full_ks*scaling_factor
362 END IF
363 DO img = 1, nimages
364 CALL distribute_ks_matrix(para_env, full_ks(:, img), ks_matrix(2, img)%matrix, actual_x_data%number_of_p_entries, &
365 actual_x_data%block_offset, kind_of, basis_parameter, &
366 off_diag_fac=0.5_dp)
367 END DO
368 DEALLOCATE (actual_x_data%full_ks_beta)
369 END IF
370
371 DEALLOCATE (last_sgf_global)
372
374
375! **************************************************************************************************
376!> \brief Given a 2d index pair, this function returns a 1d index pair for
377!> a symmetric upper triangle NxN matrix
378!> The compiler should inline this function, therefore it appears in
379!> several modules
380!> \param i 2d index
381!> \param j 2d index
382!> \param N matrix size
383!> \return ...
384!> \par History
385!> 03.2009 created [Manuel Guidon]
386!> \author Manuel Guidon
387! **************************************************************************************************
388 PURE FUNCTION get_1d_idx(i, j, N)
389 INTEGER, INTENT(IN) :: i, j
390 INTEGER(int_8), INTENT(IN) :: n
391 INTEGER(int_8) :: get_1d_idx
392
393 INTEGER(int_8) :: min_ij
394
395 min_ij = min(i, j)
396 get_1d_idx = min_ij*n + max(i, j) - (min_ij - 1)*min_ij/2 - n
397
398 END FUNCTION get_1d_idx
399
400! **************************************************************************************************
401!> \brief create a several maps array that reflects the ks matrix sparsity
402!> \param matrix ...
403!> \param basis_parameter ...
404!> \param kind_of ...
405!> \param is_assoc_atomic_block ...
406!> \param number_of_p_entries ...
407!> \param para_env ...
408!> \param atomic_block_offset ...
409!> \param set_offset ...
410!> \param block_offset ...
411!> \param map_atoms_to_cpus ...
412!> \param nkind ...
413!> \par History
414!> 11.2007 refactored [Joost VandeVondele]
415!> 07.2009 add new maps
416!> \author Manuel Guidon
417!> \notes
418!> is_assoc_atomic_block returns the mpi rank + 1 for associated blocks,
419!> zero for unassiated blocks
420! **************************************************************************************************
421 SUBROUTINE get_atomic_block_maps(matrix, basis_parameter, kind_of, &
422 is_assoc_atomic_block, number_of_p_entries, &
423 para_env, atomic_block_offset, set_offset, &
424 block_offset, map_atoms_to_cpus, nkind)
425
426 TYPE(dbcsr_type), POINTER :: matrix
427 TYPE(hfx_basis_type), DIMENSION(:) :: basis_parameter
428 INTEGER, DIMENSION(:) :: kind_of
429 INTEGER, DIMENSION(:, :), INTENT(OUT) :: is_assoc_atomic_block
430 INTEGER, INTENT(OUT) :: number_of_p_entries
431 TYPE(mp_para_env_type), POINTER :: para_env
432 INTEGER, DIMENSION(:, :), POINTER :: atomic_block_offset
433 INTEGER, DIMENSION(:, :, :, :), POINTER :: set_offset
434 INTEGER, DIMENSION(:), POINTER :: block_offset
435 TYPE(hfx_2d_map), DIMENSION(:), POINTER :: map_atoms_to_cpus
436 INTEGER :: nkind
437
438 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_atomic_block_maps'
439
440 INTEGER :: blk, handle, iatom, ibuf, icpu, ikind, ilist, iset, itask, jatom, jkind, jset, &
441 natom, ncpu, nseta, nsetb, number_of_p_blocks, offset, tmp(2)
442 INTEGER, ALLOCATABLE, DIMENSION(:) :: buffer_in, buffer_out, counter, rcount, &
443 rdispl
444 INTEGER, DIMENSION(:), POINTER :: iatom_list, jatom_list, nsgfa, nsgfb
445 REAL(kind=dp), DIMENSION(:, :), POINTER :: sparse_block
446 TYPE(dbcsr_iterator_type) :: iter
447
448 CALL timeset(routinen, handle)
449
450 is_assoc_atomic_block = 0
451 number_of_p_entries = 0
452 number_of_p_blocks = 0
453
454 !
455 ! count number_of_p_blocks and number_of_p_entries
456 !
457 CALL dbcsr_iterator_start(iter, matrix, shared=.false.)
458 DO WHILE (dbcsr_iterator_blocks_left(iter))
459 CALL dbcsr_iterator_next_block(iter, iatom, jatom, sparse_block, blk)
460 ikind = kind_of(iatom)
461 jkind = kind_of(jatom)
462 number_of_p_blocks = number_of_p_blocks + 1
463 number_of_p_entries = number_of_p_entries + &
464 basis_parameter(ikind)%nsgf_total*basis_parameter(jkind)%nsgf_total
465 END DO
466 CALL dbcsr_iterator_stop(iter)
467
468 tmp = (/number_of_p_entries, number_of_p_blocks/)
469 CALL para_env%max(tmp)
470 number_of_p_entries = tmp(1)
471 number_of_p_blocks = tmp(2)
472 !
473 ! send this info around, so we can construct is_assoc_atomic_block
474 ! pack all data in buffers and use allgatherv
475 !
476 ALLOCATE (buffer_in(3*number_of_p_blocks))
477 ALLOCATE (buffer_out(3*number_of_p_blocks*para_env%num_pe))
478 ALLOCATE (rcount(para_env%num_pe), rdispl(para_env%num_pe))
479
480 buffer_in = 0
481 ibuf = 0
482
483 CALL dbcsr_iterator_start(iter, matrix, shared=.false.)
484 DO WHILE (dbcsr_iterator_blocks_left(iter))
485 CALL dbcsr_iterator_next_block(iter, iatom, jatom, sparse_block, blk)
486
487 buffer_in(ibuf + 1) = iatom
488 buffer_in(ibuf + 2) = jatom
489 buffer_in(ibuf + 3) = para_env%mepos + 1
490 ibuf = ibuf + 3
491 END DO
492 CALL dbcsr_iterator_stop(iter)
493
494 rcount = SIZE(buffer_in)
495 rdispl(1) = 0
496 DO icpu = 2, para_env%num_pe
497 rdispl(icpu) = rdispl(icpu - 1) + rcount(icpu - 1)
498 END DO
499 CALL para_env%allgatherv(buffer_in, buffer_out, rcount, rdispl)
500
501 DO ibuf = 0, number_of_p_blocks*para_env%num_pe*3 - 3, 3
502 itask = buffer_out(ibuf + 3)
503 ! buffer_out can be 0 if buffer_in contained less elements than the max number of atom pairs
504 ! is_assoc_atomic_block is a map for atom pairs to a processor (assumes symmetry, i,j on the ame as j,i)
505 IF (itask .NE. 0) THEN
506 iatom = buffer_out(ibuf + 1)
507 jatom = buffer_out(ibuf + 2)
508 is_assoc_atomic_block(iatom, jatom) = itask
509 is_assoc_atomic_block(jatom, iatom) = itask
510 END IF
511 END DO
512
513 IF (ASSOCIATED(map_atoms_to_cpus)) THEN
514 DO icpu = 1, para_env%num_pe
515 DEALLOCATE (map_atoms_to_cpus(icpu)%iatom_list)
516 DEALLOCATE (map_atoms_to_cpus(icpu)%jatom_list)
517 END DO
518 DEALLOCATE (map_atoms_to_cpus)
519 END IF
520
521 natom = SIZE(is_assoc_atomic_block, 1)
522 ALLOCATE (map_atoms_to_cpus(para_env%num_pe))
523 ALLOCATE (counter(para_env%num_pe))
524 counter = 0
525
526 DO iatom = 1, natom
527 DO jatom = iatom, natom
528 icpu = is_assoc_atomic_block(jatom, iatom)
529 IF (icpu > 0) counter(icpu) = counter(icpu) + 1
530 END DO
531 END DO
532 DO icpu = 1, para_env%num_pe
533 ALLOCATE (map_atoms_to_cpus(icpu)%iatom_list(counter(icpu)))
534 ALLOCATE (map_atoms_to_cpus(icpu)%jatom_list(counter(icpu)))
535 END DO
536 counter = 0
537 DO iatom = 1, natom
538 DO jatom = iatom, natom
539 icpu = is_assoc_atomic_block(jatom, iatom)
540 IF (icpu > 0) THEN
541 counter(icpu) = counter(icpu) + 1
542 map_atoms_to_cpus(icpu)%jatom_list(counter(icpu)) = jatom
543 map_atoms_to_cpus(icpu)%iatom_list(counter(icpu)) = iatom
544 END IF
545 END DO
546 END DO
547
548 DEALLOCATE (counter)
549
550 ncpu = para_env%num_pe
551 offset = 1
552 atomic_block_offset = 0
553 block_offset = 0
554 DO icpu = 1, ncpu
555 iatom_list => map_atoms_to_cpus(icpu)%iatom_list
556 jatom_list => map_atoms_to_cpus(icpu)%jatom_list
557 block_offset(icpu) = offset
558 DO ilist = 1, SIZE(iatom_list)
559 iatom = iatom_list(ilist)
560 ikind = kind_of(iatom)
561 jatom = jatom_list(ilist)
562 jkind = kind_of(jatom)
563 atomic_block_offset(iatom, jatom) = offset
564 atomic_block_offset(jatom, iatom) = offset
565 offset = offset + basis_parameter(ikind)%nsgf_total*basis_parameter(jkind)%nsgf_total
566 END DO
567 END DO
568 block_offset(ncpu + 1) = offset
569 set_offset = 0
570 DO ikind = 1, nkind
571 nseta = basis_parameter(ikind)%nset
572 nsgfa => basis_parameter(ikind)%nsgf
573 DO jkind = 1, nkind
574 nsetb = basis_parameter(jkind)%nset
575 nsgfb => basis_parameter(jkind)%nsgf
576 offset = 1
577 DO iset = 1, nseta
578 DO jset = 1, nsetb
579 set_offset(jset, iset, jkind, ikind) = offset
580 offset = offset + nsgfa(iset)*nsgfb(jset)
581 END DO
582 END DO
583 END DO
584 END DO
585
586 CALL timestop(handle)
587
588 END SUBROUTINE get_atomic_block_maps
589
590END MODULE hfx_communication
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
Routines for data exchange between MPI processes.
subroutine, public distribute_ks_matrix(para_env, full_ks, ks_matrix, number_of_p_entries, block_offset, kind_of, basis_parameter, off_diag_fac, diag_fac)
Distributes the local full Kohn-Sham matrix to all CPUS
subroutine, public get_atomic_block_maps(matrix, basis_parameter, kind_of, is_assoc_atomic_block, number_of_p_entries, para_env, atomic_block_offset, set_offset, block_offset, map_atoms_to_cpus, nkind)
create a several maps array that reflects the ks matrix sparsity
subroutine, public get_full_density(para_env, full_density, rho, number_of_p_entries, block_offset, kind_of, basis_parameter, get_max_vals_spin, rho_beta, antisymmetric)
Collects full density matrix from all CPUs
subroutine, public scale_and_add_fock_to_ks_matrix(para_env, qs_env, ks_matrix, irep, scaling_factor)
Distributes the local full Kohn-Sham matrix to all CPUS. Is called in case of adiabatic rescaling....
Types and set/get functions for HFX.
Definition hfx_types.F:15
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public int_8
Definition kinds.F:54
integer, parameter, public dp
Definition kinds.F:34
Interface to the message passing library MPI.
Define the data structure for the particle information.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, rhs)
Get the QUICKSTEP environment.
Provides all information about an atomic kind.
stores some data used in construction of Kohn-Sham matrix
Definition hfx_types.F:509
stores all the informations relevant to an mpi environment