(git:ccc2433)
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 ! **************************************************************************************************
15  USE atomic_kind_types, ONLY: atomic_kind_type,&
17  USE cp_control_types, ONLY: dft_control_type
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,&
27  hfx_basis_type,&
28  hfx_type
29  USE kinds, ONLY: dp,&
30  int_8
31  USE message_passing, ONLY: mp_para_env_type,&
32  mp_request_type,&
33  mp_waitall
34  USE particle_types, ONLY: particle_type
35  USE qs_environment_types, ONLY: get_qs_env,&
36  qs_environment_type
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 
50 CONTAINS
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 
373  END SUBROUTINE scale_and_add_fock_to_ks_matrix
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 
590 END 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....
Definition: grid_common.h:117
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.