Line data Source code
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 : !> \par History
10 : !> Harald Forbert (Dec-2000): Changes for multiple linked lists
11 : !> linklist_internal_data_type
12 : !> 07.02.2005: using real coordinates for r_last_update; cleaned (MK)
13 : !> \author CJM,MK
14 : ! **************************************************************************************************
15 : MODULE fist_neighbor_list_control
16 :
17 : USE atomic_kind_types, ONLY: atomic_kind_type,&
18 : get_atomic_kind_set
19 : USE cell_methods, ONLY: cell_create
20 : USE cell_types, ONLY: cell_clone,&
21 : cell_release,&
22 : cell_type,&
23 : pbc,&
24 : real_to_scaled,&
25 : scaled_to_real
26 : USE cp_log_handling, ONLY: cp_get_default_logger,&
27 : cp_logger_type
28 : USE cp_output_handling, ONLY: cp_print_key_finished_output,&
29 : cp_print_key_unit_nr
30 : USE distribution_1d_types, ONLY: distribution_1d_type
31 : USE exclusion_types, ONLY: exclusion_type
32 : USE fist_neighbor_list_types, ONLY: fist_neighbor_type
33 : USE fist_neighbor_lists, ONLY: build_fist_neighbor_lists
34 : USE fist_nonbond_env_types, ONLY: fist_nonbond_env_get,&
35 : fist_nonbond_env_set,&
36 : fist_nonbond_env_type,&
37 : pos_type
38 : USE input_section_types, ONLY: section_vals_type,&
39 : section_vals_val_get
40 : USE kinds, ONLY: dp
41 : USE message_passing, ONLY: mp_para_env_type
42 : USE pair_potential_types, ONLY: allegro_type,&
43 : gal21_type,&
44 : gal_type,&
45 : nequip_type,&
46 : pair_potential_pp_type,&
47 : siepmann_type,&
48 : tersoff_type
49 : USE particle_types, ONLY: particle_type
50 : #include "./base/base_uses.f90"
51 :
52 : IMPLICIT NONE
53 :
54 : PRIVATE
55 :
56 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'fist_neighbor_list_control'
57 :
58 : PUBLIC :: list_control
59 :
60 : !***
61 :
62 : CONTAINS
63 :
64 : ! to decide whether the neighbor list is to be updated or not
65 : ! based on a displacement criterion;
66 : ! if any particle has moved by 0.5*verlet_skin from the previous
67 : ! list update, then the list routine is called.
68 :
69 : ! **************************************************************************************************
70 : !> \brief ...
71 : !> \param atomic_kind_set ...
72 : !> \param particle_set ...
73 : !> \param local_particles ...
74 : !> \param cell ...
75 : !> \param fist_nonbond_env ...
76 : !> \param para_env ...
77 : !> \param mm_section ...
78 : !> \param shell_particle_set ...
79 : !> \param core_particle_set ...
80 : !> \param force_update ...
81 : !> \param exclusions ...
82 : ! **************************************************************************************************
83 412055 : SUBROUTINE list_control(atomic_kind_set, particle_set, local_particles, &
84 : cell, fist_nonbond_env, para_env, mm_section, shell_particle_set, &
85 82411 : core_particle_set, force_update, exclusions)
86 :
87 : TYPE(atomic_kind_type), POINTER :: atomic_kind_set(:)
88 : TYPE(particle_type), POINTER :: particle_set(:)
89 : TYPE(distribution_1d_type), POINTER :: local_particles
90 : TYPE(cell_type), POINTER :: cell
91 : TYPE(fist_nonbond_env_type), POINTER :: fist_nonbond_env
92 : TYPE(mp_para_env_type), POINTER :: para_env
93 : TYPE(section_vals_type), POINTER :: mm_section
94 : TYPE(particle_type), OPTIONAL, POINTER :: shell_particle_set(:), &
95 : core_particle_set(:)
96 : LOGICAL, INTENT(IN), OPTIONAL :: force_update
97 : TYPE(exclusion_type), DIMENSION(:), OPTIONAL :: exclusions
98 :
99 : CHARACTER(LEN=*), PARAMETER :: routineN = 'list_control'
100 :
101 : INTEGER :: counter, handle, ikind, iparticle, iparticle_kind, iparticle_local, ishell, &
102 : jkind, last_update, nparticle, nparticle_kind, nparticle_local, nshell, num_update, &
103 : output_unit
104 : LOGICAL :: build_from_scratch, geo_check, &
105 : shell_adiabatic, shell_present, &
106 : update_neighbor_lists
107 82411 : LOGICAL, DIMENSION(:, :), POINTER :: full_nl
108 : REAL(KIND=dp) :: aup, dr2, dr2_max, ei_scale14, lup, &
109 : vdw_scale14, verlet_skin
110 : REAL(KIND=dp), DIMENSION(3) :: dr, rab, rab_last_update, s, s2r
111 82411 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: rlist_cut, rlist_lowsq
112 : TYPE(cell_type), POINTER :: cell_last_update
113 : TYPE(cp_logger_type), POINTER :: logger
114 : TYPE(fist_neighbor_type), POINTER :: nonbonded
115 : TYPE(pair_potential_pp_type), POINTER :: potparm
116 82411 : TYPE(pos_type), DIMENSION(:), POINTER :: r_last_update, r_last_update_pbc, &
117 82411 : rcore_last_update_pbc, &
118 82411 : rshell_last_update_pbc
119 :
120 82411 : CALL timeset(routineN, handle)
121 82411 : NULLIFY (logger)
122 82411 : logger => cp_get_default_logger()
123 :
124 : ! *** Assigning local pointers ***
125 : CALL fist_nonbond_env_get(fist_nonbond_env, &
126 : nonbonded=nonbonded, &
127 : rlist_cut=rlist_cut, &
128 : rlist_lowsq=rlist_lowsq, &
129 : aup=aup, &
130 : lup=lup, &
131 : ei_scale14=ei_scale14, &
132 : vdw_scale14=vdw_scale14, &
133 : counter=counter, &
134 : r_last_update=r_last_update, &
135 : r_last_update_pbc=r_last_update_pbc, &
136 : rshell_last_update_pbc=rshell_last_update_pbc, &
137 : rcore_last_update_pbc=rcore_last_update_pbc, &
138 : cell_last_update=cell_last_update, &
139 : num_update=num_update, &
140 : potparm=potparm, &
141 82411 : last_update=last_update)
142 :
143 82411 : nparticle = SIZE(particle_set)
144 82411 : nparticle_kind = SIZE(atomic_kind_set)
145 82411 : nshell = 0
146 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
147 82411 : shell_present=shell_present, shell_adiabatic=shell_adiabatic)
148 82411 : IF (shell_present) THEN
149 9344 : nshell = SIZE(shell_particle_set)
150 : END IF
151 :
152 : ! *** Check, if the neighbor lists have to be built or updated ***
153 82411 : update_neighbor_lists = .FALSE.
154 : CALL section_vals_val_get(mm_section, "NEIGHBOR_LISTS%NEIGHBOR_LISTS_FROM_SCRATCH", &
155 82411 : l_val=build_from_scratch)
156 : CALL section_vals_val_get(mm_section, "NEIGHBOR_LISTS%GEO_CHECK", &
157 82411 : l_val=geo_check)
158 82411 : IF (ASSOCIATED(r_last_update)) THEN
159 : ! Determine the maximum of the squared displacement, compared to
160 : ! r_last_update.
161 : CALL section_vals_val_get(mm_section, "NEIGHBOR_LISTS%VERLET_SKIN", &
162 79910 : r_val=verlet_skin)
163 79910 : dr2_max = 0.0_dp
164 303864 : DO iparticle_kind = 1, nparticle_kind
165 223954 : nparticle_local = local_particles%n_el(iparticle_kind)
166 4623641 : DO iparticle_local = 1, nparticle_local
167 4319777 : iparticle = local_particles%list(iparticle_kind)%array(iparticle_local)
168 17279108 : s2r = r_last_update(iparticle)%r
169 17279108 : s = particle_set(iparticle)%r(:)
170 17279108 : dr(:) = s2r - s
171 4319777 : dr2 = dr(1)*dr(1) + dr(2)*dr(2) + dr(3)*dr(3)
172 4543731 : dr2_max = MAX(dr2_max, dr2)
173 : END DO
174 : END DO
175 :
176 79910 : CALL para_env%max(dr2_max)
177 :
178 : ! If the maximum distplacement is too large, ...
179 79910 : IF (dr2_max > 0.25_dp*verlet_skin**2 .OR. build_from_scratch) THEN
180 569003 : DO iparticle = 1, nparticle
181 4492475 : r_last_update(iparticle)%r = particle_set(iparticle)%r(:)
182 : END DO
183 : update_neighbor_lists = .TRUE.
184 : END IF
185 : ELSE
186 : ! There is no r_last_update to compare with. Neighbor lists from scratch.
187 614230 : ALLOCATE (r_last_update(nparticle))
188 601725 : DO iparticle = 1, nparticle
189 4796293 : r_last_update(iparticle)%r = particle_set(iparticle)%r(:)
190 : END DO
191 :
192 2501 : update_neighbor_lists = .TRUE.
193 2501 : build_from_scratch = .TRUE.
194 : END IF
195 : ! Force Update
196 82411 : IF (PRESENT(force_update)) THEN
197 0 : IF (force_update) update_neighbor_lists = .TRUE.
198 : END IF
199 :
200 : ! Allocate the r_last_update_pbc, rshell_last_update_pbc, rcore_last_update_pbc
201 82411 : IF (.NOT. ASSOCIATED(r_last_update_pbc)) THEN
202 614230 : ALLOCATE (r_last_update_pbc(nparticle))
203 : END IF
204 82411 : IF (shell_present .AND. .NOT. ASSOCIATED(rshell_last_update_pbc)) THEN
205 28950 : ALLOCATE (rshell_last_update_pbc(nshell))
206 : END IF
207 82411 : IF (shell_present .AND. .NOT. ASSOCIATED(rcore_last_update_pbc)) THEN
208 28950 : ALLOCATE (rcore_last_update_pbc(nshell))
209 : END IF
210 :
211 : ! update the neighbor lists
212 82411 : IF (update_neighbor_lists) THEN
213 : ! determine which pairs of atom kinds need full neighbor lists. Full
214 : ! means that atom a is in the neighbor list of atom b and vice versa.
215 44032 : ALLOCATE (full_nl(nparticle_kind, nparticle_kind))
216 11008 : IF (ASSOCIATED(potparm)) THEN
217 60803 : DO ikind = 1, nparticle_kind
218 740385 : DO jkind = ikind, nparticle_kind
219 679582 : full_nl(ikind, jkind) = .FALSE.
220 1359040 : IF (ANY(potparm%pot(ikind, jkind)%pot%type == tersoff_type)) THEN
221 132 : full_nl(ikind, jkind) = .TRUE.
222 : END IF
223 1359167 : IF (ANY(potparm%pot(ikind, jkind)%pot%type == siepmann_type)) THEN
224 5 : full_nl(ikind, jkind) = .TRUE.
225 : END IF
226 1359171 : IF (ANY(potparm%pot(ikind, jkind)%pot%type == gal_type)) THEN
227 1 : full_nl(ikind, jkind) = .TRUE.
228 : END IF
229 1359171 : IF (ANY(potparm%pot(ikind, jkind)%pot%type == gal21_type)) THEN
230 1 : full_nl(ikind, jkind) = .TRUE.
231 : END IF
232 1359160 : IF (ANY(potparm%pot(ikind, jkind)%pot%type == nequip_type)) THEN
233 12 : full_nl(ikind, jkind) = .TRUE.
234 : END IF
235 1359164 : IF (ANY(potparm%pot(ikind, jkind)%pot%type == allegro_type)) THEN
236 8 : full_nl(ikind, jkind) = .TRUE.
237 : END IF
238 729407 : full_nl(jkind, ikind) = full_nl(ikind, jkind)
239 : END DO
240 : END DO
241 : ELSE
242 178 : full_nl = .FALSE.
243 : END IF
244 : CALL build_fist_neighbor_lists(atomic_kind_set, particle_set, &
245 : local_particles, cell, rlist_cut, rlist_lowsq, ei_scale14, &
246 : vdw_scale14, nonbonded, para_env, &
247 : build_from_scratch=build_from_scratch, geo_check=geo_check, &
248 : mm_section=mm_section, full_nl=full_nl, &
249 11340 : exclusions=exclusions)
250 :
251 11008 : CALL cell_release(cell_last_update)
252 11008 : CALL cell_create(cell_last_update)
253 11008 : CALL cell_clone(cell, cell_last_update)
254 :
255 11008 : IF (counter > 0) THEN
256 8507 : num_update = num_update + 1
257 8507 : lup = counter + 1 - last_update
258 8507 : last_update = counter + 1
259 8507 : aup = aup + (lup - aup)/REAL(num_update, KIND=dp)
260 : ELSE
261 2501 : num_update = 0
262 2501 : lup = 0
263 2501 : last_update = 1
264 2501 : aup = 0.0_dp
265 : END IF
266 :
267 : CALL fist_nonbond_env_set(fist_nonbond_env, &
268 : lup=lup, &
269 : aup=aup, &
270 : r_last_update=r_last_update, &
271 : r_last_update_pbc=r_last_update_pbc, &
272 : rshell_last_update_pbc=rshell_last_update_pbc, &
273 : rcore_last_update_pbc=rcore_last_update_pbc, &
274 : nonbonded=nonbonded, &
275 : num_update=num_update, &
276 : last_update=last_update, &
277 11008 : cell_last_update=cell_last_update)
278 :
279 : output_unit = cp_print_key_unit_nr(logger, mm_section, "PRINT%NEIGHBOR_LISTS", &
280 11008 : extension=".mmLog")
281 11008 : IF (output_unit > 0) THEN
282 : WRITE (UNIT=output_unit, &
283 : FMT="(/,T2,A,/,T52,A,/,A,T31,A,T49,2(1X,F15.2),/,T2,A,/)") &
284 177 : REPEAT("*", 79), "INSTANTANEOUS AVERAGES", &
285 354 : " LIST UPDATES[steps]", "= ", lup, aup, REPEAT("*", 79)
286 : END IF
287 : CALL cp_print_key_finished_output(output_unit, logger, mm_section, &
288 11008 : "PRINT%NEIGHBOR_LISTS")
289 11008 : DEALLOCATE (full_nl)
290 : END IF
291 :
292 : ! Store particle positions after the last update, translated to the
293 : ! primitive cell, in r_last_update_pbc.
294 8320341 : DO iparticle = 1, nparticle
295 : ! The pbc algorithm is sensitive to numeric noise and compiler optimization because of ANINT.
296 : ! Therefore we need to call here exactly the same routine as in build_neighbor_lists.
297 32951720 : rab_last_update = pbc(r_last_update(iparticle)%r, cell_last_update) - r_last_update(iparticle)%r
298 8237930 : CALL real_to_scaled(s, rab_last_update, cell_last_update)
299 8237930 : CALL scaled_to_real(rab, s, cell)
300 :
301 65903440 : r_last_update_pbc(iparticle)%r = particle_set(iparticle)%r + rab
302 : ! Use the same translation for core and shell.
303 8237930 : ishell = particle_set(iparticle)%shell_index
304 8320341 : IF (ishell /= 0) THEN
305 6088592 : rshell_last_update_pbc(ishell)%r = rab + shell_particle_set(ishell)%r(:)
306 761074 : IF (shell_adiabatic) THEN
307 6088592 : rcore_last_update_pbc(ishell)%r = rab + core_particle_set(ishell)%r(:)
308 : ELSE
309 0 : rcore_last_update_pbc(ishell)%r = r_last_update_pbc(iparticle)%r(:)
310 : END IF
311 : END IF
312 : END DO
313 :
314 82411 : counter = counter + 1
315 82411 : CALL fist_nonbond_env_set(fist_nonbond_env, counter=counter)
316 82411 : CALL timestop(handle)
317 :
318 82411 : END SUBROUTINE list_control
319 :
320 : END MODULE fist_neighbor_list_control
|