(git:9111030)
Loading...
Searching...
No Matches
topology_coordinate_util.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Collection of subroutine needed for topology related things
10!> \par History
11!> jgh (23-05-2004) Last atom of molecule information added
12! **************************************************************************************************
26 USE input_constants, ONLY: do_fist,&
34 USE kinds, ONLY: default_string_length,&
35 dp
41 USE molecule_types, ONLY: get_molecule,&
45 USE physcon, ONLY: massunit
47 USE string_table, ONLY: id2str,&
48 s2s,&
49 str2id
55#include "./base/base_uses.f90"
56
57 IMPLICIT NONE
58
59 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'topology_coordinate_util'
60
61 PRIVATE
63
64CONTAINS
65
66! **************************************************************************************************
67!> \brief Take info readin from different file format and stuff it into
68!> compatible data structure in cp2k
69!> \param particle_set ...
70!> \param atomic_kind_set ...
71!> \param molecule_kind_set ...
72!> \param molecule_set ...
73!> \param topology ...
74!> \param qmmm ...
75!> \param qmmm_env ...
76!> \param subsys_section ...
77!> \param force_env_section ...
78!> \param exclusions ...
79!> \param ignore_outside_box ...
80!> \par History
81!> Teodoro Laino - modified in order to optimize the list of molecules
82!> to build the exclusion lists
83! **************************************************************************************************
84 SUBROUTINE topology_coordinate_pack(particle_set, atomic_kind_set, &
85 molecule_kind_set, molecule_set, topology, qmmm, qmmm_env, &
86 subsys_section, force_env_section, exclusions, ignore_outside_box)
87 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
88 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
89 TYPE(molecule_kind_type), DIMENSION(:), POINTER :: molecule_kind_set
90 TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
91 TYPE(topology_parameters_type), INTENT(INOUT) :: topology
92 LOGICAL, INTENT(IN), OPTIONAL :: qmmm
93 TYPE(qmmm_env_mm_type), OPTIONAL, POINTER :: qmmm_env
94 TYPE(section_vals_type), POINTER :: subsys_section, force_env_section
95 TYPE(exclusion_type), DIMENSION(:), OPTIONAL, &
96 POINTER :: exclusions
97 LOGICAL, INTENT(IN), OPTIONAL :: ignore_outside_box
98
99 CHARACTER(len=*), PARAMETER :: routinen = 'topology_coordinate_pack'
100
101 CHARACTER(LEN=default_string_length) :: atmname, err
102 INTEGER :: atom_i, atom_j, counter, dim0, dim1, &
103 dim2, dim3, first, handle, handle2, i, &
104 iatom, ikind, iw, j, k, last, &
105 method_name_id, n, natom
106 INTEGER, DIMENSION(:), POINTER :: iatomlist, id_element, id_work, kind_of, &
107 list, list2, molecule_list, &
108 natom_of_kind, wlist
109 INTEGER, DIMENSION(:, :), POINTER :: pairs
110 LOGICAL :: autogen, check, disable_exclusion_lists, do_center, explicit, found, &
111 my_ignore_outside_box, my_qmmm, present_12_excl_ei_list, present_12_excl_vdw_list
112 REAL(kind=dp) :: bounds(2, 3), cdims(3), dims(3), qeff, &
113 vec(3)
114 REAL(kind=dp), DIMENSION(:), POINTER :: charge, cpoint, mass
115 TYPE(array1_list_type), DIMENSION(:), POINTER :: ex_bend_list, ex_bond_list, &
116 ex_bond_list_ei, ex_bond_list_vdw, &
117 ex_onfo_list
118 TYPE(atom_info_type), POINTER :: atom_info
119 TYPE(atom_type), DIMENSION(:), POINTER :: atom_list
120 TYPE(atomic_kind_type), POINTER :: atomic_kind
121 TYPE(connectivity_info_type), POINTER :: conn_info
122 TYPE(cp_logger_type), POINTER :: logger
123 TYPE(fist_potential_type), POINTER :: fist_potential
124 TYPE(molecule_kind_type), POINTER :: molecule_kind
125 TYPE(molecule_type), POINTER :: molecule
126 TYPE(section_vals_type), POINTER :: exclude_section, topology_section
127
128 NULLIFY (logger)
129 logger => cp_get_default_logger()
130 iw = cp_print_key_unit_nr(logger, subsys_section, "PRINT%TOPOLOGY_INFO/UTIL_INFO", &
131 extension=".subsysLog")
132 topology_section => section_vals_get_subs_vals(subsys_section, "TOPOLOGY")
133 CALL timeset(routinen, handle)
134
135 my_qmmm = .false.
136 IF (PRESENT(qmmm) .AND. PRESENT(qmmm_env)) my_qmmm = qmmm
137 atom_info => topology%atom_info
138 conn_info => topology%conn_info
139 !-----------------------------------------------------------------------------
140 !-----------------------------------------------------------------------------
141 ! 1. Determine topology%[natom_type,atom_names] and save mass(natom_type)
142 ! and element(natom_type)
143 !-----------------------------------------------------------------------------
144 CALL timeset(routinen//'_1', handle2)
145 counter = 0
146 NULLIFY (id_work, mass, id_element, charge)
147 ALLOCATE (id_work(topology%natoms))
148 ALLOCATE (mass(topology%natoms))
149 ALLOCATE (id_element(topology%natoms))
150 ALLOCATE (charge(topology%natoms))
151 id_work = str2id(s2s(""))
152 IF (iw > 0) WRITE (iw, *) "molecule_kind_set ::", SIZE(molecule_kind_set)
153 DO i = 1, SIZE(molecule_kind_set)
154 j = molecule_kind_set(i)%molecule_list(1)
155 molecule => molecule_set(j)
156 molecule_kind => molecule_set(j)%molecule_kind
157 IF (iw > 0) WRITE (iw, *) "molecule number ::", j, " has molecule kind number ::", i
158 CALL get_molecule_kind(molecule_kind=molecule_kind, &
159 natom=natom, atom_list=atom_list)
160 CALL get_molecule(molecule=molecule, &
161 first_atom=first, last_atom=last)
162 IF (iw > 0) WRITE (iw, *) "boundaries of molecules (first, last) ::", first, last
163 DO j = 1, natom
164 IF (.NOT. any(id_work(1:counter) == atom_list(j)%id_name)) THEN
165 counter = counter + 1
166 id_work(counter) = atom_list(j)%id_name
167 mass(counter) = atom_info%atm_mass(first + j - 1)
168 id_element(counter) = atom_info%id_element(first + j - 1)
169 charge(counter) = atom_info%atm_charge(first + j - 1)
170 IF (iw > 0) WRITE (iw, '(7X,A,1X,A5,F10.5,5X,A2,5X,F10.5)') &
171 "NEW ATOMIC KIND", id2str(id_work(counter)), mass(counter), id2str(id_element(counter)), charge(counter)
172 ELSE
173 found = .false.
174 DO k = 1, counter
175 IF ((id_work(k) == atom_list(j)%id_name) .AND. (charge(k) == atom_info%atm_charge(first + j - 1))) THEN
176 found = .true.
177 EXIT
178 END IF
179 END DO
180 IF (.NOT. found) THEN
181 counter = counter + 1
182 id_work(counter) = atom_list(j)%id_name
183 mass(counter) = atom_info%atm_mass(first + j - 1)
184 id_element(counter) = atom_info%id_element(first + j - 1)
185 charge(counter) = atom_info%atm_charge(first + j - 1)
186 IF (iw > 0) WRITE (iw, '(7X,A,1X,A5,F10.5,5X,A2,5X,F10.5)') &
187 "NEW ATOMIC KIND", id2str(id_work(counter)), mass(counter), id2str(id_element(counter)), charge(counter)
188 END IF
189 END IF
190 END DO
191 END DO
192 topology%natom_type = counter
193 ALLOCATE (atom_info%id_atom_names(topology%natom_type))
194 DO k = 1, counter
195 atom_info%id_atom_names(k) = id_work(k)
196 END DO
197 DEALLOCATE (id_work)
198 CALL reallocate(mass, 1, counter)
199 CALL reallocate(id_element, 1, counter)
200 CALL reallocate(charge, 1, counter)
201 IF (iw > 0) THEN
202 WRITE (iw, '(5X,A,I3)') "Total Number of Atomic Kinds = ", topology%natom_type
203 END IF
204 CALL timestop(handle2)
205
206 !-----------------------------------------------------------------------------
207 !-----------------------------------------------------------------------------
208 ! 2. Allocate the data structure for the atomic kind information
209 !-----------------------------------------------------------------------------
210 CALL timeset(routinen//'_2', handle2)
211 NULLIFY (atomic_kind_set)
212 ALLOCATE (atomic_kind_set(topology%natom_type))
213 CALL timestop(handle2)
214
215 !-----------------------------------------------------------------------------
216 !-----------------------------------------------------------------------------
217 ! 3. Allocate the data structure for the atomic information
218 !-----------------------------------------------------------------------------
219 CALL timeset(routinen//'_3', handle2)
220 NULLIFY (particle_set)
221 CALL allocate_particle_set(particle_set, topology%natoms)
222 CALL timestop(handle2)
223
224 !-----------------------------------------------------------------------------
225 !-----------------------------------------------------------------------------
226 ! 4. Set the atomic_kind_set(ikind)%[name,kind_number,mass]
227 !-----------------------------------------------------------------------------
228 CALL timeset(routinen//'_4', handle2)
229 DO i = 1, topology%natom_type
230 atomic_kind => atomic_kind_set(i)
231 mass(i) = mass(i)*massunit
232 CALL set_atomic_kind(atomic_kind=atomic_kind, &
233 kind_number=i, &
234 name=id2str(atom_info%id_atom_names(i)), &
235 element_symbol=id2str(id_element(i)), &
236 mass=mass(i))
237 IF (iw > 0) THEN
238 WRITE (iw, '(A,I5,A,I5,4A)') "Atomic Kind n.:", i, " out of:", topology%natom_type, &
239 " name: ", trim(id2str(atom_info%id_atom_names(i))), " element: ", &
240 trim(id2str(id_element(i)))
241 END IF
242 END DO
243 DEALLOCATE (mass)
244 DEALLOCATE (id_element)
245 CALL timestop(handle2)
246
247 !-----------------------------------------------------------------------------
248 !-----------------------------------------------------------------------------
249 ! 5. Determine number of atom of each kind (ie natom_of_kind and kind_of)
250 !-----------------------------------------------------------------------------
251 CALL timeset(routinen//'_5', handle2)
252 ALLOCATE (kind_of(topology%natoms))
253 ALLOCATE (natom_of_kind(topology%natom_type))
254 kind_of(:) = 0
255 natom_of_kind(:) = 0
256 DO i = 1, topology%natom_type
257 DO j = 1, topology%natoms
258 IF ((atom_info%id_atom_names(i) == atom_info%id_atmname(j)) .AND. (charge(i) == atom_info%atm_charge(j))) THEN
259 natom_of_kind(i) = natom_of_kind(i) + 1
260 IF (kind_of(j) == 0) kind_of(j) = i
261 END IF
262 END DO
263 END DO
264 IF (any(kind_of == 0)) THEN
265 DO i = 1, topology%natoms
266 IF (kind_of(i) == 0) THEN
267 WRITE (err, "(1X,I5)") i
268 END IF
269 END DO
270 CALL cp_abort(__location__, &
271 "Two molecules have been defined as identical molecules but atoms "// &
272 "mismatch charges! Check these atoms:"//trim(err))
273 END IF
274 CALL timestop(handle2)
275
276 !-----------------------------------------------------------------------------
277 !-----------------------------------------------------------------------------
278 ! 6. Set the atom_kind_set(ikind)%[natom,atom_list]
279 !-----------------------------------------------------------------------------
280 CALL timeset(routinen//'_6', handle2)
281 DO i = 1, topology%natom_type
282 atomic_kind => atomic_kind_set(i)
283 NULLIFY (iatomlist)
284 ALLOCATE (iatomlist(natom_of_kind(i)))
285 counter = 0
286 DO j = 1, topology%natoms
287 IF (kind_of(j) == i) THEN
288 counter = counter + 1
289 iatomlist(counter) = j
290 END IF
291 END DO
292 IF (iw > 0) THEN
293 WRITE (iw, '(A,I6,A)') " Atomic kind ", i, " contains particles"
294 DO j = 1, SIZE(iatomlist)
295 IF (mod(j, 5) == 0) THEN ! split long lines
296 WRITE (iw, '(I12)') iatomlist(j)
297 ELSE
298 WRITE (iw, '(I12)', advance="NO") iatomlist(j)
299 END IF
300 END DO
301 WRITE (iw, *)
302 END IF
303 CALL set_atomic_kind(atomic_kind=atomic_kind, &
304 natom=natom_of_kind(i), &
305 atom_list=iatomlist)
306 DEALLOCATE (iatomlist)
307 END DO
308 DEALLOCATE (natom_of_kind)
309 CALL timestop(handle2)
310
311 !-----------------------------------------------------------------------------
312 !-----------------------------------------------------------------------------
313 ! 7. Possibly center the coordinates and fill in coordinates in particle_set
314 !-----------------------------------------------------------------------------
315 CALL section_vals_val_get(subsys_section, &
316 "TOPOLOGY%CENTER_COORDINATES%_SECTION_PARAMETERS_", l_val=do_center)
317 CALL timeset(routinen//'_7a', handle2)
318 bounds(1, 1) = minval(atom_info%r(1, :))
319 bounds(2, 1) = maxval(atom_info%r(1, :))
320
321 bounds(1, 2) = minval(atom_info%r(2, :))
322 bounds(2, 2) = maxval(atom_info%r(2, :))
323
324 bounds(1, 3) = minval(atom_info%r(3, :))
325 bounds(2, 3) = maxval(atom_info%r(3, :))
326
327 dims = bounds(2, :) - bounds(1, :)
328 cdims(1) = topology%cell%hmat(1, 1)
329 cdims(2) = topology%cell%hmat(2, 2)
330 cdims(3) = topology%cell%hmat(3, 3)
331 IF (iw > 0) THEN
332 WRITE (iw, '(A,3F12.6)') "System sizes: ", dims, "Cell sizes (diagonal): ", cdims
333 END IF
334 check = .true.
335 DO i = 1, 3
336 IF (topology%cell%perd(i) == 0) THEN
337 check = check .AND. (dims(i) < cdims(i))
338 END IF
339 END DO
340 my_ignore_outside_box = .false.
341 IF (PRESENT(ignore_outside_box)) my_ignore_outside_box = ignore_outside_box
342 IF (.NOT. my_ignore_outside_box .AND. .NOT. check) THEN
343 CALL cp_abort(__location__, &
344 "A non-periodic calculation has been requested but the system size "// &
345 "exceeds the cell size in at least one of the non-periodic directions!")
346 END IF
347 IF (do_center) THEN
348 CALL section_vals_val_get(subsys_section, &
349 "TOPOLOGY%CENTER_COORDINATES%CENTER_POINT", explicit=explicit)
350 IF (explicit) THEN
351 CALL section_vals_val_get(subsys_section, &
352 "TOPOLOGY%CENTER_COORDINATES%CENTER_POINT", r_vals=cpoint)
353 vec = cpoint
354 ELSE
355 vec = cdims/2.0_dp
356 END IF
357 dims = (bounds(2, :) + bounds(1, :))/2.0_dp - vec
358 ELSE
359 dims = 0.0_dp
360 END IF
361 CALL timestop(handle2)
362 CALL timeset(routinen//'_7b', handle2)
363 DO i = 1, topology%natoms
364 ikind = kind_of(i)
365 IF (iw > 0) THEN
366 WRITE (iw, *) "atom number :: ", i, "kind number ::", ikind
367 END IF
368 particle_set(i)%atomic_kind => atomic_kind_set(ikind)
369 particle_set(i)%r(:) = atom_info%r(:, i) - dims
370 particle_set(i)%atom_index = i
371 END DO
372 CALL timestop(handle2)
373 DEALLOCATE (kind_of)
374
375 !-----------------------------------------------------------------------------
376 !-----------------------------------------------------------------------------
377 ! 8. Fill in the exclusions%list_exclude_vdw
378 ! 9. Fill in the exclusions%list_exclude_ei
379 ! 10. Fill in the exclusions%list_onfo
380 !-----------------------------------------------------------------------------
381 CALL timeset(routinen//'_89', handle2)
382 CALL section_vals_val_get(force_env_section, "METHOD", i_val=method_name_id)
383 CALL section_vals_val_get(subsys_section, "TOPOLOGY%DISABLE_EXCLUSION_LISTS", &
384 l_val=disable_exclusion_lists)
385 IF ((method_name_id == do_fist) .AND. (.NOT. disable_exclusion_lists)) THEN
386 cpassert(PRESENT(exclusions))
387 natom = topology%natoms
388 ! allocate exclusions. Most likely they would only be needed for the local_particles
389 ALLOCATE (exclusions(natom))
390 DO i = 1, natom
391 NULLIFY (exclusions(i)%list_exclude_vdw)
392 NULLIFY (exclusions(i)%list_exclude_ei)
393 NULLIFY (exclusions(i)%list_onfo)
394 END DO
395 ! Reorder bonds
396 ALLOCATE (ex_bond_list(natom))
397 DO i = 1, natom
398 ALLOCATE (ex_bond_list(i)%array1(0))
399 END DO
400 n = 0
401 IF (ASSOCIATED(conn_info%bond_a)) THEN
402 n = SIZE(conn_info%bond_a)
403 CALL reorder_structure(ex_bond_list, conn_info%bond_a, conn_info%bond_b, n)
404 END IF
405
406 ! Check if a list of 1-2 exclusion bonds is defined.. if not use all bonds
407 NULLIFY (ex_bond_list_vdw, ex_bond_list_ei)
408 ! VdW
409 exclude_section => section_vals_get_subs_vals(topology_section, "EXCLUDE_VDW_LIST")
410 CALL section_vals_get(exclude_section, explicit=explicit)
411 present_12_excl_vdw_list = .false.
412 IF (explicit) present_12_excl_vdw_list = .true.
413 IF (present_12_excl_vdw_list) THEN
414 ALLOCATE (ex_bond_list_vdw(natom))
415 DO i = 1, natom
416 ALLOCATE (ex_bond_list_vdw(i)%array1(0))
417 END DO
418 CALL setup_exclusion_list(exclude_section, "BOND", ex_bond_list, ex_bond_list_vdw, &
419 particle_set)
420 ELSE
421 ex_bond_list_vdw => ex_bond_list
422 END IF
423 ! EI
424 exclude_section => section_vals_get_subs_vals(topology_section, "EXCLUDE_EI_LIST")
425 CALL section_vals_get(exclude_section, explicit=explicit)
426 present_12_excl_ei_list = .false.
427 IF (explicit) present_12_excl_ei_list = .true.
428 IF (present_12_excl_ei_list) THEN
429 ALLOCATE (ex_bond_list_ei(natom))
430 DO i = 1, natom
431 ALLOCATE (ex_bond_list_ei(i)%array1(0))
432 END DO
433 CALL setup_exclusion_list(exclude_section, "BOND", ex_bond_list, ex_bond_list_ei, &
434 particle_set)
435 ELSE
436 ex_bond_list_ei => ex_bond_list
437 END IF
438
439 CALL section_vals_val_get(topology_section, "AUTOGEN_EXCLUDE_LISTS", &
440 l_val=autogen)
441 ! Reorder bends
442 ALLOCATE (ex_bend_list(natom))
443 DO i = 1, natom
444 ALLOCATE (ex_bend_list(i)%array1(0))
445 END DO
446 IF (autogen) THEN
447 ! Construct autogenerated 1-3 pairs, i.e. all possible 1-3 pairs instead
448 ! of only the bends that are present in the topology.
449 ALLOCATE (pairs(0, 2))
450 n = 0
451 DO iatom = 1, natom
452 DO i = 1, SIZE(ex_bond_list(iatom)%array1)
453 ! a neighboring atom of iatom:
454 atom_i = ex_bond_list(iatom)%array1(i)
455 DO j = 1, i - 1
456 ! another neighboring atom of iatom
457 atom_j = ex_bond_list(iatom)%array1(j)
458 ! It is only a true bend if there is no shorter path.
459 ! No need to check if i and j correspond to the same atom.
460 ! Check if i and j are not involved in a bond:
461 check = .false.
462 DO counter = 1, SIZE(ex_bond_list(atom_i)%array1)
463 IF (ex_bond_list(atom_i)%array1(counter) == atom_j) THEN
464 check = .true.
465 EXIT
466 END IF
467 END DO
468 IF (check) cycle
469 ! Add the genuine 1-3 pair
470 n = n + 1
471 IF (SIZE(pairs, dim=1) <= n) THEN
472 CALL reallocate(pairs, 1, n + 5, 1, 2)
473 END IF
474 pairs(n, 1) = atom_i
475 pairs(n, 2) = atom_j
476 END DO
477 END DO
478 END DO
479 CALL reorder_structure(ex_bend_list, pairs(:, 1), pairs(:, 2), n)
480 DEALLOCATE (pairs)
481 ELSE
482 IF (ASSOCIATED(conn_info%theta_a)) THEN
483 n = SIZE(conn_info%theta_a)
484 CALL reorder_structure(ex_bend_list, conn_info%theta_a, conn_info%theta_c, n)
485 END IF
486 END IF
487
488 ! Reorder onfo
489 ALLOCATE (ex_onfo_list(natom))
490 DO i = 1, natom
491 ALLOCATE (ex_onfo_list(i)%array1(0))
492 END DO
493 IF (autogen) THEN
494 ! Construct autogenerated 1-4 pairs, i.e. all possible 1-4 pairs instead
495 ! of only the onfo's that are present in the topology.
496 ALLOCATE (pairs(0, 2))
497 n = 0
498 DO iatom = 1, natom
499 DO i = 1, SIZE(ex_bond_list(iatom)%array1)
500 ! a neighboring atom of iatom:
501 atom_i = ex_bond_list(iatom)%array1(i)
502 DO j = 1, SIZE(ex_bend_list(iatom)%array1)
503 ! a next neighboring atom of iatom:
504 atom_j = ex_bend_list(iatom)%array1(j)
505 ! It is only a true onfo if there is no shorter path.
506 ! check if i and j are not the same atom
507 IF (atom_i == atom_j) cycle
508 ! check if i and j are not involved in a bond
509 check = .false.
510 DO counter = 1, SIZE(ex_bond_list(atom_i)%array1)
511 IF (ex_bond_list(atom_i)%array1(counter) == atom_j) THEN
512 check = .true.
513 EXIT
514 END IF
515 END DO
516 IF (check) cycle
517 ! check if i and j are not involved in a bend
518 check = .false.
519 DO counter = 1, SIZE(ex_bend_list(atom_i)%array1)
520 IF (ex_bend_list(atom_i)%array1(counter) == atom_j) THEN
521 check = .true.
522 EXIT
523 END IF
524 END DO
525 IF (check) cycle
526 ! Add the true onfo.
527 n = n + 1
528 IF (SIZE(pairs, dim=1) <= n) THEN
529 CALL reallocate(pairs, 1, n + 5, 1, 2)
530 END IF
531 pairs(n, 1) = atom_i
532 pairs(n, 2) = atom_j
533 END DO
534 END DO
535 END DO
536 CALL reorder_structure(ex_onfo_list, pairs(:, 1), pairs(:, 2), n)
537 DEALLOCATE (pairs)
538 ELSE
539 IF (ASSOCIATED(conn_info%onfo_a)) THEN
540 n = SIZE(conn_info%onfo_a)
541 CALL reorder_structure(ex_onfo_list, conn_info%onfo_a, conn_info%onfo_b, n)
542 END IF
543 END IF
544
545 ! Build the exclusion (and onfo) list per atom.
546 DO iatom = 1, SIZE(particle_set)
547 ! Setup exclusion list for VDW: always exclude itself
548 dim0 = 1
549 ! exclude bond-neighbors (only if do_skip_12 .OR. do_skip_13 .OR. do_skip_14)
550 dim1 = 0
551 IF (topology%exclude_vdw == do_skip_12 .OR. &
552 topology%exclude_vdw == do_skip_13 .OR. &
553 topology%exclude_vdw == do_skip_14) dim1 = SIZE(ex_bond_list_vdw(iatom)%array1)
554 dim1 = dim1 + dim0
555 dim2 = 0
556 IF (topology%exclude_vdw == do_skip_13 .OR. &
557 topology%exclude_vdw == do_skip_14) dim2 = SIZE(ex_bend_list(iatom)%array1)
558 dim2 = dim1 + dim2
559 dim3 = 0
560 IF (topology%exclude_vdw == do_skip_14) dim3 = SIZE(ex_onfo_list(iatom)%array1)
561 dim3 = dim2 + dim3
562 IF (dim3 /= 0) THEN
563 NULLIFY (list, wlist)
564 ALLOCATE (wlist(dim3))
565 wlist(dim0:dim0) = iatom
566 IF (dim1 > dim0) wlist(dim0 + 1:dim1) = ex_bond_list_vdw(iatom)%array1
567 IF (dim2 > dim1) wlist(dim1 + 1:dim2) = ex_bend_list(iatom)%array1
568 IF (dim3 > dim2) wlist(dim2 + 1:dim3) = ex_onfo_list(iatom)%array1
569 ! Get a unique list
570 DO i = 1, SIZE(wlist) - 1
571 IF (wlist(i) == 0) cycle
572 DO j = i + 1, SIZE(wlist)
573 IF (wlist(j) == wlist(i)) wlist(j) = 0
574 END DO
575 END DO
576 dim3 = SIZE(wlist) - count(wlist == 0)
577 ALLOCATE (list(dim3))
578 j = 0
579 DO i = 1, SIZE(wlist)
580 IF (wlist(i) == 0) cycle
581 j = j + 1
582 list(j) = wlist(i)
583 END DO
584 DEALLOCATE (wlist)
585 ! Unique list completed
586 NULLIFY (list2)
587 IF ((topology%exclude_vdw == topology%exclude_ei) .AND. &
588 (.NOT. present_12_excl_ei_list) .AND. (.NOT. present_12_excl_vdw_list)) THEN
589 list2 => list
590 ELSE
591 ! Setup exclusion list for EI : always exclude itself
592 dim0 = 1
593 ! exclude bond-neighbors (only if do_skip_12 .OR. do_skip_13 .OR. do_skip_14)
594 dim1 = 0
595 IF (topology%exclude_ei == do_skip_12 .OR. &
596 topology%exclude_ei == do_skip_13 .OR. &
597 topology%exclude_ei == do_skip_14) dim1 = SIZE(ex_bond_list_ei(iatom)%array1)
598 dim1 = dim1 + dim0
599 dim2 = 0
600 IF (topology%exclude_ei == do_skip_13 .OR. &
601 topology%exclude_ei == do_skip_14) dim2 = SIZE(ex_bend_list(iatom)%array1)
602 dim2 = dim1 + dim2
603 dim3 = 0
604 IF (topology%exclude_ei == do_skip_14) dim3 = SIZE(ex_onfo_list(iatom)%array1)
605 dim3 = dim2 + dim3
606
607 IF (dim3 /= 0) THEN
608 ALLOCATE (wlist(dim3))
609 wlist(dim0:dim0) = iatom
610 IF (dim1 > dim0) wlist(dim0 + 1:dim1) = ex_bond_list_ei(iatom)%array1
611 IF (dim2 > dim1) wlist(dim1 + 1:dim2) = ex_bend_list(iatom)%array1
612 IF (dim3 > dim2) wlist(dim2 + 1:dim3) = ex_onfo_list(iatom)%array1
613 ! Get a unique list
614 DO i = 1, SIZE(wlist) - 1
615 IF (wlist(i) == 0) cycle
616 DO j = i + 1, SIZE(wlist)
617 IF (wlist(j) == wlist(i)) wlist(j) = 0
618 END DO
619 END DO
620 dim3 = SIZE(wlist) - count(wlist == 0)
621 ALLOCATE (list2(dim3))
622 j = 0
623 DO i = 1, SIZE(wlist)
624 IF (wlist(i) == 0) cycle
625 j = j + 1
626 list2(j) = wlist(i)
627 END DO
628 DEALLOCATE (wlist)
629 ! Unique list completed
630 END IF
631 END IF
632 END IF
633 exclusions(iatom)%list_exclude_vdw => list
634 exclusions(iatom)%list_exclude_ei => list2
635 ! Keep a list of onfo atoms for proper selection of specialized 1-4
636 ! potentials instead of conventional nonbonding potentials.
637 ALLOCATE (exclusions(iatom)%list_onfo(SIZE(ex_onfo_list(iatom)%array1)))
638 ! copy of data, not copy of pointer
639 exclusions(iatom)%list_onfo = ex_onfo_list(iatom)%array1
640 IF (iw > 0) THEN
641 IF (ASSOCIATED(list)) THEN
642 WRITE (iw, *) "exclusion list_vdw :: ", &
643 "atom num :", iatom, "exclusion list ::", &
644 list
645 END IF
646 IF (topology%exclude_vdw /= topology%exclude_ei) THEN
647 IF (ASSOCIATED(list2)) THEN
648 WRITE (iw, *) "exclusion list_ei :: ", &
649 "atom num :", iatom, "exclusion list ::", &
650 list2
651 END IF
652 END IF
653 IF (ASSOCIATED(exclusions(iatom)%list_onfo)) THEN
654 WRITE (iw, *) "onfo list :: ", &
655 "atom num :", iatom, "onfo list ::", &
656 exclusions(iatom)%list_onfo
657 END IF
658 END IF
659 END DO
660 ! deallocate onfo
661 DO i = 1, natom
662 DEALLOCATE (ex_onfo_list(i)%array1)
663 END DO
664 DEALLOCATE (ex_onfo_list)
665 ! deallocate bends
666 DO i = 1, natom
667 DEALLOCATE (ex_bend_list(i)%array1)
668 END DO
669 DEALLOCATE (ex_bend_list)
670 ! deallocate bonds
671 IF (present_12_excl_ei_list) THEN
672 DO i = 1, natom
673 DEALLOCATE (ex_bond_list_ei(i)%array1)
674 END DO
675 DEALLOCATE (ex_bond_list_ei)
676 ELSE
677 NULLIFY (ex_bond_list_ei)
678 END IF
679 IF (present_12_excl_vdw_list) THEN
680 DO i = 1, natom
681 DEALLOCATE (ex_bond_list_vdw(i)%array1)
682 END DO
683 DEALLOCATE (ex_bond_list_vdw)
684 ELSE
685 NULLIFY (ex_bond_list_vdw)
686 END IF
687 DO i = 1, natom
688 DEALLOCATE (ex_bond_list(i)%array1)
689 END DO
690 DEALLOCATE (ex_bond_list)
691 END IF
692 CALL timestop(handle2)
693 !-----------------------------------------------------------------------------
694 !-----------------------------------------------------------------------------
695 ! 11. Set the atomic_kind_set()%fist_potential%[qeff] (PART 1)
696 !-----------------------------------------------------------------------------
697 CALL timeset(routinen//'_10', handle2)
698 CALL section_vals_val_get(force_env_section, "METHOD", i_val=method_name_id)
699 IF (method_name_id == do_fist) THEN
700 DO i = 1, SIZE(atomic_kind_set)
701 atomic_kind => atomic_kind_set(i)
702 CALL get_atomic_kind(atomic_kind=atomic_kind, name=atmname)
703 qeff = charge(i)
704 NULLIFY (fist_potential)
705 CALL allocate_potential(fist_potential)
706 CALL set_potential(potential=fist_potential, qeff=qeff)
707 CALL set_atomic_kind(atomic_kind=atomic_kind, fist_potential=fist_potential)
708 END DO
709 END IF
710 DEALLOCATE (charge)
711 CALL timestop(handle2)
712
713 !-----------------------------------------------------------------------------
714 !-----------------------------------------------------------------------------
715 ! 12. Set the atom_list for molecule_kind in molecule_kind_set (PART 2)
716 !-----------------------------------------------------------------------------
717 CALL timeset(routinen//'_11', handle2)
718 DO i = 1, SIZE(molecule_kind_set)
719 molecule_kind => molecule_kind_set(i)
720 CALL get_molecule_kind(molecule_kind=molecule_kind, &
721 natom=natom, molecule_list=molecule_list, &
722 atom_list=atom_list)
723 molecule => molecule_set(molecule_list(1))
724 CALL get_molecule(molecule=molecule, &
725 first_atom=first, last_atom=last)
726 DO j = 1, natom
727 DO k = 1, SIZE(atomic_kind_set)
728 atomic_kind => atomic_kind_set(k)
729 CALL get_atomic_kind(atomic_kind=atomic_kind, name=atmname)
730 IF (method_name_id == do_fist) THEN
731 CALL get_atomic_kind(atomic_kind=atomic_kind, fist_potential=fist_potential)
732 CALL get_potential(potential=fist_potential, qeff=qeff)
733 IF ((id2str(atom_list(j)%id_name) == atmname) .AND. (qeff == atom_info%atm_charge(first + j - 1))) THEN
734 atom_list(j)%atomic_kind => atomic_kind_set(k)
735 EXIT
736 END IF
737 ELSE
738 IF (id2str(atom_list(j)%id_name) == atmname) THEN
739 atom_list(j)%atomic_kind => atomic_kind_set(k)
740 EXIT
741 END IF
742 END IF
743 END DO
744 END DO
745 CALL set_molecule_kind(molecule_kind=molecule_kind, atom_list=atom_list)
746 END DO
747 CALL timestop(handle2)
748
749 CALL timestop(handle)
750 CALL cp_print_key_finished_output(iw, logger, subsys_section, &
751 "PRINT%TOPOLOGY_INFO/UTIL_INFO")
752 END SUBROUTINE topology_coordinate_pack
753
754! **************************************************************************************************
755!> \brief Builds the exclusion list for VDW and EI if an explicit list of terms
756!> is provided by the user. Otherwise all possibilities are excluded
757!> \param exclude_section ...
758!> \param keyword ...
759!> \param ex_bond_list ...
760!> \param ex_bond_list_w ...
761!> \param particle_set ...
762!> \par History
763!> Teodoro Laino [tlaino] - 12.2009
764! **************************************************************************************************
765 SUBROUTINE setup_exclusion_list(exclude_section, keyword, ex_bond_list, &
766 ex_bond_list_w, particle_set)
767 TYPE(section_vals_type), POINTER :: exclude_section
768 CHARACTER(LEN=*), INTENT(IN) :: keyword
769 TYPE(array1_list_type), DIMENSION(:), POINTER :: ex_bond_list, ex_bond_list_w
770 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
771
772 CHARACTER(LEN=default_string_length) :: flag1, flag2
773 CHARACTER(LEN=default_string_length), &
774 DIMENSION(:), POINTER :: names
775 INTEGER :: i, ind, j, k, l, m, n_rep
776
777 cpassert(ASSOCIATED(ex_bond_list))
778 cpassert(ASSOCIATED(ex_bond_list_w))
779 SELECT CASE (keyword)
780 CASE ("BOND")
781 CALL section_vals_val_get(exclude_section, keyword, n_rep_val=n_rep)
782 DO j = 1, SIZE(ex_bond_list)
783 cpassert(ASSOCIATED(ex_bond_list(j)%array1))
784 cpassert(ASSOCIATED(ex_bond_list_w(j)%array1))
785
786 flag1 = particle_set(j)%atomic_kind%name
787 m = SIZE(ex_bond_list(j)%array1)
788 CALL reallocate(ex_bond_list_w(j)%array1, 1, m)
789
790 l = 0
791 DO k = 1, m
792 ind = ex_bond_list(j)%array1(k)
793 flag2 = particle_set(ind)%atomic_kind%name
794 DO i = 1, n_rep
795 CALL section_vals_val_get(exclude_section, keyword, i_rep_val=i, &
796 c_vals=names)
797 IF (((trim(names(1)) == trim(flag1)) .AND. (trim(names(2)) == trim(flag2))) .OR. &
798 ((trim(names(1)) == trim(flag2)) .AND. (trim(names(2)) == trim(flag1)))) THEN
799 l = l + 1
800 ex_bond_list_w(j)%array1(l) = ind
801 END IF
802 END DO
803 END DO
804 CALL reallocate(ex_bond_list_w(j)%array1, 1, l)
805 END DO
806 CASE DEFAULT
807 CALL cp_abort(__location__, &
808 "<BOND> is supported as the <keyword> for "// &
809 "setup_exclusion_list, found unknown option "// &
810 "<"//trim(keyword)//">")
811 END SELECT
812
813 END SUBROUTINE setup_exclusion_list
814
Define the atomic kind types and their sub types.
subroutine, public set_atomic_kind(atomic_kind, element_symbol, name, mass, kind_number, natom, atom_list, fist_potential, shell, shell_active, damping)
Set the components of an atomic kind data set.
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.
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
an exclusion type
Definition of the atomic potential types.
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_skip_13
integer, parameter, public do_fist
integer, parameter, public do_skip_12
integer, parameter, public do_skip_14
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_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
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
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition list.F:24
Utility routines for the memory handling.
Define the molecule kind structure types and the corresponding functionality.
subroutine, public get_molecule_kind(molecule_kind, atom_list, bond_list, bend_list, ub_list, impr_list, opbend_list, colv_list, fixd_list, g3x3_list, g4x6_list, vsite_list, torsion_list, shell_list, name, mass, charge, kind_number, natom, nbend, nbond, nub, nimpr, nopbend, nconstraint, nconstraint_fixd, nfixd, ncolv, ng3x3, ng4x6, nvsite, nfixd_restraint, ng3x3_restraint, ng4x6_restraint, nvsite_restraint, nrestraints, nmolecule, nsgf, nshell, ntorsion, molecule_list, nelectron, nelectron_alpha, nelectron_beta, bond_kind_set, bend_kind_set, ub_kind_set, impr_kind_set, opbend_kind_set, torsion_kind_set, molname_generated)
Get informations about a molecule kind.
subroutine, public set_molecule_kind(molecule_kind, name, mass, charge, kind_number, molecule_list, atom_list, nbond, bond_list, nbend, bend_list, nub, ub_list, nimpr, impr_list, nopbend, opbend_list, ntorsion, torsion_list, fixd_list, ncolv, colv_list, ng3x3, g3x3_list, ng4x6, nfixd, g4x6_list, nvsite, vsite_list, ng3x3_restraint, ng4x6_restraint, nfixd_restraint, nshell, shell_list, nvsite_restraint, bond_kind_set, bend_kind_set, ub_kind_set, torsion_kind_set, impr_kind_set, opbend_kind_set, nelectron, nsgf, molname_generated)
Set the components of a molecule kind.
Define the data structure for the molecule information.
subroutine, public get_molecule(molecule, molecule_kind, lmi, lci, lg3x3, lg4x6, lcolv, first_atom, last_atom, first_shell, last_shell)
Get components from a molecule data set.
Define the data structure for the particle information.
subroutine, public allocate_particle_set(particle_set, nparticle)
Allocate a particle set.
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public massunit
Definition physcon.F:141
generates a unique id number for a string (str2id) that can be used two compare two strings....
character(len=default_string_length) function, public s2s(str)
converts a string in a string of default_string_length
integer function, public str2id(str)
returns a unique id for a given string, and stores the string for later retrieval using the id.
character(len=default_string_length) function, public id2str(id)
returns the string associated with a given id
Collection of subroutine needed for topology related things.
subroutine, public topology_coordinate_pack(particle_set, atomic_kind_set, molecule_kind_set, molecule_set, topology, qmmm, qmmm_env, subsys_section, force_env_section, exclusions, ignore_outside_box)
Take info readin from different file format and stuff it into compatible data structure in cp2k.
Collection of subroutine needed for topology related things.
Control for reading in different topologies and coordinates.
Definition topology.F:13
Provides all information about an atomic kind.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
A type used to store lists of exclusions and onfos.