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 : !> Efficient tersoff implementation and general "lifting" of manybody_potential module
11 : !> 12.2007 [tlaino] - Splitting manybody module : In this module we should only
12 : !> keep the main routines for computing energy and forces of
13 : !> manybody potentials. Each potential should have his own module!
14 : !> \author CJM, I-Feng W. Kuo, Teodoro Laino
15 : ! **************************************************************************************************
16 : MODULE manybody_potential
17 :
18 : USE atomic_kind_types, ONLY: atomic_kind_type
19 : USE cell_types, ONLY: cell_type
20 : USE distribution_1d_types, ONLY: distribution_1d_type
21 : USE fist_neighbor_list_types, ONLY: fist_neighbor_type,&
22 : neighbor_kind_pairs_type
23 : USE fist_nonbond_env_types, ONLY: eam_type,&
24 : fist_nonbond_env_get,&
25 : fist_nonbond_env_type,&
26 : pos_type
27 : USE input_section_types, ONLY: section_vals_type
28 : USE kinds, ONLY: dp
29 : USE manybody_ace, ONLY: ace_add_force_virial,&
30 : ace_energy_store_force_virial
31 : USE manybody_deepmd, ONLY: deepmd_add_force_virial,&
32 : deepmd_energy_store_force_virial
33 : USE manybody_eam, ONLY: get_force_eam
34 : USE manybody_gal, ONLY: destroy_gal_arrays,&
35 : gal_energy,&
36 : gal_forces,&
37 : setup_gal_arrays
38 : USE manybody_gal21, ONLY: destroy_gal21_arrays,&
39 : gal21_energy,&
40 : gal21_forces,&
41 : setup_gal21_arrays
42 : USE manybody_nequip, ONLY: nequip_add_force_virial,&
43 : nequip_energy_store_force_virial
44 : USE manybody_siepmann, ONLY: destroy_siepmann_arrays,&
45 : print_nr_ions_siepmann,&
46 : setup_siepmann_arrays,&
47 : siepmann_energy,&
48 : siepmann_forces_v2,&
49 : siepmann_forces_v3
50 : USE manybody_tersoff, ONLY: destroy_tersoff_arrays,&
51 : setup_tersoff_arrays,&
52 : tersoff_energy,&
53 : tersoff_forces
54 : USE message_passing, ONLY: mp_para_env_type
55 : USE pair_potential_types, ONLY: &
56 : ace_type, allegro_type, deepmd_type, ea_type, eam_pot_type, gal21_pot_type, gal21_type, &
57 : gal_pot_type, gal_type, nequip_type, pair_potential_pp_type, pair_potential_single_type, &
58 : siepmann_pot_type, siepmann_type, tersoff_pot_type, tersoff_type
59 : USE particle_types, ONLY: particle_type
60 : USE util, ONLY: sort
61 : #include "./base/base_uses.f90"
62 :
63 : IMPLICIT NONE
64 :
65 : PRIVATE
66 : PUBLIC :: energy_manybody
67 : PUBLIC :: force_nonbond_manybody
68 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'manybody_potential'
69 :
70 : CONTAINS
71 :
72 : ! **************************************************************************************************
73 : !> \brief computes the embedding contribution to the energy
74 : !> \param fist_nonbond_env ...
75 : !> \param atomic_kind_set ...
76 : !> \param local_particles ...
77 : !> \param particle_set ...
78 : !> \param cell ...
79 : !> \param pot_manybody ...
80 : !> \param para_env ...
81 : !> \param mm_section ...
82 : !> \param use_virial ...
83 : !> \par History
84 : !> tlaino [2007] - New algorithm for tersoff potential
85 : !> \author CJM, I-Feng W. Kuo, Teodoro Laino
86 : ! **************************************************************************************************
87 81972 : SUBROUTINE energy_manybody(fist_nonbond_env, atomic_kind_set, local_particles, &
88 : particle_set, cell, pot_manybody, para_env, mm_section, use_virial)
89 :
90 : TYPE(fist_nonbond_env_type), POINTER :: fist_nonbond_env
91 : TYPE(atomic_kind_type), POINTER :: atomic_kind_set(:)
92 : TYPE(distribution_1d_type), POINTER :: local_particles
93 : TYPE(particle_type), POINTER :: particle_set(:)
94 : TYPE(cell_type), POINTER :: cell
95 : REAL(dp), INTENT(INOUT) :: pot_manybody
96 : TYPE(mp_para_env_type), OPTIONAL, POINTER :: para_env
97 : TYPE(section_vals_type), POINTER :: mm_section
98 : LOGICAL, INTENT(IN) :: use_virial
99 :
100 : CHARACTER(LEN=*), PARAMETER :: routineN = 'energy_manybody'
101 :
102 : INTEGER :: atom_a, atom_b, handle, i, iend, ifirst, igrp, ikind, ilast, ilist, indexa, &
103 : ipair, iparticle, iparticle_local, istart, iunique, jkind, junique, mpair, nkinds, &
104 : nloc_size, npairs, nparticle, nparticle_local, nr_h3O, nr_o, nr_oh, nunique
105 81972 : INTEGER, DIMENSION(:), POINTER :: glob_loc_list_a, work_list
106 81972 : INTEGER, DIMENSION(:, :), POINTER :: glob_loc_list, list, sort_list
107 : LOGICAL :: any_ace, any_allegro, any_deepmd, &
108 : any_gal, any_gal21, any_nequip, &
109 : any_siepmann, any_tersoff
110 : REAL(KIND=dp) :: drij, embed, pot_ace, pot_allegro, &
111 : pot_deepmd, pot_loc, pot_nequip, qr, &
112 : rab2_max, rij(3)
113 : REAL(KIND=dp), DIMENSION(3) :: cell_v, cvi
114 81972 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: glob_cell_v
115 81972 : REAL(KIND=dp), POINTER :: fembed(:)
116 : TYPE(eam_pot_type), POINTER :: eam
117 81972 : TYPE(eam_type), DIMENSION(:), POINTER :: eam_data
118 : TYPE(fist_neighbor_type), POINTER :: nonbonded
119 : TYPE(gal21_pot_type), POINTER :: gal21
120 : TYPE(gal_pot_type), POINTER :: gal
121 : TYPE(neighbor_kind_pairs_type), POINTER :: neighbor_kind_pair
122 : TYPE(pair_potential_pp_type), POINTER :: potparm
123 : TYPE(pair_potential_single_type), POINTER :: pot
124 81972 : TYPE(pos_type), DIMENSION(:), POINTER :: r_last_update_pbc
125 : TYPE(siepmann_pot_type), POINTER :: siepmann
126 : TYPE(tersoff_pot_type), POINTER :: tersoff
127 :
128 81972 : NULLIFY (eam, siepmann, tersoff, gal, gal21)
129 81972 : any_tersoff = .FALSE.
130 81972 : any_siepmann = .FALSE.
131 81972 : any_gal = .FALSE.
132 81972 : any_gal21 = .FALSE.
133 81972 : any_allegro = .FALSE.
134 81972 : any_nequip = .FALSE.
135 81972 : any_ace = .FALSE.
136 81972 : any_deepmd = .FALSE.
137 81972 : CALL timeset(routineN, handle)
138 : CALL fist_nonbond_env_get(fist_nonbond_env, r_last_update_pbc=r_last_update_pbc, &
139 81972 : potparm=potparm, eam_data=eam_data)
140 : ! EAM requires a single loop
141 315230 : DO ikind = 1, SIZE(atomic_kind_set)
142 233258 : pot => potparm%pot(ikind, ikind)%pot
143 548536 : DO i = 1, SIZE(pot%type)
144 233306 : IF (pot%type(i) /= ea_type) CYCLE
145 488 : eam => pot%set(i)%eam
146 488 : nparticle = SIZE(particle_set)
147 1464 : ALLOCATE (fembed(nparticle))
148 14258 : fembed(:) = 0._dp
149 488 : CPASSERT(ASSOCIATED(eam_data))
150 : ! computation of embedding function and energy
151 488 : nparticle_local = local_particles%n_el(ikind)
152 4136 : DO iparticle_local = 1, nparticle_local
153 3648 : iparticle = local_particles%list(ikind)%array(iparticle_local)
154 3648 : indexa = INT(eam_data(iparticle)%rho/eam%drhoar) + 1
155 3648 : IF (indexa > eam%npoints - 1) indexa = eam%npoints - 1
156 3648 : qr = eam_data(iparticle)%rho - eam%rhoval(indexa)
157 :
158 3648 : embed = eam%frho(indexa) + qr*eam%frhop(indexa)
159 3648 : fembed(iparticle) = eam%frhop(indexa) + qr*(eam%frhop(indexa + 1) - eam%frhop(indexa))/eam%drhoar
160 :
161 4136 : pot_manybody = pot_manybody + embed
162 : END DO
163 : ! communicate data
164 28028 : CALL para_env%sum(fembed)
165 14258 : DO iparticle = 1, nparticle
166 14258 : IF (particle_set(iparticle)%atomic_kind%kind_number == ikind) THEN
167 7296 : eam_data(iparticle)%f_embed = fembed(iparticle)
168 : END IF
169 : END DO
170 :
171 466564 : DEALLOCATE (fembed)
172 : END DO
173 : END DO
174 : ! Other manybody potential
175 315230 : DO ikind = 1, SIZE(atomic_kind_set)
176 1790884 : DO jkind = ikind, SIZE(atomic_kind_set)
177 1475654 : pot => potparm%pot(ikind, jkind)%pot
178 2947924 : any_tersoff = any_tersoff .OR. ANY(pot%type == tersoff_type)
179 2951350 : any_nequip = any_nequip .OR. ANY(pot%type == nequip_type)
180 2950738 : any_ace = any_ace .OR. ANY(pot%type == ace_type)
181 2951350 : any_allegro = any_allegro .OR. ANY(pot%type == allegro_type)
182 2951350 : any_deepmd = any_deepmd .OR. ANY(pot%type == deepmd_type)
183 2951335 : any_siepmann = any_siepmann .OR. ANY(pot%type == siepmann_type)
184 2951355 : any_gal = any_gal .OR. ANY(pot%type == gal_type)
185 3184613 : any_gal21 = any_gal21 .OR. ANY(pot%type == gal21_type)
186 : END DO
187 : END DO
188 81972 : CALL fist_nonbond_env_get(fist_nonbond_env, nonbonded=nonbonded, natom_types=nkinds)
189 : ! NEQUIP
190 81972 : IF (any_nequip) THEN
191 2 : NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
192 : CALL nequip_energy_store_force_virial(nonbonded, particle_set, local_particles, cell, &
193 : atomic_kind_set, potparm, r_last_update_pbc, &
194 : pot_nequip, fist_nonbond_env, &
195 2 : para_env, use_virial, nequip_type)
196 2 : pot_manybody = pot_manybody + pot_nequip
197 : END IF
198 : ! ALLEGRO
199 81972 : IF (any_allegro) THEN
200 2 : NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
201 : CALL nequip_energy_store_force_virial(nonbonded, particle_set, local_particles, cell, &
202 : atomic_kind_set, potparm, r_last_update_pbc, &
203 : pot_allegro, fist_nonbond_env, &
204 2 : para_env, use_virial, allegro_type)
205 2 : pot_manybody = pot_manybody + pot_allegro
206 : END IF
207 : ! ACE
208 81972 : IF (any_ace) THEN
209 : CALL ace_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, &
210 206 : fist_nonbond_env, pot_ace)
211 206 : pot_manybody = pot_manybody + pot_ace
212 : END IF
213 : ! DEEPMD
214 81972 : IF (any_deepmd) THEN
215 : CALL deepmd_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, &
216 2 : fist_nonbond_env, pot_deepmd, para_env)
217 2 : pot_manybody = pot_manybody + pot_deepmd
218 : END IF
219 :
220 : ! TERSOFF
221 81972 : IF (any_tersoff) THEN
222 3124 : NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
223 3124 : CALL setup_tersoff_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
224 115500 : DO ilist = 1, nonbonded%nlists
225 112376 : neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
226 112376 : npairs = neighbor_kind_pair%npairs
227 112376 : IF (npairs == 0) CYCLE
228 87731 : Kind_Group_Loop: DO igrp = 1, neighbor_kind_pair%ngrp_kind
229 42864 : istart = neighbor_kind_pair%grp_kind_start(igrp)
230 42864 : iend = neighbor_kind_pair%grp_kind_end(igrp)
231 42864 : ikind = neighbor_kind_pair%ij_kind(1, igrp)
232 42864 : jkind = neighbor_kind_pair%ij_kind(2, igrp)
233 42864 : list => neighbor_kind_pair%list
234 171456 : cvi = neighbor_kind_pair%cell_vector
235 42864 : pot => potparm%pot(ikind, jkind)%pot
236 198106 : DO i = 1, SIZE(pot%type)
237 42866 : IF (pot%type(i) /= tersoff_type) CYCLE
238 42823 : rab2_max = pot%set(i)%tersoff%rcutsq
239 556699 : cell_v = MATMUL(cell%hmat, cvi)
240 42823 : pot => potparm%pot(ikind, jkind)%pot
241 42823 : tersoff => pot%set(i)%tersoff
242 42823 : npairs = iend - istart + 1
243 85687 : IF (npairs /= 0) THEN
244 214115 : ALLOCATE (sort_list(2, npairs), work_list(npairs))
245 45922303 : sort_list = list(:, istart:iend)
246 : ! Sort the list of neighbors, this increases the efficiency for single
247 : ! potential contributions
248 42823 : CALL sort(sort_list(1, :), npairs, work_list)
249 7689403 : DO ipair = 1, npairs
250 7689403 : work_list(ipair) = sort_list(2, work_list(ipair))
251 : END DO
252 15335983 : sort_list(2, :) = work_list
253 : ! find number of unique elements of array index 1
254 42823 : nunique = 1
255 7646580 : DO ipair = 1, npairs - 1
256 7646580 : IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
257 : END DO
258 42823 : ipair = 1
259 42823 : junique = sort_list(1, ipair)
260 42823 : ifirst = 1
261 494916 : DO iunique = 1, nunique
262 452093 : atom_a = junique
263 452093 : IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
264 93196653 : DO mpair = ifirst, SIZE(glob_loc_list_a)
265 93196653 : IF (glob_loc_list_a(mpair) == atom_a) EXIT
266 : END DO
267 110993591 : ifirst = mpair
268 110993591 : DO mpair = ifirst, SIZE(glob_loc_list_a)
269 110993591 : IF (glob_loc_list_a(mpair) /= atom_a) EXIT
270 : END DO
271 452093 : ilast = mpair - 1
272 452093 : nloc_size = 0
273 452093 : IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
274 8098673 : DO WHILE (ipair <= npairs)
275 8055850 : IF (sort_list(1, ipair) /= junique) EXIT
276 7646580 : atom_b = sort_list(2, ipair)
277 : ! Energy terms
278 7646580 : pot_loc = 0.0_dp
279 30586320 : rij(:) = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
280 30586320 : drij = DOT_PRODUCT(rij, rij)
281 7646580 : ipair = ipair + 1
282 7646580 : IF (drij > rab2_max) CYCLE
283 330372 : drij = SQRT(drij)
284 : CALL tersoff_energy(pot_loc, tersoff, r_last_update_pbc, atom_a, atom_b, nloc_size, &
285 330372 : glob_loc_list(:, ifirst:ilast), glob_cell_v(:, ifirst:ilast), cell_v, drij)
286 8055850 : pot_manybody = pot_manybody + 0.5_dp*pot_loc
287 : END DO
288 452093 : ifirst = ilast + 1
289 494916 : IF (ipair <= npairs) junique = sort_list(1, ipair)
290 : END DO
291 42823 : DEALLOCATE (sort_list, work_list)
292 : END IF
293 : END DO
294 : END DO Kind_Group_Loop
295 : END DO
296 3124 : CALL destroy_tersoff_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
297 : END IF
298 :
299 : !SIEPMANN POTENTIAL
300 81972 : IF (any_siepmann) THEN
301 21 : NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
302 21 : nr_oh = 0
303 21 : nr_h3O = 0
304 21 : nr_o = 0
305 21 : CALL setup_siepmann_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
306 588 : DO ilist = 1, nonbonded%nlists
307 567 : neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
308 567 : npairs = neighbor_kind_pair%npairs
309 567 : IF (npairs == 0) CYCLE
310 918 : Kind_Group_Loop_2: DO igrp = 1, neighbor_kind_pair%ngrp_kind
311 708 : istart = neighbor_kind_pair%grp_kind_start(igrp)
312 708 : iend = neighbor_kind_pair%grp_kind_end(igrp)
313 708 : ikind = neighbor_kind_pair%ij_kind(1, igrp)
314 708 : jkind = neighbor_kind_pair%ij_kind(2, igrp)
315 708 : list => neighbor_kind_pair%list
316 2832 : cvi = neighbor_kind_pair%cell_vector
317 708 : pot => potparm%pot(ikind, jkind)%pot
318 1983 : DO i = 1, SIZE(pot%type)
319 708 : IF (pot%type(i) /= siepmann_type) CYCLE
320 165 : rab2_max = pot%set(i)%siepmann%rcutsq
321 2145 : cell_v = MATMUL(cell%hmat, cvi)
322 165 : pot => potparm%pot(ikind, jkind)%pot
323 165 : siepmann => pot%set(i)%siepmann
324 165 : npairs = iend - istart + 1
325 873 : IF (npairs /= 0) THEN
326 825 : ALLOCATE (sort_list(2, npairs), work_list(npairs))
327 109533 : sort_list = list(:, istart:iend)
328 : ! Sort the list of neighbors, this increases the efficiency for single
329 : ! potential contributions
330 165 : CALL sort(sort_list(1, :), npairs, work_list)
331 18393 : DO ipair = 1, npairs
332 18393 : work_list(ipair) = sort_list(2, work_list(ipair))
333 : END DO
334 36621 : sort_list(2, :) = work_list
335 : ! find number of unique elements of array index 1
336 165 : nunique = 1
337 18228 : DO ipair = 1, npairs - 1
338 18228 : IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
339 : END DO
340 165 : ipair = 1
341 165 : junique = sort_list(1, ipair)
342 165 : ifirst = 1
343 5340 : DO iunique = 1, nunique
344 5175 : atom_a = junique
345 5175 : IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
346 91602 : DO mpair = ifirst, SIZE(glob_loc_list_a)
347 91602 : IF (glob_loc_list_a(mpair) == atom_a) EXIT
348 : END DO
349 62187 : ifirst = mpair
350 62187 : DO mpair = ifirst, SIZE(glob_loc_list_a)
351 62187 : IF (glob_loc_list_a(mpair) /= atom_a) EXIT
352 : END DO
353 5175 : ilast = mpair - 1
354 5175 : nloc_size = 0
355 5175 : IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
356 23403 : DO WHILE (ipair <= npairs)
357 23238 : IF (sort_list(1, ipair) /= junique) EXIT
358 18228 : atom_b = sort_list(2, ipair)
359 : ! Energy terms
360 18228 : pot_loc = 0.0_dp
361 72912 : rij(:) = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
362 72912 : drij = DOT_PRODUCT(rij, rij)
363 18228 : ipair = ipair + 1
364 18228 : IF (drij > rab2_max) CYCLE
365 318 : drij = SQRT(drij)
366 : CALL siepmann_energy(pot_loc, siepmann, r_last_update_pbc, atom_a, atom_b, nloc_size, &
367 : glob_loc_list(:, ifirst:ilast), cell_v, cell, drij, &
368 318 : particle_set, nr_oh, nr_h3O, nr_o)
369 23238 : pot_manybody = pot_manybody + pot_loc
370 : END DO
371 5175 : ifirst = ilast + 1
372 5340 : IF (ipair <= npairs) junique = sort_list(1, ipair)
373 : END DO
374 165 : DEALLOCATE (sort_list, work_list)
375 : END IF
376 : END DO
377 : END DO Kind_Group_Loop_2
378 : END DO
379 21 : CALL destroy_siepmann_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
380 : CALL print_nr_ions_siepmann(nr_oh, mm_section, para_env, print_oh=.TRUE., &
381 21 : print_h3o=.FALSE., print_o=.FALSE.)
382 : CALL print_nr_ions_siepmann(nr_h3o, mm_section, para_env, print_oh=.FALSE., &
383 21 : print_h3o=.TRUE., print_o=.FALSE.)
384 : CALL print_nr_ions_siepmann(nr_o, mm_section, para_env, print_oh=.FALSE., &
385 21 : print_h3o=.FALSE., print_o=.TRUE.)
386 : END IF
387 :
388 : !GAL19 POTENTIAL
389 81972 : IF (any_gal) THEN
390 1 : NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
391 1 : CALL setup_gal_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
392 28 : DO ilist = 1, nonbonded%nlists
393 27 : neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
394 27 : npairs = neighbor_kind_pair%npairs
395 27 : IF (npairs == 0) CYCLE
396 168 : Kind_Group_Loop_3: DO igrp = 1, neighbor_kind_pair%ngrp_kind
397 158 : istart = neighbor_kind_pair%grp_kind_start(igrp)
398 158 : iend = neighbor_kind_pair%grp_kind_end(igrp)
399 158 : ikind = neighbor_kind_pair%ij_kind(1, igrp)
400 158 : jkind = neighbor_kind_pair%ij_kind(2, igrp)
401 158 : list => neighbor_kind_pair%list
402 632 : cvi = neighbor_kind_pair%cell_vector
403 158 : pot => potparm%pot(ikind, jkind)%pot
404 343 : DO i = 1, SIZE(pot%type)
405 158 : IF (pot%type(i) /= gal_type) CYCLE
406 9 : rab2_max = pot%set(i)%gal%rcutsq
407 117 : cell_v = MATMUL(cell%hmat, cvi)
408 9 : pot => potparm%pot(ikind, jkind)%pot
409 9 : gal => pot%set(i)%gal
410 9 : npairs = iend - istart + 1
411 167 : IF (npairs /= 0) THEN
412 45 : ALLOCATE (sort_list(2, npairs), work_list(npairs))
413 45609 : sort_list = list(:, istart:iend)
414 : ! Sort the list of neighbors, this increases the efficiency for single
415 : ! potential contributions
416 9 : CALL sort(sort_list(1, :), npairs, work_list)
417 7609 : DO ipair = 1, npairs
418 7609 : work_list(ipair) = sort_list(2, work_list(ipair))
419 : END DO
420 15209 : sort_list(2, :) = work_list
421 : ! find number of unique elements of array index 1
422 9 : nunique = 1
423 7600 : DO ipair = 1, npairs - 1
424 7600 : IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
425 : END DO
426 9 : ipair = 1
427 9 : junique = sort_list(1, ipair)
428 9 : ifirst = 1
429 659 : DO iunique = 1, nunique
430 650 : atom_a = junique
431 650 : IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
432 36198 : DO mpair = ifirst, SIZE(glob_loc_list_a)
433 36198 : IF (glob_loc_list_a(mpair) == atom_a) EXIT
434 : END DO
435 24581 : ifirst = mpair
436 24581 : DO mpair = ifirst, SIZE(glob_loc_list_a)
437 24581 : IF (glob_loc_list_a(mpair) /= atom_a) EXIT
438 : END DO
439 650 : ilast = mpair - 1
440 650 : nloc_size = 0
441 650 : IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
442 8250 : DO WHILE (ipair <= npairs)
443 8241 : IF (sort_list(1, ipair) /= junique) EXIT
444 7600 : atom_b = sort_list(2, ipair)
445 : ! Energy terms
446 7600 : pot_loc = 0.0_dp
447 30400 : rij(:) = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
448 30400 : drij = DOT_PRODUCT(rij, rij)
449 7600 : ipair = ipair + 1
450 7600 : IF (drij > rab2_max) CYCLE
451 2004 : drij = SQRT(drij)
452 : CALL gal_energy(pot_loc, gal, r_last_update_pbc, atom_a, atom_b, &
453 2004 : cell, particle_set, mm_section)
454 :
455 8241 : pot_manybody = pot_manybody + pot_loc
456 : END DO
457 650 : ifirst = ilast + 1
458 659 : IF (ipair <= npairs) junique = sort_list(1, ipair)
459 : END DO
460 9 : DEALLOCATE (sort_list, work_list)
461 : END IF
462 : END DO
463 : END DO Kind_Group_Loop_3
464 : END DO
465 1 : CALL destroy_gal_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
466 : END IF
467 :
468 : !GAL21 POTENTIAL
469 81972 : IF (any_gal21) THEN
470 1 : NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
471 1 : CALL setup_gal21_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
472 28 : DO ilist = 1, nonbonded%nlists
473 27 : neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
474 27 : npairs = neighbor_kind_pair%npairs
475 27 : IF (npairs == 0) CYCLE
476 168 : Kind_Group_Loop_5: DO igrp = 1, neighbor_kind_pair%ngrp_kind
477 158 : istart = neighbor_kind_pair%grp_kind_start(igrp)
478 158 : iend = neighbor_kind_pair%grp_kind_end(igrp)
479 158 : ikind = neighbor_kind_pair%ij_kind(1, igrp)
480 158 : jkind = neighbor_kind_pair%ij_kind(2, igrp)
481 158 : list => neighbor_kind_pair%list
482 632 : cvi = neighbor_kind_pair%cell_vector
483 158 : pot => potparm%pot(ikind, jkind)%pot
484 343 : DO i = 1, SIZE(pot%type)
485 158 : IF (pot%type(i) /= gal21_type) CYCLE
486 9 : rab2_max = pot%set(i)%gal21%rcutsq
487 117 : cell_v = MATMUL(cell%hmat, cvi)
488 9 : pot => potparm%pot(ikind, jkind)%pot
489 9 : gal21 => pot%set(i)%gal21
490 9 : npairs = iend - istart + 1
491 167 : IF (npairs /= 0) THEN
492 45 : ALLOCATE (sort_list(2, npairs), work_list(npairs))
493 52809 : sort_list = list(:, istart:iend)
494 : ! Sort the list of neighbors, this increases the efficiency for single
495 : ! potential contributions
496 9 : CALL sort(sort_list(1, :), npairs, work_list)
497 8809 : DO ipair = 1, npairs
498 8809 : work_list(ipair) = sort_list(2, work_list(ipair))
499 : END DO
500 17609 : sort_list(2, :) = work_list
501 : ! find number of unique elements of array index 1
502 9 : nunique = 1
503 8800 : DO ipair = 1, npairs - 1
504 8800 : IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
505 : END DO
506 9 : ipair = 1
507 9 : junique = sort_list(1, ipair)
508 9 : ifirst = 1
509 710 : DO iunique = 1, nunique
510 701 : atom_a = junique
511 701 : IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
512 42242 : DO mpair = ifirst, SIZE(glob_loc_list_a)
513 42242 : IF (glob_loc_list_a(mpair) == atom_a) EXIT
514 : END DO
515 30069 : ifirst = mpair
516 30069 : DO mpair = ifirst, SIZE(glob_loc_list_a)
517 30069 : IF (glob_loc_list_a(mpair) /= atom_a) EXIT
518 : END DO
519 701 : ilast = mpair - 1
520 701 : nloc_size = 0
521 701 : IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
522 9501 : DO WHILE (ipair <= npairs)
523 9492 : IF (sort_list(1, ipair) /= junique) EXIT
524 8800 : atom_b = sort_list(2, ipair)
525 : ! Energy terms
526 8800 : pot_loc = 0.0_dp
527 35200 : rij(:) = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
528 35200 : drij = DOT_PRODUCT(rij, rij)
529 8800 : ipair = ipair + 1
530 8800 : IF (drij > rab2_max) CYCLE
531 5732 : drij = SQRT(drij)
532 : CALL gal21_energy(pot_loc, gal21, r_last_update_pbc, atom_a, atom_b, &
533 5732 : cell, particle_set, mm_section)
534 :
535 9492 : pot_manybody = pot_manybody + pot_loc
536 : END DO
537 701 : ifirst = ilast + 1
538 710 : IF (ipair <= npairs) junique = sort_list(1, ipair)
539 : END DO
540 9 : DEALLOCATE (sort_list, work_list)
541 : END IF
542 : END DO
543 : END DO Kind_Group_Loop_5
544 : END DO
545 1 : CALL destroy_gal21_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
546 : END IF
547 :
548 81972 : CALL timestop(handle)
549 81972 : END SUBROUTINE energy_manybody
550 :
551 : ! **************************************************************************************************
552 : !> \brief ...
553 : !> \param fist_nonbond_env ...
554 : !> \param particle_set ...
555 : !> \param cell ...
556 : !> \param f_nonbond ...
557 : !> \param pv_nonbond ...
558 : !> \param use_virial ...
559 : !> \par History
560 : !> Fast implementation of the tersoff potential - [tlaino] 2007
561 : !> \author I-Feng W. Kuo, Teodoro Laino
562 : ! **************************************************************************************************
563 72592 : SUBROUTINE force_nonbond_manybody(fist_nonbond_env, particle_set, cell, &
564 72592 : f_nonbond, pv_nonbond, use_virial)
565 :
566 : TYPE(fist_nonbond_env_type), POINTER :: fist_nonbond_env
567 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
568 : TYPE(cell_type), POINTER :: cell
569 : REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: f_nonbond, pv_nonbond
570 : LOGICAL, INTENT(IN) :: use_virial
571 :
572 : CHARACTER(LEN=*), PARAMETER :: routineN = 'force_nonbond_manybody'
573 :
574 : INTEGER :: atom_a, atom_b, handle, i, i_a, i_b, iend, ifirst, igrp, ikind, ilast, ilist, &
575 : ipair, istart, iunique, jkind, junique, kind_a, kind_b, mpair, nkinds, nloc_size, npairs, &
576 : nunique
577 72592 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: eam_kinds_index
578 72592 : INTEGER, DIMENSION(:), POINTER :: glob_loc_list_a, work_list
579 72592 : INTEGER, DIMENSION(:, :), POINTER :: glob_loc_list, list, sort_list
580 : LOGICAL :: any_ace, any_allegro, any_deepmd, &
581 : any_gal, any_gal21, any_nequip, &
582 : any_siepmann, any_tersoff
583 : REAL(KIND=dp) :: f_eam, fac, fr(3), ptens11, ptens12, ptens13, ptens21, ptens22, ptens23, &
584 : ptens31, ptens32, ptens33, rab(3), rab2, rab2_max, rtmp(3)
585 : REAL(KIND=dp), DIMENSION(3) :: cell_v, cvi
586 72592 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: glob_cell_v
587 : TYPE(eam_pot_type), POINTER :: eam_a, eam_b
588 72592 : TYPE(eam_type), DIMENSION(:), POINTER :: eam_data
589 : TYPE(fist_neighbor_type), POINTER :: nonbonded
590 : TYPE(gal21_pot_type), POINTER :: gal21
591 : TYPE(gal_pot_type), POINTER :: gal
592 : TYPE(neighbor_kind_pairs_type), POINTER :: neighbor_kind_pair
593 : TYPE(pair_potential_pp_type), POINTER :: potparm
594 : TYPE(pair_potential_single_type), POINTER :: pot
595 72592 : TYPE(pos_type), DIMENSION(:), POINTER :: r_last_update_pbc
596 : TYPE(siepmann_pot_type), POINTER :: siepmann
597 : TYPE(tersoff_pot_type), POINTER :: tersoff
598 :
599 72592 : any_tersoff = .FALSE.
600 72592 : any_allegro = .FALSE.
601 72592 : any_nequip = .FALSE.
602 72592 : any_siepmann = .FALSE.
603 72592 : any_ace = .FALSE.
604 72592 : any_deepmd = .FALSE.
605 72592 : any_gal = .FALSE.
606 72592 : any_gal21 = .FALSE.
607 72592 : CALL timeset(routineN, handle)
608 72592 : NULLIFY (eam_a, eam_b, tersoff, siepmann, gal, gal21)
609 :
610 : CALL fist_nonbond_env_get(fist_nonbond_env, nonbonded=nonbonded, potparm=potparm, &
611 72592 : natom_types=nkinds, eam_data=eam_data, r_last_update_pbc=r_last_update_pbc)
612 :
613 : ! Initializing the potential energy, pressure tensor and force
614 : IF (use_virial) THEN
615 : ptens11 = 0.0_dp; ptens12 = 0.0_dp; ptens13 = 0.0_dp
616 : ptens21 = 0.0_dp; ptens22 = 0.0_dp; ptens23 = 0.0_dp
617 : ptens31 = 0.0_dp; ptens32 = 0.0_dp; ptens33 = 0.0_dp
618 : END IF
619 :
620 72592 : nkinds = SIZE(potparm%pot, 1)
621 290368 : ALLOCATE (eam_kinds_index(nkinds, nkinds))
622 2967680 : eam_kinds_index = -1
623 287108 : DO ikind = 1, nkinds
624 1734652 : DO jkind = ikind, nkinds
625 3109652 : DO i = 1, SIZE(potparm%pot(ikind, jkind)%pot%type)
626 2895136 : IF (potparm%pot(ikind, jkind)%pot%type(i) == ea_type) THEN
627 : ! At the moment we allow only 1 EAM per each kinds pair..
628 692 : CPASSERT(eam_kinds_index(ikind, jkind) == -1)
629 692 : CPASSERT(eam_kinds_index(jkind, ikind) == -1)
630 692 : eam_kinds_index(ikind, jkind) = i
631 692 : eam_kinds_index(jkind, ikind) = i
632 : END IF
633 : END DO
634 : END DO
635 : END DO
636 287108 : DO ikind = 1, nkinds
637 1734652 : DO jkind = ikind, nkinds
638 3109034 : any_ace = any_ace .OR. ANY(potparm%pot(ikind, jkind)%pot%type == ace_type)
639 : END DO
640 : END DO
641 : ! ACE
642 72592 : IF (any_ace) &
643 206 : CALL ace_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
644 :
645 287108 : DO ikind = 1, nkinds
646 1734652 : DO jkind = ikind, nkinds
647 3109646 : any_deepmd = any_deepmd .OR. ANY(potparm%pot(ikind, jkind)%pot%type == deepmd_type)
648 : END DO
649 : END DO
650 : ! DEEPMD
651 72592 : IF (any_deepmd) &
652 2 : CALL deepmd_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
653 :
654 : ! NEQUIP
655 287108 : DO ikind = 1, nkinds
656 1734652 : DO jkind = ikind, nkinds
657 3109646 : any_nequip = any_nequip .OR. ANY(potparm%pot(ikind, jkind)%pot%type == nequip_type)
658 : END DO
659 : END DO
660 72592 : IF (any_nequip) THEN
661 2 : CALL nequip_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
662 : END IF
663 :
664 : ! ALLEGRO
665 287108 : DO ikind = 1, nkinds
666 1734652 : DO jkind = ikind, nkinds
667 3109646 : any_allegro = any_allegro .OR. ANY(potparm%pot(ikind, jkind)%pot%type == allegro_type)
668 : END DO
669 : END DO
670 72592 : IF (any_allegro) THEN
671 2 : CALL nequip_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
672 : END IF
673 :
674 : ! starting the force loop
675 8259630 : DO ilist = 1, nonbonded%nlists
676 8187038 : neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
677 8187038 : npairs = neighbor_kind_pair%npairs
678 8187038 : IF (npairs == 0) CYCLE
679 10173568 : Kind_Group_Loop1: DO igrp = 1, neighbor_kind_pair%ngrp_kind
680 7775929 : istart = neighbor_kind_pair%grp_kind_start(igrp)
681 7775929 : iend = neighbor_kind_pair%grp_kind_end(igrp)
682 7775929 : ikind = neighbor_kind_pair%ij_kind(1, igrp)
683 7775929 : jkind = neighbor_kind_pair%ij_kind(2, igrp)
684 7775929 : list => neighbor_kind_pair%list
685 31103716 : cvi = neighbor_kind_pair%cell_vector
686 7775929 : pot => potparm%pot(ikind, jkind)%pot
687 7775929 : IF (pot%no_mb) CYCLE Kind_Group_Loop1
688 73321 : rab2_max = pot%rcutsq
689 953173 : cell_v = MATMUL(cell%hmat, cvi)
690 103821 : any_tersoff = any_tersoff .OR. ANY(pot%type == tersoff_type)
691 146479 : any_siepmann = any_siepmann .OR. ANY(pot%type == siepmann_type)
692 130130 : any_ace = any_ace .OR. ANY(pot%type == ace_type)
693 146642 : any_deepmd = any_deepmd .OR. ANY(pot%type == deepmd_type)
694 146635 : any_gal = any_gal .OR. ANY(pot%type == gal_type)
695 146635 : any_gal21 = any_gal21 .OR. ANY(pot%type == gal21_type)
696 146512 : any_nequip = any_nequip .OR. ANY(pot%type == nequip_type)
697 146512 : any_allegro = any_allegro .OR. ANY(pot%type == allegro_type)
698 73321 : i = eam_kinds_index(ikind, jkind)
699 73321 : IF (i == -1) CYCLE Kind_Group_Loop1
700 : ! EAM
701 13535 : CPASSERT(ASSOCIATED(eam_data))
702 8358474 : DO ipair = istart, iend
703 157901 : atom_a = list(1, ipair)
704 157901 : atom_b = list(2, ipair)
705 157901 : fac = 1.0_dp
706 157901 : IF (atom_a == atom_b) fac = 0.5_dp
707 157901 : kind_a = particle_set(atom_a)%atomic_kind%kind_number
708 157901 : kind_b = particle_set(atom_b)%atomic_kind%kind_number
709 157901 : i_a = eam_kinds_index(kind_a, kind_a)
710 157901 : i_b = eam_kinds_index(kind_b, kind_b)
711 157901 : eam_a => potparm%pot(kind_a, kind_a)%pot%set(i_a)%eam
712 157901 : eam_b => potparm%pot(kind_b, kind_b)%pot%set(i_b)%eam
713 :
714 : !set this outside the potential type in case need multiple potentials
715 : !Do everything necessary for EAM here
716 631604 : rab = r_last_update_pbc(atom_b)%r - r_last_update_pbc(atom_a)%r
717 631604 : rab = rab + cell_v
718 157901 : rab2 = rab(1)*rab(1) + rab(2)*rab(2) + rab(3)*rab(3)
719 7933830 : IF (rab2 <= rab2_max) THEN
720 97493 : CALL get_force_eam(rab2, eam_a, eam_b, eam_data, atom_a, atom_b, f_eam)
721 97493 : f_eam = f_eam*fac
722 :
723 97493 : fr(1) = -f_eam*rab(1)
724 97493 : fr(2) = -f_eam*rab(2)
725 97493 : fr(3) = -f_eam*rab(3)
726 97493 : f_nonbond(1, atom_a) = f_nonbond(1, atom_a) - fr(1)
727 97493 : f_nonbond(2, atom_a) = f_nonbond(2, atom_a) - fr(2)
728 97493 : f_nonbond(3, atom_a) = f_nonbond(3, atom_a) - fr(3)
729 :
730 97493 : f_nonbond(1, atom_b) = f_nonbond(1, atom_b) + fr(1)
731 97493 : f_nonbond(2, atom_b) = f_nonbond(2, atom_b) + fr(2)
732 97493 : f_nonbond(3, atom_b) = f_nonbond(3, atom_b) + fr(3)
733 97493 : IF (use_virial) THEN
734 4112 : ptens11 = ptens11 + rab(1)*fr(1)
735 4112 : ptens21 = ptens21 + rab(2)*fr(1)
736 4112 : ptens31 = ptens31 + rab(3)*fr(1)
737 4112 : ptens12 = ptens12 + rab(1)*fr(2)
738 4112 : ptens22 = ptens22 + rab(2)*fr(2)
739 4112 : ptens32 = ptens32 + rab(3)*fr(2)
740 4112 : ptens13 = ptens13 + rab(1)*fr(3)
741 4112 : ptens23 = ptens23 + rab(2)*fr(3)
742 4112 : ptens33 = ptens33 + rab(3)*fr(3)
743 : END IF
744 : END IF
745 : END DO
746 : END DO Kind_Group_Loop1
747 : END DO
748 72592 : DEALLOCATE (eam_kinds_index)
749 :
750 : ! Special way of handling the tersoff potential..
751 72592 : IF (any_tersoff) THEN
752 3124 : NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
753 3124 : CALL setup_tersoff_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
754 115500 : DO ilist = 1, nonbonded%nlists
755 112376 : neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
756 112376 : npairs = neighbor_kind_pair%npairs
757 112376 : IF (npairs == 0) CYCLE
758 87731 : Kind_Group_Loop2: DO igrp = 1, neighbor_kind_pair%ngrp_kind
759 42864 : istart = neighbor_kind_pair%grp_kind_start(igrp)
760 42864 : iend = neighbor_kind_pair%grp_kind_end(igrp)
761 42864 : ikind = neighbor_kind_pair%ij_kind(1, igrp)
762 42864 : jkind = neighbor_kind_pair%ij_kind(2, igrp)
763 42864 : list => neighbor_kind_pair%list
764 171456 : cvi = neighbor_kind_pair%cell_vector
765 42864 : pot => potparm%pot(ikind, jkind)%pot
766 :
767 42864 : IF (pot%no_mb) CYCLE Kind_Group_Loop2
768 42828 : rab2_max = pot%rcutsq
769 556764 : cell_v = MATMUL(cell%hmat, cvi)
770 198034 : DO i = 1, SIZE(pot%type)
771 : ! TERSOFF
772 85694 : IF (pot%type(i) == tersoff_type) THEN
773 42823 : npairs = iend - istart + 1
774 42823 : tersoff => pot%set(i)%tersoff
775 214115 : ALLOCATE (sort_list(2, npairs), work_list(npairs))
776 45965126 : sort_list = list(:, istart:iend)
777 : ! Sort the list of neighbors, this increases the efficiency for single
778 : ! potential contributions
779 42823 : CALL sort(sort_list(1, :), npairs, work_list)
780 7689403 : DO ipair = 1, npairs
781 7689403 : work_list(ipair) = sort_list(2, work_list(ipair))
782 : END DO
783 15378806 : sort_list(2, :) = work_list
784 : ! find number of unique elements of array index 1
785 42823 : nunique = 1
786 7646580 : DO ipair = 1, npairs - 1
787 7646580 : IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
788 : END DO
789 42823 : ipair = 1
790 42823 : junique = sort_list(1, ipair)
791 42823 : ifirst = 1
792 494916 : DO iunique = 1, nunique
793 452093 : atom_a = junique
794 452093 : IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
795 93196653 : DO mpair = ifirst, SIZE(glob_loc_list_a)
796 93196653 : IF (glob_loc_list_a(mpair) == atom_a) EXIT
797 : END DO
798 110993591 : ifirst = mpair
799 110993591 : DO mpair = ifirst, SIZE(glob_loc_list_a)
800 110993591 : IF (glob_loc_list_a(mpair) /= atom_a) EXIT
801 : END DO
802 452093 : ilast = mpair - 1
803 452093 : nloc_size = 0
804 452093 : IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
805 8098673 : DO WHILE (ipair <= npairs)
806 8055850 : IF (sort_list(1, ipair) /= junique) EXIT
807 7646580 : atom_b = sort_list(2, ipair)
808 : ! Derivative terms
809 30586320 : rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
810 7646580 : ipair = ipair + 1
811 31038413 : IF (DOT_PRODUCT(rtmp, rtmp) <= tersoff%rcutsq) THEN
812 : CALL tersoff_forces(tersoff, r_last_update_pbc, cell_v, &
813 : nloc_size, glob_loc_list(:, ifirst:ilast), glob_cell_v(:, ifirst:ilast), &
814 330372 : atom_a, atom_b, f_nonbond, pv_nonbond, use_virial, tersoff%rcutsq)
815 : END IF
816 : END DO
817 452093 : ifirst = ilast + 1
818 494916 : IF (ipair <= npairs) junique = sort_list(1, ipair)
819 : END DO
820 42823 : DEALLOCATE (sort_list, work_list)
821 : END IF
822 : END DO
823 : END DO Kind_Group_Loop2
824 : END DO
825 3124 : CALL destroy_tersoff_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
826 : END IF
827 : ! Special way of handling the siepmann potential..
828 72592 : IF (any_siepmann) THEN
829 21 : NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
830 21 : CALL setup_siepmann_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
831 588 : DO ilist = 1, nonbonded%nlists
832 567 : neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
833 567 : npairs = neighbor_kind_pair%npairs
834 567 : IF (npairs == 0) CYCLE
835 918 : Kind_Group_Loop3: DO igrp = 1, neighbor_kind_pair%ngrp_kind
836 708 : istart = neighbor_kind_pair%grp_kind_start(igrp)
837 708 : iend = neighbor_kind_pair%grp_kind_end(igrp)
838 708 : ikind = neighbor_kind_pair%ij_kind(1, igrp)
839 708 : jkind = neighbor_kind_pair%ij_kind(2, igrp)
840 708 : list => neighbor_kind_pair%list
841 2832 : cvi = neighbor_kind_pair%cell_vector
842 708 : pot => potparm%pot(ikind, jkind)%pot
843 :
844 708 : IF (pot%no_mb) CYCLE Kind_Group_Loop3
845 165 : rab2_max = pot%rcutsq
846 2145 : cell_v = MATMUL(cell%hmat, cvi)
847 897 : DO i = 1, SIZE(pot%type)
848 : ! SIEPMANN
849 873 : IF (pot%type(i) == siepmann_type) THEN
850 165 : npairs = iend - istart + 1
851 165 : siepmann => pot%set(i)%siepmann
852 825 : ALLOCATE (sort_list(2, npairs), work_list(npairs))
853 109698 : sort_list = list(:, istart:iend)
854 : ! Sort the list of neighbors, this increases the efficiency for single
855 : ! potential contributions
856 165 : CALL sort(sort_list(1, :), npairs, work_list)
857 18393 : DO ipair = 1, npairs
858 18393 : work_list(ipair) = sort_list(2, work_list(ipair))
859 : END DO
860 36786 : sort_list(2, :) = work_list
861 : ! find number of unique elements of array index 1
862 165 : nunique = 1
863 18228 : DO ipair = 1, npairs - 1
864 18228 : IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
865 : END DO
866 165 : ipair = 1
867 165 : junique = sort_list(1, ipair)
868 165 : ifirst = 1
869 5340 : DO iunique = 1, nunique
870 5175 : atom_a = junique
871 5175 : IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
872 91602 : DO mpair = ifirst, SIZE(glob_loc_list_a)
873 91602 : IF (glob_loc_list_a(mpair) == atom_a) EXIT
874 : END DO
875 62187 : ifirst = mpair
876 62187 : DO mpair = ifirst, SIZE(glob_loc_list_a)
877 62187 : IF (glob_loc_list_a(mpair) /= atom_a) EXIT
878 : END DO
879 5175 : ilast = mpair - 1
880 5175 : nloc_size = 0
881 5175 : IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
882 23403 : DO WHILE (ipair <= npairs)
883 23238 : IF (sort_list(1, ipair) /= junique) EXIT
884 18228 : atom_b = sort_list(2, ipair)
885 : ! Derivative terms
886 72912 : rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
887 18228 : ipair = ipair + 1
888 78087 : IF (DOT_PRODUCT(rtmp, rtmp) <= siepmann%rcutsq) THEN
889 : CALL siepmann_forces_v2(siepmann, r_last_update_pbc, cell_v, cell, &
890 : atom_a, atom_b, f_nonbond, use_virial, siepmann%rcutsq, &
891 318 : particle_set)
892 : CALL siepmann_forces_v3(siepmann, r_last_update_pbc, cell_v, &
893 : nloc_size, glob_loc_list(:, ifirst:ilast), &
894 : atom_a, atom_b, f_nonbond, use_virial, siepmann%rcutsq, &
895 318 : cell, particle_set)
896 : END IF
897 : END DO
898 5175 : ifirst = ilast + 1
899 5340 : IF (ipair <= npairs) junique = sort_list(1, ipair)
900 : END DO
901 165 : DEALLOCATE (sort_list, work_list)
902 : END IF
903 : END DO
904 : END DO Kind_Group_Loop3
905 : END DO
906 21 : CALL destroy_siepmann_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
907 : END IF
908 :
909 : ! GAL19 potential..
910 72592 : IF (any_gal) THEN
911 1 : NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
912 1 : CALL setup_gal_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
913 28 : DO ilist = 1, nonbonded%nlists
914 27 : neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
915 27 : npairs = neighbor_kind_pair%npairs
916 27 : IF (npairs == 0) CYCLE
917 168 : Kind_Group_Loop4: DO igrp = 1, neighbor_kind_pair%ngrp_kind
918 158 : istart = neighbor_kind_pair%grp_kind_start(igrp)
919 158 : iend = neighbor_kind_pair%grp_kind_end(igrp)
920 158 : ikind = neighbor_kind_pair%ij_kind(1, igrp)
921 158 : jkind = neighbor_kind_pair%ij_kind(2, igrp)
922 158 : list => neighbor_kind_pair%list
923 632 : cvi = neighbor_kind_pair%cell_vector
924 158 : pot => potparm%pot(ikind, jkind)%pot
925 :
926 158 : IF (pot%no_mb) CYCLE Kind_Group_Loop4
927 9 : rab2_max = pot%rcutsq
928 117 : cell_v = MATMUL(cell%hmat, cvi)
929 45 : DO i = 1, SIZE(pot%type)
930 : ! GAL19
931 167 : IF (pot%type(i) == gal_type) THEN
932 9 : npairs = iend - istart + 1
933 9 : gal => pot%set(i)%gal
934 45 : ALLOCATE (sort_list(2, npairs), work_list(npairs))
935 45618 : sort_list = list(:, istart:iend)
936 : ! Sort the list of neighbors, this increases the efficiency for single
937 : ! potential contributions
938 9 : CALL sort(sort_list(1, :), npairs, work_list)
939 7609 : DO ipair = 1, npairs
940 7609 : work_list(ipair) = sort_list(2, work_list(ipair))
941 : END DO
942 15218 : sort_list(2, :) = work_list
943 : ! find number of unique elements of array index 1
944 9 : nunique = 1
945 7600 : DO ipair = 1, npairs - 1
946 7600 : IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
947 : END DO
948 9 : ipair = 1
949 9 : junique = sort_list(1, ipair)
950 9 : ifirst = 1
951 659 : DO iunique = 1, nunique
952 650 : atom_a = junique
953 650 : IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
954 36198 : DO mpair = ifirst, SIZE(glob_loc_list_a)
955 36198 : IF (glob_loc_list_a(mpair) == atom_a) EXIT
956 : END DO
957 24581 : ifirst = mpair
958 24581 : DO mpair = ifirst, SIZE(glob_loc_list_a)
959 24581 : IF (glob_loc_list_a(mpair) /= atom_a) EXIT
960 : END DO
961 650 : ilast = mpair - 1
962 650 : nloc_size = 0
963 650 : IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
964 8250 : DO WHILE (ipair <= npairs)
965 8241 : IF (sort_list(1, ipair) /= junique) EXIT
966 7600 : atom_b = sort_list(2, ipair)
967 : ! Derivative terms
968 30400 : rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
969 7600 : ipair = ipair + 1
970 31050 : IF (DOT_PRODUCT(rtmp, rtmp) <= gal%rcutsq) THEN
971 : CALL gal_forces(gal, r_last_update_pbc, &
972 : atom_a, atom_b, f_nonbond, use_virial, &
973 2004 : cell, particle_set)
974 : END IF
975 : END DO
976 650 : ifirst = ilast + 1
977 659 : IF (ipair <= npairs) junique = sort_list(1, ipair)
978 : END DO
979 9 : DEALLOCATE (sort_list, work_list)
980 : END IF
981 : END DO
982 : END DO Kind_Group_Loop4
983 : END DO
984 1 : CALL destroy_gal_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
985 : END IF
986 :
987 : ! GAL21 potential..
988 72592 : IF (any_gal21) THEN
989 1 : NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
990 1 : CALL setup_gal21_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
991 28 : DO ilist = 1, nonbonded%nlists
992 27 : neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
993 27 : npairs = neighbor_kind_pair%npairs
994 27 : IF (npairs == 0) CYCLE
995 168 : Kind_Group_Loop6: DO igrp = 1, neighbor_kind_pair%ngrp_kind
996 158 : istart = neighbor_kind_pair%grp_kind_start(igrp)
997 158 : iend = neighbor_kind_pair%grp_kind_end(igrp)
998 158 : ikind = neighbor_kind_pair%ij_kind(1, igrp)
999 158 : jkind = neighbor_kind_pair%ij_kind(2, igrp)
1000 158 : list => neighbor_kind_pair%list
1001 632 : cvi = neighbor_kind_pair%cell_vector
1002 158 : pot => potparm%pot(ikind, jkind)%pot
1003 :
1004 158 : IF (pot%no_mb) CYCLE Kind_Group_Loop6
1005 9 : rab2_max = pot%rcutsq
1006 117 : cell_v = MATMUL(cell%hmat, cvi)
1007 45 : DO i = 1, SIZE(pot%type)
1008 : ! GAL21
1009 167 : IF (pot%type(i) == gal21_type) THEN
1010 9 : npairs = iend - istart + 1
1011 9 : gal21 => pot%set(i)%gal21
1012 45 : ALLOCATE (sort_list(2, npairs), work_list(npairs))
1013 52818 : sort_list = list(:, istart:iend)
1014 : ! Sort the list of neighbors, this increases the efficiency for single
1015 : ! potential contributions
1016 9 : CALL sort(sort_list(1, :), npairs, work_list)
1017 8809 : DO ipair = 1, npairs
1018 8809 : work_list(ipair) = sort_list(2, work_list(ipair))
1019 : END DO
1020 17618 : sort_list(2, :) = work_list
1021 : ! find number of unique elements of array index 1
1022 9 : nunique = 1
1023 8800 : DO ipair = 1, npairs - 1
1024 8800 : IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
1025 : END DO
1026 9 : ipair = 1
1027 9 : junique = sort_list(1, ipair)
1028 9 : ifirst = 1
1029 710 : DO iunique = 1, nunique
1030 701 : atom_a = junique
1031 701 : IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
1032 42242 : DO mpair = ifirst, SIZE(glob_loc_list_a)
1033 42242 : IF (glob_loc_list_a(mpair) == atom_a) EXIT
1034 : END DO
1035 30069 : ifirst = mpair
1036 30069 : DO mpair = ifirst, SIZE(glob_loc_list_a)
1037 30069 : IF (glob_loc_list_a(mpair) /= atom_a) EXIT
1038 : END DO
1039 701 : ilast = mpair - 1
1040 701 : nloc_size = 0
1041 701 : IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
1042 9501 : DO WHILE (ipair <= npairs)
1043 9492 : IF (sort_list(1, ipair) /= junique) EXIT
1044 8800 : atom_b = sort_list(2, ipair)
1045 : ! Derivative terms
1046 35200 : rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
1047 8800 : ipair = ipair + 1
1048 35901 : IF (DOT_PRODUCT(rtmp, rtmp) <= gal21%rcutsq) THEN
1049 : CALL gal21_forces(gal21, r_last_update_pbc, &
1050 : atom_a, atom_b, f_nonbond, pv_nonbond, use_virial, &
1051 5732 : cell, particle_set)
1052 : END IF
1053 : END DO
1054 701 : ifirst = ilast + 1
1055 710 : IF (ipair <= npairs) junique = sort_list(1, ipair)
1056 : END DO
1057 9 : DEALLOCATE (sort_list, work_list)
1058 : END IF
1059 : END DO
1060 : END DO Kind_Group_Loop6
1061 : END DO
1062 1 : CALL destroy_gal_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
1063 : END IF
1064 :
1065 72592 : IF (use_virial) THEN
1066 9346 : pv_nonbond(1, 1) = pv_nonbond(1, 1) + ptens11
1067 9346 : pv_nonbond(1, 2) = pv_nonbond(1, 2) + ptens12
1068 9346 : pv_nonbond(1, 3) = pv_nonbond(1, 3) + ptens13
1069 9346 : pv_nonbond(2, 1) = pv_nonbond(2, 1) + ptens21
1070 9346 : pv_nonbond(2, 2) = pv_nonbond(2, 2) + ptens22
1071 9346 : pv_nonbond(2, 3) = pv_nonbond(2, 3) + ptens23
1072 9346 : pv_nonbond(3, 1) = pv_nonbond(3, 1) + ptens31
1073 9346 : pv_nonbond(3, 2) = pv_nonbond(3, 2) + ptens32
1074 9346 : pv_nonbond(3, 3) = pv_nonbond(3, 3) + ptens33
1075 : END IF
1076 72592 : CALL timestop(handle)
1077 72592 : END SUBROUTINE force_nonbond_manybody
1078 :
1079 : END MODULE manybody_potential
1080 :
|