(git:374b731)
Loading...
Searching...
No Matches
fist_neighbor_list_types.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 Define the neighbor list data types and the corresponding functionality
10! **************************************************************************************************
12
13 USE cell_types, ONLY: cell_type,&
14 pbc
16 USE kinds, ONLY: dp
18#include "./base/base_uses.f90"
19
20 IMPLICIT NONE
21
22 PRIVATE
23 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'fist_neighbor_list_types'
24
25! **************************************************************************************************
27 INTEGER, POINTER, DIMENSION(:, :) :: list, ij_kind
28 INTEGER, POINTER, DIMENSION(:) :: id_kind
29 INTEGER, POINTER, DIMENSION(:) :: grp_kind_start, grp_kind_end
30 INTEGER :: cell_vector(3), npairs
31 INTEGER :: ngrp_kind
32 REAL(kind=dp) :: rmax
33 ! The *_scale arrays are scaling factors for the corresponding nonbonding
34 ! interaction energies and forces for the pairs in 'list'. To keep the size
35 ! of these arrays small, pairs whose interaction must be scaled are moved
36 ! to beginning of the array 'list'. nscale is the number of elements in
37 ! *_scale that are effectively used. This way one does not have to
38 ! reallocate the *_scale arrays for every new scaled pair interaction.
39 ! The field is_info is only used to switch between the regular nonbonded
40 ! and the nonbonded14 splines for the van der waals interactions.
41 REAL(kind=dp), POINTER, DIMENSION(:) :: ei_scale
42 REAL(kind=dp), POINTER, DIMENSION(:) :: vdw_scale
43 LOGICAL, POINTER, DIMENSION(:) :: is_onfo
44 INTEGER :: nscale
46
47! **************************************************************************************************
49 TYPE(neighbor_kind_pairs_type), DIMENSION(:), POINTER :: neighbor_kind_pairs
50 INTEGER :: nlists
51 END TYPE fist_neighbor_type
52
53 PUBLIC :: neighbor_kind_pairs_type, &
58
59CONTAINS
60
61! **************************************************************************************************
62!> \brief ...
63!> \param fist_neighbor ...
64!> \par History
65!> 08.2006 created [tlaino]
66!> \author Teodoro Laino
67! **************************************************************************************************
68 SUBROUTINE fist_neighbor_deallocate(fist_neighbor)
69 TYPE(fist_neighbor_type), POINTER :: fist_neighbor
70
71 INTEGER :: i
72
73 IF (ASSOCIATED(fist_neighbor)) THEN
74 ! deallocate neighbor_kind_pairs
75 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs)) THEN
76 DO i = 1, SIZE(fist_neighbor%neighbor_kind_pairs)
77 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%list)) THEN
78 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%list)
79 END IF
80 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%id_kind)) THEN
81 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%id_kind)
82 END IF
83 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%ij_kind)) THEN
84 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%ij_kind)
85 END IF
86 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%grp_kind_start)) THEN
87 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%grp_kind_start)
88 END IF
89 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%grp_kind_end)) THEN
90 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%grp_kind_end)
91 END IF
92 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%ei_scale)) THEN
93 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%ei_scale)
94 END IF
95 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%vdw_scale)) THEN
96 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%vdw_scale)
97 END IF
98 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%is_onfo)) THEN
99 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%is_onfo)
100 END IF
101 END DO
102 DEALLOCATE (fist_neighbor%neighbor_kind_pairs)
103 END IF
104 DEALLOCATE (fist_neighbor)
105 END IF
106 END SUBROUTINE fist_neighbor_deallocate
107
108! **************************************************************************************************
109!> \brief ...
110!> \param fist_neighbor ...
111!> \param ncell ...
112!> \par History
113!> 08.2006 created [tlaino]
114!> \author Teodoro Laino
115! **************************************************************************************************
116 SUBROUTINE fist_neighbor_init(fist_neighbor, ncell)
117 TYPE(fist_neighbor_type), POINTER :: fist_neighbor
118 INTEGER, INTENT(IN) :: ncell(3)
119
120 CHARACTER(LEN=*), PARAMETER :: routinen = 'fist_neighbor_init'
121
122 INTEGER :: handle, i, list_size, nlistmin
123 TYPE(neighbor_kind_pairs_type), DIMENSION(:), &
124 POINTER :: new_pairs
125
126 CALL timeset(routinen, handle)
127 IF (.NOT. ASSOCIATED(fist_neighbor)) THEN
128 ALLOCATE (fist_neighbor)
129 NULLIFY (fist_neighbor%neighbor_kind_pairs)
130 END IF
131
132 nlistmin = (2*maxval(ncell) + 1)**3
133 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs)) THEN
134 IF (SIZE(fist_neighbor%neighbor_kind_pairs) < nlistmin) THEN
135 ALLOCATE (new_pairs(nlistmin))
136 DO i = 1, SIZE(fist_neighbor%neighbor_kind_pairs)
137 new_pairs(i)%list => fist_neighbor%neighbor_kind_pairs(i)%list
138 list_size = SIZE(new_pairs(i)%list)
139 ALLOCATE (new_pairs(i)%id_kind(list_size))
140 ALLOCATE (new_pairs(i)%ei_scale(0))
141 ALLOCATE (new_pairs(i)%vdw_scale(0))
142 ALLOCATE (new_pairs(i)%is_onfo(0))
143 NULLIFY (new_pairs(i)%ij_kind, &
144 new_pairs(i)%grp_kind_start, &
145 new_pairs(i)%grp_kind_end)
146 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%ij_kind)) THEN
147 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%ij_kind)
148 END IF
149 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%id_kind)) THEN
150 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%id_kind)
151 END IF
152 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%grp_kind_start)) THEN
153 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%grp_kind_start)
154 END IF
155 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%grp_kind_end)) THEN
156 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%grp_kind_end)
157 END IF
158 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%ei_scale)) THEN
159 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%ei_scale)
160 END IF
161 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%vdw_scale)) THEN
162 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%vdw_scale)
163 END IF
164 IF (ASSOCIATED(fist_neighbor%neighbor_kind_pairs(i)%is_onfo)) THEN
165 DEALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%is_onfo)
166 END IF
167 END DO
168 DO i = SIZE(fist_neighbor%neighbor_kind_pairs) + 1, nlistmin
169 ALLOCATE (new_pairs(i)%list(2, 0))
170 ALLOCATE (new_pairs(i)%id_kind(0))
171 NULLIFY (new_pairs(i)%ij_kind, &
172 new_pairs(i)%grp_kind_start, &
173 new_pairs(i)%grp_kind_end)
174 NULLIFY (new_pairs(i)%ei_scale, new_pairs(i)%vdw_scale, new_pairs(i)%is_onfo)
175 END DO
176 DEALLOCATE (fist_neighbor%neighbor_kind_pairs)
177 fist_neighbor%neighbor_kind_pairs => new_pairs
178 ELSE
179 DO i = 1, SIZE(fist_neighbor%neighbor_kind_pairs)
180 list_size = SIZE(fist_neighbor%neighbor_kind_pairs(i)%list)
181 CALL reallocate(fist_neighbor%neighbor_kind_pairs(i)%id_kind, 1, list_size)
182 END DO
183 END IF
184 ELSE
185 ALLOCATE (fist_neighbor%neighbor_kind_pairs(nlistmin))
186 DO i = 1, nlistmin
187 ALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%list(2, 0))
188 ALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%id_kind(0))
189 ALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%ei_scale(0))
190 ALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%vdw_scale(0))
191 ALLOCATE (fist_neighbor%neighbor_kind_pairs(i)%is_onfo(0))
192 NULLIFY (fist_neighbor%neighbor_kind_pairs(i)%ij_kind, &
193 fist_neighbor%neighbor_kind_pairs(i)%grp_kind_start, &
194 fist_neighbor%neighbor_kind_pairs(i)%grp_kind_end)
195 END DO
196 END IF
197
198 fist_neighbor%nlists = nlistmin
199 DO i = 1, nlistmin
200 fist_neighbor%neighbor_kind_pairs(i)%npairs = 0
201 fist_neighbor%neighbor_kind_pairs(i)%list = huge(0)
202 fist_neighbor%neighbor_kind_pairs(i)%id_kind = huge(0)
203 fist_neighbor%neighbor_kind_pairs(i)%cell_vector = huge(0)
204 fist_neighbor%neighbor_kind_pairs(i)%nscale = 0
205 END DO
206 CALL timestop(handle)
207 END SUBROUTINE fist_neighbor_init
208
209! **************************************************************************************************
210!> \brief ...
211!> \param neighbor_kind_pair ...
212!> \param atom_a ...
213!> \param atom_b ...
214!> \param rab ...
215!> \param check_spline ...
216!> \param id_kind ...
217!> \param skip ...
218!> \param cell ...
219!> \param ei_scale14 ...
220!> \param vdw_scale14 ...
221!> \param exclusions ...
222!> \par History
223!> 08.2006 created [tlaino]
224!> \author Teodoro Laino
225! **************************************************************************************************
226 SUBROUTINE fist_neighbor_add(neighbor_kind_pair, atom_a, atom_b, &
227 rab, check_spline, id_kind, skip, cell, &
228 ei_scale14, vdw_scale14, exclusions)
229 TYPE(neighbor_kind_pairs_type), POINTER :: neighbor_kind_pair
230 INTEGER, INTENT(IN) :: atom_a, atom_b
231 REAL(kind=dp), DIMENSION(3) :: rab
232 LOGICAL, INTENT(OUT) :: check_spline
233 INTEGER, INTENT(IN) :: id_kind
234 LOGICAL, INTENT(IN) :: skip
235 TYPE(cell_type), POINTER :: cell
236 REAL(kind=dp), INTENT(IN) :: ei_scale14, vdw_scale14
237 TYPE(exclusion_type), DIMENSION(:), OPTIONAL :: exclusions
238
239 REAL(kind=dp), PARAMETER :: eps_default = epsilon(0.0_dp)*1.0e4_dp
240
241 INTEGER :: new_npairs, npairs, nscale, old_npairs
242 INTEGER, DIMENSION(:), POINTER :: new_id_kind
243 INTEGER, DIMENSION(:, :), POINTER :: new_list
244 LOGICAL :: ex_ei, ex_vdw, is_onfo
245 REAL(kind=dp), DIMENSION(3) :: rabc
246
247 IF (.NOT. PRESENT(exclusions)) THEN
248 ex_ei = .false.
249 ex_vdw = .false.
250 is_onfo = .false.
251 ELSE
252 ex_ei = any(exclusions(atom_a)%list_exclude_ei == atom_b)
253 ex_vdw = any(exclusions(atom_a)%list_exclude_vdw == atom_b)
254 is_onfo = any(exclusions(atom_a)%list_onfo == atom_b)
255 IF (ex_ei .OR. ex_vdw .OR. is_onfo) THEN
256 ! Check if this pair could correspond to a local interaction (bond, bend,
257 ! or torsion) to which the exclusion lists and 14 potentials apply.
258 !
259 ! rab is the relative vector that may include some cell vectors. rabc is
260 ! the 'shortest' possible relative vector, i.e. cell vectors are
261 ! subtracted. When they are not the same, rab corresponds to a non-local
262 ! interaction and the exclusion lists do not apply.
263 rabc = pbc(rab, cell)
264 IF ((any(abs(rab - rabc) > eps_default))) THEN
265 ex_ei = .false.
266 ex_vdw = .false.
267 is_onfo = .false.
268 END IF
269 END IF
270 END IF
271
272 ! The skip option is .TRUE. for QM-QM pairs in an QM/MM run. In case these
273 ! interactions have an ex_ei option, we store it in the neighbor list to
274 ! do a proper bonded correction for the ewald summation. If there is no
275 ! exclusion, the pair can be neglected.
276 IF (skip .AND. (.NOT. ex_ei)) THEN
277 ! If the pair is not present, checking is obviously not need.
278 check_spline = .false.
279 RETURN
280 END IF
281
282 ! The check_spline is set to .TRUE. when the van derwaals is not excluded.
283 ! Electrostatic interactions do not matter here as they are not evaluated
284 ! with splines.
285 check_spline = (.NOT. ex_vdw)
286
287 ! If both types of interactions are excluded, the corresponding potentials
288 ! will never be evaluated. At first sight such a pair would not need to be
289 ! added to the neighborlists at all. However, they are still needed for
290 ! proper corrections on interactions between the screening charges of bonded
291 ! atoms when the ewald summation is used for the electrostatic interactions.
292
293 ! If an interaction is excluded or scaled, store scale. If the interaction
294 ! is an onfo, also store that property.
295 IF (ex_ei .OR. ex_vdw .OR. is_onfo) THEN
296 ! Allocate more memory for the scalings if necessary.
297 nscale = neighbor_kind_pair%nscale
298 IF (nscale == SIZE(neighbor_kind_pair%ei_scale)) THEN
299 CALL reallocate(neighbor_kind_pair%ei_scale, 1, int(5 + 1.2*nscale))
300 CALL reallocate(neighbor_kind_pair%vdw_scale, 1, int(5 + 1.2*nscale))
301 CALL reallocate(neighbor_kind_pair%is_onfo, 1, int(5 + 1.2*nscale))
302 END IF
303 nscale = nscale + 1
304 IF (ex_ei) THEN
305 neighbor_kind_pair%ei_scale(nscale) = 0.0_dp
306 ELSE IF (is_onfo) THEN
307 neighbor_kind_pair%ei_scale(nscale) = ei_scale14
308 ELSE
309 neighbor_kind_pair%ei_scale(nscale) = 1.0_dp
310 END IF
311 IF (ex_vdw) THEN
312 neighbor_kind_pair%vdw_scale(nscale) = 0.0_dp
313 ELSE IF (is_onfo) THEN
314 neighbor_kind_pair%vdw_scale(nscale) = vdw_scale14
315 ELSE
316 neighbor_kind_pair%vdw_scale(nscale) = 1.0_dp
317 END IF
318 neighbor_kind_pair%is_onfo(nscale) = is_onfo
319 neighbor_kind_pair%nscale = nscale
320 ELSE
321 nscale = huge(0)
322 END IF
323
324 ! Allocate more memory for the pair list if necessary.
325 old_npairs = SIZE(neighbor_kind_pair%list, 2)
326 IF (old_npairs == neighbor_kind_pair%npairs) THEN
327 ! just a choice that will also grow for zero size arrays:
328 new_npairs = int(5 + 1.2*old_npairs)
329 ! Pair Atoms Info
330 ALLOCATE (new_list(2, new_npairs))
331 new_list(1:2, 1:old_npairs) = neighbor_kind_pair%list(1:2, 1:old_npairs)
332 DEALLOCATE (neighbor_kind_pair%list)
333 neighbor_kind_pair%list => new_list
334 ! Kind Info
335 ALLOCATE (new_id_kind(new_npairs))
336 new_id_kind(1:old_npairs) = neighbor_kind_pair%id_kind(1:old_npairs)
337 DEALLOCATE (neighbor_kind_pair%id_kind)
338 neighbor_kind_pair%id_kind => new_id_kind
339 END IF
340
341 ! Store the pair ...
342 npairs = neighbor_kind_pair%npairs + 1
343 IF ((ex_ei .OR. ex_vdw .OR. is_onfo) .AND. (npairs > nscale)) THEN
344 ! ... after the previous pair that had scaling factors.
345 neighbor_kind_pair%list(1, npairs) = neighbor_kind_pair%list(1, nscale)
346 neighbor_kind_pair%list(2, npairs) = neighbor_kind_pair%list(2, nscale)
347 neighbor_kind_pair%id_kind(npairs) = neighbor_kind_pair%id_kind(nscale)
348 neighbor_kind_pair%list(1, nscale) = atom_a
349 neighbor_kind_pair%list(2, nscale) = atom_b
350 neighbor_kind_pair%id_kind(nscale) = id_kind
351 ELSE
352 ! ... at the end of the list.
353 neighbor_kind_pair%list(1, npairs) = atom_a
354 neighbor_kind_pair%list(2, npairs) = atom_b
355 neighbor_kind_pair%id_kind(npairs) = id_kind
356 END IF
357 neighbor_kind_pair%npairs = npairs
358 END SUBROUTINE fist_neighbor_add
359
Handles all functions related to the CELL.
Definition cell_types.F:15
an exclusion type
Define the neighbor list data types and the corresponding functionality.
subroutine, public fist_neighbor_add(neighbor_kind_pair, atom_a, atom_b, rab, check_spline, id_kind, skip, cell, ei_scale14, vdw_scale14, exclusions)
...
subroutine, public fist_neighbor_init(fist_neighbor, ncell)
...
subroutine, public fist_neighbor_deallocate(fist_neighbor)
...
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
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.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
A type used to store lists of exclusions and onfos.