(git:ccc2433)
kg_environment.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 a Kim-Gordon-like partitioning into molecular subunits
10 !> \par History
11 !> 2012.07 created [Martin Haeufel]
12 !> \author Martin Haeufel
13 ! **************************************************************************************************
15  USE atomic_kind_types, ONLY: atomic_kind_type,&
18  gto_basis_set_type
19  USE bibliography, ONLY: andermatt2016,&
20  cite_reference
21  USE cell_types, ONLY: cell_type
22  USE cp_files, ONLY: close_file,&
23  open_file
26  cp_logger_type
27  USE distribution_1d_types, ONLY: distribution_1d_type
28  USE distribution_2d_types, ONLY: distribution_2d_type
29  USE external_potential_types, ONLY: get_potential,&
30  local_potential_type
31  USE input_constants, ONLY: kg_tnadd_atomic,&
36  section_vals_type,&
39  integration_grid_type
40  USE kg_environment_types, ONLY: kg_environment_type
42  USE kinds, ONLY: dp,&
43  int_4,&
44  int_4_size,&
45  int_8
48  USE message_passing, ONLY: mp_para_env_type
49  USE molecule_types, ONLY: molecule_type
50  USE particle_types, ONLY: particle_type
51  USE qs_environment_types, ONLY: get_qs_env,&
52  qs_environment_type
54  USE qs_kind_types, ONLY: get_qs_kind,&
55  qs_kind_type
59  neighbor_list_iterator_p_type,&
61  neighbor_list_set_p_type,&
63  USE qs_neighbor_lists, ONLY: atom2d_build,&
66  local_atoms_type,&
69  USE string_utilities, ONLY: uppercase
71  USE util, ONLY: sort
72 #include "./base/base_uses.f90"
73 
74  IMPLICIT NONE
75 
76  PRIVATE
77 
78  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'kg_environment'
79 
81 
82 CONTAINS
83 
84 ! **************************************************************************************************
85 !> \brief Allocates and intitializes kg_env
86 !> \param qs_env ...
87 !> \param kg_env the object to create
88 !> \param qs_kind_set ...
89 !> \param input ...
90 !> \par History
91 !> 2012.07 created [Martin Haeufel]
92 !> \author Martin Haeufel
93 ! **************************************************************************************************
94  SUBROUTINE kg_env_create(qs_env, kg_env, qs_kind_set, input)
95  TYPE(qs_environment_type), POINTER :: qs_env
96  TYPE(kg_environment_type), POINTER :: kg_env
97  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
98  TYPE(section_vals_type), OPTIONAL, POINTER :: input
99 
100  ALLOCATE (kg_env)
101  CALL init_kg_env(qs_env, kg_env, qs_kind_set, input)
102  END SUBROUTINE kg_env_create
103 
104 ! **************************************************************************************************
105 !> \brief Initializes kg_env
106 !> \param qs_env ...
107 !> \param kg_env ...
108 !> \param qs_kind_set ...
109 !> \param input ...
110 !> \par History
111 !> 2012.07 created [Martin Haeufel]
112 !> 2018.01 TNADD correction {JGH]
113 !> \author Martin Haeufel
114 ! **************************************************************************************************
115  SUBROUTINE init_kg_env(qs_env, kg_env, qs_kind_set, input)
116  TYPE(qs_environment_type), POINTER :: qs_env
117  TYPE(kg_environment_type), POINTER :: kg_env
118  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
119  TYPE(section_vals_type), OPTIONAL, POINTER :: input
120 
121  CHARACTER(LEN=*), PARAMETER :: routinen = 'init_kg_env'
122 
123  CHARACTER(LEN=10) :: intgrid
124  INTEGER :: handle, i, iatom, ib, ikind, iunit, n, &
125  na, natom, nbatch, nkind, np, nr
126  INTEGER, ALLOCATABLE, DIMENSION(:, :) :: bid
127  REAL(kind=dp) :: load, radb, rmax
128  TYPE(cp_logger_type), POINTER :: logger
129  TYPE(gto_basis_set_type), POINTER :: lri_aux_basis
130  TYPE(integration_grid_type), POINTER :: ig_full, ig_mol
131  TYPE(mp_para_env_type), POINTER :: para_env
132  TYPE(qs_kind_type), POINTER :: qs_kind
133  TYPE(section_vals_type), POINTER :: lri_section
134 
135  CALL timeset(routinen, handle)
136 
137  CALL cite_reference(andermatt2016)
138 
139  NULLIFY (para_env)
140  NULLIFY (kg_env%sab_orb_full)
141  NULLIFY (kg_env%sac_kin)
142  NULLIFY (kg_env%subset_of_mol)
143  NULLIFY (kg_env%subset)
144  NULLIFY (kg_env%tnadd_mat)
145  NULLIFY (kg_env%lri_env)
146  NULLIFY (kg_env%lri_env1)
147  NULLIFY (kg_env%int_grid_atom)
148  NULLIFY (kg_env%int_grid_molecules)
149  NULLIFY (kg_env%int_grid_full)
150  NULLIFY (kg_env%lri_density)
151  NULLIFY (kg_env%lri_rho1)
152 
153  kg_env%nsubsets = 0
154 
155  ! get coloring method settings
156  CALL section_vals_val_get(input, "DFT%KG_METHOD%COLORING_METHOD", i_val=kg_env%coloring_method)
157  ! get method for nonadditive kinetic energy embedding potential
158  CALL section_vals_val_get(input, "DFT%KG_METHOD%TNADD_METHOD", i_val=kg_env%tnadd_method)
159  !
160  SELECT CASE (kg_env%tnadd_method)
162  ! kinetic energy functional
163  kg_env%xc_section_kg => section_vals_get_subs_vals(input, "DFT%KG_METHOD%XC")
164  IF (.NOT. ASSOCIATED(kg_env%xc_section_kg)) THEN
165  CALL cp_abort(__location__, &
166  "KG runs require a kinetic energy functional set in &KG_METHOD")
167  END IF
169  NULLIFY (kg_env%xc_section_kg)
170  CASE DEFAULT
171  cpabort("KG:TNADD METHOD")
172  END SELECT
173 
174  IF (kg_env%tnadd_method == kg_tnadd_embed_ri) THEN
175  ! initialize the LRI environment
176  ! Check if LRI_AUX basis is available
177  rmax = 0.0_dp
178  nkind = SIZE(qs_kind_set)
179  DO ikind = 1, nkind
180  qs_kind => qs_kind_set(ikind)
181  NULLIFY (lri_aux_basis)
182  CALL get_qs_kind(qs_kind, basis_set=lri_aux_basis, basis_type="LRI_AUX")
183  cpassert(ASSOCIATED(lri_aux_basis))
184  CALL get_gto_basis_set(gto_basis_set=lri_aux_basis, kind_radius=radb)
185  rmax = max(rmax, radb)
186  END DO
187  rmax = 1.25_dp*rmax
188  lri_section => section_vals_get_subs_vals(input, "DFT%KG_METHOD%LRIGPW")
189  CALL lri_env_init(kg_env%lri_env, lri_section)
190  CALL lri_env_basis("LRI", qs_env, kg_env%lri_env, qs_kind_set)
191  !
192  ! if energy correction is performed with force calculation,
193  ! then response calculation requires
194  ! perturbation density for kernel calculation
195  CALL lri_env_init(kg_env%lri_env1, lri_section)
196  CALL lri_env_basis("LRI", qs_env, kg_env%lri_env1, qs_kind_set)
197  !
198  ! integration grid
199  !
200  CALL section_vals_val_get(input, "DFT%KG_METHOD%INTEGRATION_GRID", c_val=intgrid)
201  CALL uppercase(intgrid)
202  SELECT CASE (intgrid)
203  CASE ("SMALL")
204  nr = 50
205  na = 38
206  CASE ("MEDIUM")
207  nr = 100
208  na = 110
209  CASE ("LARGE")
210  nr = 200
211  na = 302
212  CASE ("HUGE")
213  nr = 400
214  na = 590
215  CASE DEFAULT
216  cpabort("KG:INTEGRATION_GRID")
217  END SELECT
218  NULLIFY (logger)
219  logger => cp_get_default_logger()
220  iunit = cp_logger_get_default_io_unit(logger)
221  CALL initialize_atomic_grid(kg_env%int_grid_atom, nr, na, rmax, iunit=iunit)
222  ! load balancing
223  CALL get_qs_env(qs_env=qs_env, natom=natom, para_env=para_env)
224  np = para_env%num_pe
225  load = real(natom, kind=dp)*kg_env%int_grid_atom%ntot/real(np, kind=dp)
226  !
227  CALL allocate_intgrid(kg_env%int_grid_full)
228  ig_full => kg_env%int_grid_full
229  CALL allocate_intgrid(kg_env%int_grid_molecules)
230  ig_mol => kg_env%int_grid_molecules
231  nbatch = (natom*kg_env%int_grid_atom%nbatch)/np
232  nbatch = nint((nbatch + 1)*1.2_dp)
233  ALLOCATE (bid(2, nbatch))
234  nbatch = 0
235  DO iatom = 1, natom
236  DO ib = 1, kg_env%int_grid_atom%nbatch
237  IF (para_env%mepos == mod(iatom + ib, np)) THEN
238  nbatch = nbatch + 1
239  cpassert(nbatch <= SIZE(bid, 2))
240  bid(1, nbatch) = iatom
241  bid(2, nbatch) = ib
242  END IF
243  END DO
244  END DO
245  !
246  ig_full%nbatch = nbatch
247  ALLOCATE (ig_full%grid_batch(nbatch))
248  !
249  ig_mol%nbatch = nbatch
250  ALLOCATE (ig_mol%grid_batch(nbatch))
251  !
252  DO i = 1, nbatch
253  iatom = bid(1, i)
254  ib = bid(2, i)
255  !
256  ig_full%grid_batch(i)%ref_atom = iatom
257  ig_full%grid_batch(i)%ibatch = ib
258  ig_full%grid_batch(i)%np = kg_env%int_grid_atom%batch(ib)%np
259  ig_full%grid_batch(i)%radius = kg_env%int_grid_atom%batch(ib)%rad
260  ig_full%grid_batch(i)%rcenter(1:3) = kg_env%int_grid_atom%batch(ib)%rcenter(1:3)
261  n = ig_full%grid_batch(i)%np
262  ALLOCATE (ig_full%grid_batch(i)%rco(3, n))
263  ALLOCATE (ig_full%grid_batch(i)%weight(n))
264  ALLOCATE (ig_full%grid_batch(i)%wref(n))
265  ALLOCATE (ig_full%grid_batch(i)%wsum(n))
266  ig_full%grid_batch(i)%weight(:) = kg_env%int_grid_atom%batch(ib)%weight(:)
267  !
268  ig_mol%grid_batch(i)%ref_atom = iatom
269  ig_mol%grid_batch(i)%ibatch = ib
270  ig_mol%grid_batch(i)%np = kg_env%int_grid_atom%batch(ib)%np
271  ig_mol%grid_batch(i)%radius = kg_env%int_grid_atom%batch(ib)%rad
272  ig_mol%grid_batch(i)%rcenter(1:3) = kg_env%int_grid_atom%batch(ib)%rcenter(1:3)
273  n = ig_mol%grid_batch(i)%np
274  ALLOCATE (ig_mol%grid_batch(i)%rco(3, n))
275  ALLOCATE (ig_mol%grid_batch(i)%weight(n))
276  ALLOCATE (ig_mol%grid_batch(i)%wref(n))
277  ALLOCATE (ig_mol%grid_batch(i)%wsum(n))
278  ig_mol%grid_batch(i)%weight(:) = kg_env%int_grid_atom%batch(ib)%weight(:)
279  END DO
280  !
281  DEALLOCATE (bid)
282  END IF
283 
284  CALL timestop(handle)
285 
286  END SUBROUTINE init_kg_env
287 
288 ! **************************************************************************************************
289 !> \brief builds either the full neighborlist or neighborlists of molecular
290 !> \brief subsets, depending on parameter values
291 !> \param qs_env ...
292 !> \param sab_orb the return type, a neighborlist
293 !> \param sac_kin ...
294 !> \param molecular if false, the full neighborlist is build
295 !> \param subset_of_mol the molecular subsets
296 !> \param current_subset the subset of which the neighborlist is to be build
297 !> \par History
298 !> 2012.07 created [Martin Haeufel]
299 !> \author Martin Haeufel
300 ! **************************************************************************************************
301  SUBROUTINE kg_build_neighborlist(qs_env, sab_orb, sac_kin, &
302  molecular, subset_of_mol, current_subset)
303  TYPE(qs_environment_type), POINTER :: qs_env
304  TYPE(neighbor_list_set_p_type), DIMENSION(:), &
305  OPTIONAL, POINTER :: sab_orb, sac_kin
306  LOGICAL, OPTIONAL :: molecular
307  INTEGER, DIMENSION(:), OPTIONAL, POINTER :: subset_of_mol
308  INTEGER, OPTIONAL :: current_subset
309 
310  CHARACTER(LEN=*), PARAMETER :: routinen = 'kg_build_neighborlist'
311 
312  INTEGER :: handle, ikind, nkind
313  LOGICAL :: mic, molecule_only
314  LOGICAL, ALLOCATABLE, DIMENSION(:) :: orb_present, tpot_present
315  REAL(dp) :: subcells
316  REAL(dp), ALLOCATABLE, DIMENSION(:) :: orb_radius, tpot_radius
317  REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: pair_radius
318  TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
319  TYPE(cell_type), POINTER :: cell
320  TYPE(distribution_1d_type), POINTER :: distribution_1d
321  TYPE(distribution_2d_type), POINTER :: distribution_2d
322  TYPE(gto_basis_set_type), POINTER :: orb_basis_set
323  TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:) :: atom2d
324  TYPE(local_potential_type), POINTER :: tnadd_potential
325  TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
326  TYPE(mp_para_env_type), POINTER :: para_env
327  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
328  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
329  TYPE(section_vals_type), POINTER :: neighbor_list_section
330 
331  CALL timeset(routinen, handle)
332  NULLIFY (para_env)
333 
334  ! restrict lists to molecular subgroups
335  molecule_only = .false.
336  IF (PRESENT(molecular)) molecule_only = molecular
337  ! enforce minimum image convention if we use molecules
338  mic = molecule_only
339 
340  CALL get_qs_env(qs_env=qs_env, &
341  atomic_kind_set=atomic_kind_set, &
342  qs_kind_set=qs_kind_set, &
343  cell=cell, &
344  distribution_2d=distribution_2d, &
345  molecule_set=molecule_set, &
346  local_particles=distribution_1d, &
347  particle_set=particle_set, &
348  para_env=para_env)
349 
350  CALL section_vals_val_get(qs_env%input, "DFT%SUBCELLS", r_val=subcells)
351 
352  ! Allocate work storage
353  nkind = SIZE(atomic_kind_set)
354  ALLOCATE (orb_radius(nkind), tpot_radius(nkind))
355  orb_radius(:) = 0.0_dp
356  tpot_radius(:) = 0.0_dp
357  ALLOCATE (orb_present(nkind), tpot_present(nkind))
358  ALLOCATE (pair_radius(nkind, nkind))
359  ALLOCATE (atom2d(nkind))
360 
361  CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
362  molecule_set, molecule_only, particle_set=particle_set)
363 
364  DO ikind = 1, nkind
365  CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom2d(ikind)%list)
366  CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
367  IF (ASSOCIATED(orb_basis_set)) THEN
368  orb_present(ikind) = .true.
369  IF (PRESENT(subset_of_mol)) THEN
370  CALL get_gto_basis_set(gto_basis_set=orb_basis_set, kind_radius=orb_radius(ikind))
371  ELSE
372  CALL get_gto_basis_set(gto_basis_set=orb_basis_set, short_kind_radius=orb_radius(ikind))
373  END IF
374  ELSE
375  orb_present(ikind) = .false.
376  orb_radius(ikind) = 0.0_dp
377  END IF
378  END DO
379 
380  IF (PRESENT(sab_orb)) THEN
381  ! Build the orbital-orbital overlap neighbor list
382  CALL pair_radius_setup(orb_present, orb_present, orb_radius, orb_radius, pair_radius)
383  IF (PRESENT(subset_of_mol)) THEN
384  CALL build_neighbor_lists(sab_orb, particle_set, atom2d, cell, pair_radius, &
385  mic=mic, subcells=subcells, molecular=molecule_only, subset_of_mol=subset_of_mol, &
386  current_subset=current_subset, nlname="sab_orb")
387  ELSE
388  CALL build_neighbor_lists(sab_orb, particle_set, atom2d, cell, pair_radius, &
389  mic=mic, subcells=subcells, molecular=molecule_only, nlname="sab_orb")
390  END IF
391  ! Print out the neighborlist
392  neighbor_list_section => section_vals_get_subs_vals(qs_env%input, "DFT%KG_METHOD%PRINT%NEIGHBOR_LISTS")
393  IF (molecule_only) THEN
394  CALL write_neighbor_lists(sab_orb, particle_set, cell, para_env, neighbor_list_section, &
395  "/SAB_ORB_MOLECULAR", "sab_orb", "MOLECULAR SUBSET NEIGHBORLIST")
396  ELSE
397  CALL write_neighbor_lists(sab_orb, particle_set, cell, para_env, neighbor_list_section, &
398  "/SAB_ORB_FULL", "sab_orb", "FULL NEIGHBORLIST")
399  END IF
400  END IF
401 
402  IF (PRESENT(sac_kin)) THEN
403  DO ikind = 1, nkind
404  tpot_present(ikind) = .false.
405  CALL get_qs_kind(qs_kind_set(ikind), tnadd_potential=tnadd_potential)
406  IF (ASSOCIATED(tnadd_potential)) THEN
407  CALL get_potential(potential=tnadd_potential, radius=tpot_radius(ikind))
408  tpot_present(ikind) = .true.
409  END IF
410  END DO
411  CALL pair_radius_setup(orb_present, tpot_present, orb_radius, tpot_radius, pair_radius)
412  CALL build_neighbor_lists(sac_kin, particle_set, atom2d, cell, pair_radius, &
413  subcells=subcells, operator_type="ABC", nlname="sac_kin")
414  neighbor_list_section => section_vals_get_subs_vals(qs_env%input, &
415  "DFT%KG_METHOD%PRINT%NEIGHBOR_LISTS")
416  CALL write_neighbor_lists(sac_kin, particle_set, cell, para_env, neighbor_list_section, &
417  "/SAC_KIN", "sac_kin", "ORBITAL kin energy potential")
418  END IF
419 
420  ! Release work storage
421  CALL atom2d_cleanup(atom2d)
422  DEALLOCATE (atom2d)
423  DEALLOCATE (orb_present, tpot_present)
424  DEALLOCATE (orb_radius, tpot_radius)
425  DEALLOCATE (pair_radius)
426 
427  CALL timestop(handle)
428 
429  END SUBROUTINE kg_build_neighborlist
430 
431 ! **************************************************************************************************
432 !> \brief Removes all replicated pairs from a 2d integer buffer array
433 !> \param pairs_buffer the array, assumed to have the shape (2,:)
434 !> \param n number of pairs (in), number of disjunct pairs (out)
435 !> \par History
436 !> 2012.07 created [Martin Haeufel]
437 !> 2014.11 simplified [Ole Schuett]
438 !> \author Martin Haeufel
439 ! **************************************************************************************************
440  SUBROUTINE kg_remove_duplicates(pairs_buffer, n)
441  INTEGER(KIND=int_4), DIMENSION(:, :), &
442  INTENT(INOUT) :: pairs_buffer
443  INTEGER, INTENT(INOUT) :: n
444 
445  CHARACTER(LEN=*), PARAMETER :: routinen = 'kg_remove_duplicates'
446 
447  INTEGER :: handle, i, npairs
448  INTEGER, DIMENSION(n) :: ind
449  INTEGER(KIND=int_8), DIMENSION(n) :: sort_keys
450  INTEGER(KIND=int_4), DIMENSION(2, n) :: work
451 
452  CALL timeset(routinen, handle)
453 
454  IF (n > 0) THEN
455  ! represent a pair of int_4 as a single int_8 number, simplifies sorting.
456  sort_keys(1:n) = ishft(int(pairs_buffer(1, 1:n), kind=int_8), 8*int_4_size)
457  sort_keys(1:n) = sort_keys(1:n) + pairs_buffer(2, 1:n) !upper + lower bytes
458  CALL sort(sort_keys, n, ind)
459 
460  ! add first pair, the case npairs==0 was excluded above
461  npairs = 1
462  work(:, 1) = pairs_buffer(:, ind(1))
463 
464  ! remove duplicates from the sorted list
465  DO i = 2, n
466  IF (sort_keys(i) /= sort_keys(i - 1)) THEN
467  npairs = npairs + 1
468  work(:, npairs) = pairs_buffer(:, ind(i))
469  END IF
470  END DO
471 
472  n = npairs
473  pairs_buffer(:, :n) = work(:, :n)
474  END IF
475 
476  CALL timestop(handle)
477 
478  END SUBROUTINE kg_remove_duplicates
479 
480 ! **************************************************************************************************
481 !> \brief writes the graph to file using the DIMACS standard format
482 !> for a definition of the file format see
483 !> mat.gsia.cmu.edu?COLOR/general/ccformat.ps
484 !> c comment line
485 !> p edge NODES EDGES
486 !> with NODES - number of nodes
487 !> EDGES - numer of edges
488 !> e W V
489 !> ...
490 !> there is one edge descriptor line for each edge in the graph
491 !> for an edge (w,v) the fields W and V specify its endpoints
492 !> \param pairs ...
493 !> \param nnodes the total number of nodes
494 ! **************************************************************************************************
495  SUBROUTINE write_to_file(pairs, nnodes)
496  INTEGER(KIND=int_4), ALLOCATABLE, &
497  DIMENSION(:, :), INTENT(IN) :: pairs
498  INTEGER, INTENT(IN) :: nnodes
499 
500  CHARACTER(LEN=*), PARAMETER :: routinen = 'write_to_file'
501 
502  INTEGER :: handle, i, imol, jmol, npairs, unit_nr
503  INTEGER(KIND=int_4), ALLOCATABLE, DIMENSION(:, :) :: sorted_pairs
504 
505  CALL timeset(routinen, handle)
506 
507  ! get the number of disjunct pairs
508  npairs = SIZE(pairs, 2)
509 
510  ALLOCATE (sorted_pairs(2, npairs))
511 
512  ! reorder pairs such that pairs(1,*) < pairs(2,*)
513  DO i = 1, npairs
514  ! get molecular ids
515  imol = pairs(1, i)
516  jmol = pairs(2, i)
517  IF (imol > jmol) THEN
518  ! switch pair and store
519  sorted_pairs(1, i) = jmol
520  sorted_pairs(2, i) = imol
521  ELSE
522  ! keep ordering just copy
523  sorted_pairs(1, i) = imol
524  sorted_pairs(2, i) = jmol
525  END IF
526  END DO
527 
528  ! remove duplicates and get the number of disjunct pairs (number of edges)
529  CALL kg_remove_duplicates(sorted_pairs, npairs)
530 
531  ! should now be half as much pairs as before
532  cpassert(npairs == SIZE(pairs, 2)/2)
533 
534  CALL open_file(unit_number=unit_nr, file_name="graph.col")
535 
536  WRITE (unit_nr, '(A6,1X,I8,1X,I8)') "p edge", nnodes, npairs
537 
538  ! only write out the first npairs entries
539  DO i = 1, npairs
540  WRITE (unit_nr, '(A1,1X,I8,1X,I8)') "e", sorted_pairs(1, i), sorted_pairs(2, i)
541  END DO
542 
543  CALL close_file(unit_nr)
544 
545  DEALLOCATE (sorted_pairs)
546 
547  CALL timestop(handle)
548 
549  END SUBROUTINE write_to_file
550 
551 ! **************************************************************************************************
552 !> \brief ...
553 !> \param kg_env ...
554 !> \param para_env ...
555 ! **************************************************************************************************
556  SUBROUTINE kg_build_subsets(kg_env, para_env)
557  TYPE(kg_environment_type), POINTER :: kg_env
558  TYPE(mp_para_env_type), POINTER :: para_env
559 
560  CHARACTER(LEN=*), PARAMETER :: routinen = 'kg_build_subsets'
561 
562  INTEGER :: color, handle, i, iatom, imol, isub, &
563  jatom, jmol, nmol, npairs, npairs_local
564  INTEGER(KIND=int_4) :: ncolors
565  INTEGER(KIND=int_4), ALLOCATABLE, DIMENSION(:) :: color_of_node
566  INTEGER(KIND=int_4), ALLOCATABLE, DIMENSION(:, :) :: msg_gather, pairs, pairs_buffer
567  INTEGER, ALLOCATABLE, DIMENSION(:) :: nnodes_of_color
568  TYPE(neighbor_list_iterator_p_type), &
569  DIMENSION(:), POINTER :: nl_iterator
570 
571  CALL timeset(routinen, handle)
572 
573  ! first: get a (local) list of pairs from the (local) neighbor list data
574  nmol = SIZE(kg_env%molecule_set)
575 
576  npairs = 0
577  CALL neighbor_list_iterator_create(nl_iterator, kg_env%sab_orb_full)
578  DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
579  CALL get_iterator_info(nl_iterator, iatom=iatom, jatom=jatom)
580 
581  imol = kg_env%atom_to_molecule(iatom)
582  jmol = kg_env%atom_to_molecule(jatom)
583 
584  !IF (imol<jmol) THEN
585  IF (imol .NE. jmol) THEN
586 
587  npairs = npairs + 2
588 
589  END IF
590 
591  END DO
592  CALL neighbor_list_iterator_release(nl_iterator)
593 
594  ALLOCATE (pairs_buffer(2, npairs))
595 
596  npairs = 0
597  CALL neighbor_list_iterator_create(nl_iterator, kg_env%sab_orb_full)
598  DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
599  CALL get_iterator_info(nl_iterator, iatom=iatom, jatom=jatom)
600 
601  imol = kg_env%atom_to_molecule(iatom)
602  jmol = kg_env%atom_to_molecule(jatom)
603 
604  IF (imol .NE. jmol) THEN
605 
606  ! add pair to the local list
607 
608  ! add both orderings - makes it easier to build the neighborlist
609  npairs = npairs + 1
610 
611  pairs_buffer(1, npairs) = imol
612  pairs_buffer(2, npairs) = jmol
613 
614  npairs = npairs + 1
615 
616  pairs_buffer(2, npairs) = imol
617  pairs_buffer(1, npairs) = jmol
618 
619  END IF
620 
621  END DO
622  CALL neighbor_list_iterator_release(nl_iterator)
623 
624  ! remove duplicates
625  CALL kg_remove_duplicates(pairs_buffer, npairs)
626 
627  ! get the maximum number of local pairs on all nodes (size of the mssg)
628  ! remember how many pairs we have local
629  npairs_local = npairs
630  CALL para_env%max(npairs)
631 
632  ! allocate message
633  ALLOCATE (pairs(2, npairs))
634 
635  pairs(:, 1:npairs_local) = pairs_buffer(:, 1:npairs_local)
636  pairs(:, npairs_local + 1:) = 0
637 
638  DEALLOCATE (pairs_buffer)
639 
640  ! second: gather all data on the master node
641  ! better would be a scheme where duplicates are removed in a tree-like reduction scheme.
642  ! this step can be needlessly memory intensive in the current implementation.
643 
644  IF (para_env%is_source()) THEN
645  ALLOCATE (msg_gather(2, npairs*para_env%num_pe))
646  ELSE
647  ALLOCATE (msg_gather(2, 1))
648  END IF
649 
650  msg_gather = 0
651 
652  CALL para_env%gather(pairs, msg_gather)
653 
654  DEALLOCATE (pairs)
655 
656  IF (para_env%is_source()) THEN
657 
658  ! shift all non-zero entries to the beginning of the array and count the number of actual pairs
659  npairs = 0
660 
661  DO i = 1, SIZE(msg_gather, 2)
662  IF (msg_gather(1, i) .NE. 0) THEN
663  npairs = npairs + 1
664  msg_gather(:, npairs) = msg_gather(:, i)
665  END IF
666  END DO
667 
668  ! remove duplicates
669  CALL kg_remove_duplicates(msg_gather, npairs)
670 
671  ALLOCATE (pairs(2, npairs))
672 
673  pairs(:, 1:npairs) = msg_gather(:, 1:npairs)
674 
675  DEALLOCATE (msg_gather)
676 
677  !WRITE(*,'(A48,5X,I10,4X,A2,1X,I10)') " KG| Total number of overlapping molecular pairs",npairs/2,"of",nmol*(nmol-1)/2
678 
679  ! write to file, nnodes = number of molecules
680  IF (.false.) THEN
681  CALL write_to_file(pairs, SIZE(kg_env%molecule_set))
682  END IF
683 
684  ! vertex coloring algorithm
685  CALL kg_vertex_coloring(kg_env, pairs, ncolors, color_of_node)
686 
687  DEALLOCATE (pairs)
688 
689  ELSE
690 
691  DEALLOCATE (msg_gather)
692 
693  END IF
694 
695  !WRITE(*,'(A27,40X,I6,1X,A6)') ' KG| Vertex coloring result', ncolors, 'colors'
696 
697  ! broadcast the number of colors to all nodes
698  CALL para_env%bcast(ncolors)
699 
700  IF (.NOT. ALLOCATED(color_of_node)) ALLOCATE (color_of_node(nmol))
701 
702  ! broadcast the resulting coloring to all nodes.....
703  CALL para_env%bcast(color_of_node)
704 
705  IF ((kg_env%nsubsets .NE. 0) .AND. (ncolors .NE. kg_env%nsubsets)) THEN
706  ! number of subsets has changed
707 
708  ! deallocate stuff if necessary
709  IF (ASSOCIATED(kg_env%subset)) THEN
710  DO isub = 1, kg_env%nsubsets
711  CALL release_neighbor_list_sets(kg_env%subset(isub)%sab_orb)
712  CALL deallocate_task_list(kg_env%subset(isub)%task_list)
713  END DO
714  DEALLOCATE (kg_env%subset)
715  NULLIFY (kg_env%subset)
716  END IF
717 
718  END IF
719 
720  ! allocate and nullify some stuff
721  IF (.NOT. ASSOCIATED(kg_env%subset)) THEN
722 
723  ALLOCATE (kg_env%subset(ncolors))
724 
725  DO i = 1, ncolors
726  NULLIFY (kg_env%subset(i)%sab_orb)
727  NULLIFY (kg_env%subset(i)%task_list)
728  END DO
729  END IF
730 
731  ! set the number of subsets
732  kg_env%nsubsets = ncolors
733 
734  ! counting loop
735  ALLOCATE (nnodes_of_color(ncolors))
736  nnodes_of_color = 0
737  DO i = 1, nmol ! nmol=nnodes
738  color = color_of_node(i)
739  kg_env%subset_of_mol(i) = color
740  nnodes_of_color(color) = nnodes_of_color(color) + 1
741  END DO
742 
743  DEALLOCATE (nnodes_of_color)
744  DEALLOCATE (color_of_node)
745 
746  CALL timestop(handle)
747 
748  END SUBROUTINE kg_build_subsets
749 
750 END MODULE kg_environment
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.
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius)
...
collects all references to literature in CP2K as new algorithms / method are included from literature...
Definition: bibliography.F:28
integer, save, public andermatt2016
Definition: bibliography.F:43
Handles all functions related to the CELL.
Definition: cell_types.F:15
Utility routines to open and close files. Tracking of preconnections.
Definition: cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition: cp_files.F:308
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition: cp_files.F:119
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...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
stores a mapping of 2D info (e.g. matrix) on a 2D processor distribution (i.e. blacs grid) where cpus...
Definition of the atomic potential types.
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public kg_tnadd_none
integer, parameter, public kg_tnadd_embed_ri
integer, parameter, public kg_tnadd_embed
integer, parameter, public kg_tnadd_atomic
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
subroutine, public allocate_intgrid(int_grid)
Initialize integration_grid_type.
Types needed for a Kim-Gordon-like partitioning into molecular subunits.
Routines for a Kim-Gordon-like partitioning into molecular subunits.
subroutine, public kg_env_create(qs_env, kg_env, qs_kind_set, input)
Allocates and intitializes kg_env.
subroutine, public kg_build_neighborlist(qs_env, sab_orb, sac_kin, molecular, subset_of_mol, current_subset)
builds either the full neighborlist or neighborlists of molecular
subroutine, public kg_build_subsets(kg_env, para_env)
...
Routines for a Kim-Gordon-like partitioning into molecular subunits unsing a vertex coloring algorith...
subroutine, public kg_vertex_coloring(kg_env, pairs, ncolors, color_of_node)
...
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
integer, parameter, public int_4_size
Definition: kinds.F:52
integer, parameter, public int_4
Definition: kinds.F:51
initializes the environment for lri lri : local resolution of the identity
subroutine, public lri_env_init(lri_env, lri_section)
initializes the lri env
subroutine, public lri_env_basis(ri_type, qs_env, lri_env, qs_kind_set)
initializes the lri env
Interface to the message passing library MPI.
Define the data structure for the molecule information.
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.
subroutine, public initialize_atomic_grid(int_grid, nr, na, rmax, quadrature, iunit)
Initialize atomic grid.
Definition: qs_grid_atom.F:286
Define the quickstep kind type and their sub types.
Definition: qs_kind_types.F:23
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_r3d_rs_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, U_of_dft_plus_u, J_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, J0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Define the neighbor list data types and the corresponding functionality.
subroutine, public release_neighbor_list_sets(nlists)
releases an array of neighbor_list_sets
subroutine, public neighbor_list_iterator_create(iterator_set, nl, search, nthread)
Neighbor list iterator functions.
subroutine, public neighbor_list_iterator_release(iterator_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)
...
Generate the atomic neighbor lists.
subroutine, public atom2d_cleanup(atom2d)
free the internals of atom2d
subroutine, public pair_radius_setup(present_a, present_b, radius_a, radius_b, pair_radius, prmin)
...
subroutine, public build_neighbor_lists(ab_list, particle_set, atom, cell, pair_radius, subcells, mic, symmetric, molecular, subset_of_mol, current_subset, operator_type, nlname, atomb_to_keep)
Build simple pair neighbor lists.
subroutine, public write_neighbor_lists(ab, particle_set, cell, para_env, neighbor_list_section, nl_type, middle_name, nlname)
Write a set of neighbor lists to the output unit.
subroutine, public atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, molecule_set, molecule_only, particle_set)
Build some distribution structure of atoms, refactored from build_qs_neighbor_lists.
Utilities for string manipulations.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
types for task lists
subroutine, public deallocate_task_list(task_list)
deallocates the components and the object itself
All kind of helpful little routines.
Definition: util.F:14