(git:374b731)
Loading...
Searching...
No Matches
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! **************************************************************************************************
19 USE bibliography, ONLY: andermatt2016,&
20 cite_reference
21 USE cell_types, ONLY: cell_type
22 USE cp_files, ONLY: close_file,&
42 USE kinds, ONLY: dp,&
43 int_4,&
45 int_8
54 USE qs_kind_types, ONLY: get_qs_kind,&
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
82CONTAINS
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
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
750END 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...
integer, save, public andermatt2016
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.
Define the quickstep kind type and their sub types.
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
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
type of a logger, at the moment it contains just a print level starting at which level it should be l...
structure to store local (to a processor) ordered lists of integers.
distributes pairs on a 2d grid of processors
Contains all the info needed for KG runs...
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.