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