(git:e5b1968)
Loading...
Searching...
No Matches
manybody_potential.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 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! **************************************************************************************************
17
19 USE cell_types, ONLY: cell_type
28 USE kinds, ONLY: dp
63 USE pair_potential_types, ONLY: &
69 USE util, ONLY: sort
70#include "./base/base_uses.f90"
71
72 IMPLICIT NONE
73
74 PRIVATE
75 PUBLIC :: energy_manybody
77 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'manybody_potential'
78
79CONTAINS
80
81! **************************************************************************************************
82!> \brief computes the embedding contribution to the energy
83!> \param fist_nonbond_env ...
84!> \param atomic_kind_set ...
85!> \param local_particles ...
86!> \param particle_set ...
87!> \param cell ...
88!> \param pot_manybody ...
89!> \param para_env ...
90!> \param mm_section ...
91!> \param use_virial ...
92!> \par History
93!> tlaino [2007] - New algorithm for tersoff potential
94!> \author CJM, I-Feng W. Kuo, Teodoro Laino
95! **************************************************************************************************
96 SUBROUTINE energy_manybody(fist_nonbond_env, atomic_kind_set, local_particles, &
97 particle_set, cell, pot_manybody, para_env, mm_section, use_virial)
98
99 TYPE(fist_nonbond_env_type), POINTER :: fist_nonbond_env
100 TYPE(atomic_kind_type), POINTER :: atomic_kind_set(:)
101 TYPE(distribution_1d_type), POINTER :: local_particles
102 TYPE(particle_type), POINTER :: particle_set(:)
103 TYPE(cell_type), POINTER :: cell
104 REAL(dp), INTENT(INOUT) :: pot_manybody
105 TYPE(mp_para_env_type), OPTIONAL, POINTER :: para_env
106 TYPE(section_vals_type), POINTER :: mm_section
107 LOGICAL, INTENT(IN) :: use_virial
108
109 CHARACTER(LEN=*), PARAMETER :: routinen = 'energy_manybody'
110
111 INTEGER :: atom_a, atom_b, handle, i, iend, ifirst, igrp, ikind, ilast, ilist, indexa, &
112 ipair, iparticle, iparticle_local, istart, iunique, jkind, junique, mpair, nkinds, &
113 nloc_size, npairs, nparticle, nparticle_local, nr_h3o, nr_o, nr_oh, nunique
114 INTEGER, DIMENSION(:), POINTER :: glob_loc_list_a, unique_list_a, work_list
115 INTEGER, DIMENSION(:, :), POINTER :: glob_loc_list, list, sort_list
116 LOGICAL :: any_ace, any_allegro, any_deepmd, &
117 any_gal, any_gal21, any_nequip, &
118 any_quip, any_siepmann, any_tersoff
119 REAL(kind=dp) :: drij, embed, pot_ace, pot_allegro, &
120 pot_deepmd, pot_loc, pot_nequip, &
121 pot_quip, qr, rab2_max, rij(3)
122 REAL(kind=dp), DIMENSION(3) :: cell_v, cvi
123 REAL(kind=dp), DIMENSION(:, :), POINTER :: glob_cell_v
124 REAL(kind=dp), POINTER :: fembed(:)
125 TYPE(allegro_pot_type), POINTER :: allegro
126 TYPE(eam_pot_type), POINTER :: eam
127 TYPE(eam_type), DIMENSION(:), POINTER :: eam_data
128 TYPE(fist_neighbor_type), POINTER :: nonbonded
129 TYPE(gal21_pot_type), POINTER :: gal21
130 TYPE(gal_pot_type), POINTER :: gal
131 TYPE(neighbor_kind_pairs_type), POINTER :: neighbor_kind_pair
132 TYPE(nequip_pot_type), POINTER :: nequip
133 TYPE(pair_potential_pp_type), POINTER :: potparm
134 TYPE(pair_potential_single_type), POINTER :: pot
135 TYPE(pos_type), DIMENSION(:), POINTER :: r_last_update_pbc
136 TYPE(siepmann_pot_type), POINTER :: siepmann
137 TYPE(tersoff_pot_type), POINTER :: tersoff
138
139 NULLIFY (eam, siepmann, tersoff, gal, gal21)
140 any_tersoff = .false.
141 any_siepmann = .false.
142 any_gal = .false.
143 any_gal21 = .false.
144 any_quip = .false.
145 any_nequip = .false.
146 any_allegro = .false.
147 any_ace = .false.
148 any_deepmd = .false.
149 CALL timeset(routinen, handle)
150 CALL fist_nonbond_env_get(fist_nonbond_env, r_last_update_pbc=r_last_update_pbc, &
151 potparm=potparm, eam_data=eam_data)
152 ! EAM requires a single loop
153 DO ikind = 1, SIZE(atomic_kind_set)
154 pot => potparm%pot(ikind, ikind)%pot
155 DO i = 1, SIZE(pot%type)
156 IF (pot%type(i) /= ea_type) cycle
157 eam => pot%set(i)%eam
158 nparticle = SIZE(particle_set)
159 ALLOCATE (fembed(nparticle))
160 fembed(:) = 0._dp
161 cpassert(ASSOCIATED(eam_data))
162 ! computation of embedding function and energy
163 nparticle_local = local_particles%n_el(ikind)
164 DO iparticle_local = 1, nparticle_local
165 iparticle = local_particles%list(ikind)%array(iparticle_local)
166 indexa = int(eam_data(iparticle)%rho/eam%drhoar) + 1
167 IF (indexa > eam%npoints - 1) indexa = eam%npoints - 1
168 qr = eam_data(iparticle)%rho - eam%rhoval(indexa)
169
170 embed = eam%frho(indexa) + qr*eam%frhop(indexa)
171 fembed(iparticle) = eam%frhop(indexa) + qr*(eam%frhop(indexa + 1) - eam%frhop(indexa))/eam%drhoar
172
173 pot_manybody = pot_manybody + embed
174 END DO
175 ! communicate data
176 CALL para_env%sum(fembed)
177 DO iparticle = 1, nparticle
178 IF (particle_set(iparticle)%atomic_kind%kind_number == ikind) THEN
179 eam_data(iparticle)%f_embed = fembed(iparticle)
180 END IF
181 END DO
182
183 DEALLOCATE (fembed)
184 END DO
185 END DO
186 ! Other manybody potential
187 DO ikind = 1, SIZE(atomic_kind_set)
188 DO jkind = ikind, SIZE(atomic_kind_set)
189 pot => potparm%pot(ikind, jkind)%pot
190 any_tersoff = any_tersoff .OR. any(pot%type == tersoff_type)
191 any_quip = any_quip .OR. any(pot%type == quip_type)
192 any_nequip = any_nequip .OR. any(pot%type == nequip_type)
193 any_allegro = any_allegro .OR. any(pot%type == allegro_type)
194 any_ace = any_ace .OR. any(pot%type == ace_type)
195 any_deepmd = any_deepmd .OR. any(pot%type == deepmd_type)
196 any_siepmann = any_siepmann .OR. any(pot%type == siepmann_type)
197 any_gal = any_gal .OR. any(pot%type == gal_type)
198 any_gal21 = any_gal21 .OR. any(pot%type == gal21_type)
199 END DO
200 END DO
201 CALL fist_nonbond_env_get(fist_nonbond_env, nonbonded=nonbonded, natom_types=nkinds)
202 ! QUIP
203 IF (any_quip) THEN
204 CALL quip_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, &
205 fist_nonbond_env, pot_quip, para_env)
206 pot_manybody = pot_manybody + pot_quip
207 END IF
208 ! NEQUIP
209 IF (any_nequip) THEN
210 NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
211 CALL setup_nequip_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
212 CALL nequip_energy_store_force_virial(nonbonded, particle_set, cell, atomic_kind_set, potparm, &
213 nequip, glob_loc_list_a, r_last_update_pbc, pot_nequip, &
214 fist_nonbond_env, para_env, use_virial)
215 pot_manybody = pot_manybody + pot_nequip
216 CALL destroy_nequip_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
217 END IF
218 ! ALLEGRO
219 IF (any_allegro) THEN
220 NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a, unique_list_a)
221 CALL setup_allegro_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, &
222 unique_list_a, cell)
223 CALL allegro_energy_store_force_virial(nonbonded, particle_set, cell, atomic_kind_set, potparm, &
224 allegro, glob_loc_list_a, r_last_update_pbc, pot_allegro, &
225 fist_nonbond_env, unique_list_a, para_env, use_virial)
226 pot_manybody = pot_manybody + pot_allegro
227 CALL destroy_allegro_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a, unique_list_a)
228 END IF
229 ! ACE
230 IF (any_ace) THEN
231 CALL ace_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, &
232 fist_nonbond_env, pot_ace)
233 pot_manybody = pot_manybody + pot_ace
234 END IF
235 ! DEEPMD
236 IF (any_deepmd) THEN
237 CALL deepmd_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, &
238 fist_nonbond_env, pot_deepmd, para_env)
239 pot_manybody = pot_manybody + pot_deepmd
240 END IF
241
242 ! TERSOFF
243 IF (any_tersoff) THEN
244 NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
245 CALL setup_tersoff_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
246 DO ilist = 1, nonbonded%nlists
247 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
248 npairs = neighbor_kind_pair%npairs
249 IF (npairs == 0) cycle
250 kind_group_loop: DO igrp = 1, neighbor_kind_pair%ngrp_kind
251 istart = neighbor_kind_pair%grp_kind_start(igrp)
252 iend = neighbor_kind_pair%grp_kind_end(igrp)
253 ikind = neighbor_kind_pair%ij_kind(1, igrp)
254 jkind = neighbor_kind_pair%ij_kind(2, igrp)
255 list => neighbor_kind_pair%list
256 cvi = neighbor_kind_pair%cell_vector
257 pot => potparm%pot(ikind, jkind)%pot
258 DO i = 1, SIZE(pot%type)
259 IF (pot%type(i) /= tersoff_type) cycle
260 rab2_max = pot%set(i)%tersoff%rcutsq
261 cell_v = matmul(cell%hmat, cvi)
262 pot => potparm%pot(ikind, jkind)%pot
263 tersoff => pot%set(i)%tersoff
264 npairs = iend - istart + 1
265 IF (npairs /= 0) THEN
266 ALLOCATE (sort_list(2, npairs), work_list(npairs))
267 sort_list = list(:, istart:iend)
268 ! Sort the list of neighbors, this increases the efficiency for single
269 ! potential contributions
270 CALL sort(sort_list(1, :), npairs, work_list)
271 DO ipair = 1, npairs
272 work_list(ipair) = sort_list(2, work_list(ipair))
273 END DO
274 sort_list(2, :) = work_list
275 ! find number of unique elements of array index 1
276 nunique = 1
277 DO ipair = 1, npairs - 1
278 IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
279 END DO
280 ipair = 1
281 junique = sort_list(1, ipair)
282 ifirst = 1
283 DO iunique = 1, nunique
284 atom_a = junique
285 IF (glob_loc_list_a(ifirst) > atom_a) cycle
286 DO mpair = ifirst, SIZE(glob_loc_list_a)
287 IF (glob_loc_list_a(mpair) == atom_a) EXIT
288 END DO
289 ifirst = mpair
290 DO mpair = ifirst, SIZE(glob_loc_list_a)
291 IF (glob_loc_list_a(mpair) /= atom_a) EXIT
292 END DO
293 ilast = mpair - 1
294 nloc_size = 0
295 IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
296 DO WHILE (ipair <= npairs)
297 IF (sort_list(1, ipair) /= junique) EXIT
298 atom_b = sort_list(2, ipair)
299 ! Energy terms
300 pot_loc = 0.0_dp
301 rij(:) = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
302 drij = dot_product(rij, rij)
303 ipair = ipair + 1
304 IF (drij > rab2_max) cycle
305 drij = sqrt(drij)
306 CALL tersoff_energy(pot_loc, tersoff, r_last_update_pbc, atom_a, atom_b, nloc_size, &
307 glob_loc_list(:, ifirst:ilast), glob_cell_v(:, ifirst:ilast), cell_v, drij)
308 pot_manybody = pot_manybody + 0.5_dp*pot_loc
309 END DO
310 ifirst = ilast + 1
311 IF (ipair <= npairs) junique = sort_list(1, ipair)
312 END DO
313 DEALLOCATE (sort_list, work_list)
314 END IF
315 END DO
316 END DO kind_group_loop
317 END DO
318 CALL destroy_tersoff_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
319 END IF
320
321 !SIEPMANN POTENTIAL
322 IF (any_siepmann) THEN
323 NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
324 nr_oh = 0
325 nr_h3o = 0
326 nr_o = 0
327 CALL setup_siepmann_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
328 DO ilist = 1, nonbonded%nlists
329 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
330 npairs = neighbor_kind_pair%npairs
331 IF (npairs == 0) cycle
332 kind_group_loop_2: DO igrp = 1, neighbor_kind_pair%ngrp_kind
333 istart = neighbor_kind_pair%grp_kind_start(igrp)
334 iend = neighbor_kind_pair%grp_kind_end(igrp)
335 ikind = neighbor_kind_pair%ij_kind(1, igrp)
336 jkind = neighbor_kind_pair%ij_kind(2, igrp)
337 list => neighbor_kind_pair%list
338 cvi = neighbor_kind_pair%cell_vector
339 pot => potparm%pot(ikind, jkind)%pot
340 DO i = 1, SIZE(pot%type)
341 IF (pot%type(i) /= siepmann_type) cycle
342 rab2_max = pot%set(i)%siepmann%rcutsq
343 cell_v = matmul(cell%hmat, cvi)
344 pot => potparm%pot(ikind, jkind)%pot
345 siepmann => pot%set(i)%siepmann
346 npairs = iend - istart + 1
347 IF (npairs /= 0) THEN
348 ALLOCATE (sort_list(2, npairs), work_list(npairs))
349 sort_list = list(:, istart:iend)
350 ! Sort the list of neighbors, this increases the efficiency for single
351 ! potential contributions
352 CALL sort(sort_list(1, :), npairs, work_list)
353 DO ipair = 1, npairs
354 work_list(ipair) = sort_list(2, work_list(ipair))
355 END DO
356 sort_list(2, :) = work_list
357 ! find number of unique elements of array index 1
358 nunique = 1
359 DO ipair = 1, npairs - 1
360 IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
361 END DO
362 ipair = 1
363 junique = sort_list(1, ipair)
364 ifirst = 1
365 DO iunique = 1, nunique
366 atom_a = junique
367 IF (glob_loc_list_a(ifirst) > atom_a) cycle
368 DO mpair = ifirst, SIZE(glob_loc_list_a)
369 IF (glob_loc_list_a(mpair) == atom_a) EXIT
370 END DO
371 ifirst = mpair
372 DO mpair = ifirst, SIZE(glob_loc_list_a)
373 IF (glob_loc_list_a(mpair) /= atom_a) EXIT
374 END DO
375 ilast = mpair - 1
376 nloc_size = 0
377 IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
378 DO WHILE (ipair <= npairs)
379 IF (sort_list(1, ipair) /= junique) EXIT
380 atom_b = sort_list(2, ipair)
381 ! Energy terms
382 pot_loc = 0.0_dp
383 rij(:) = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
384 drij = dot_product(rij, rij)
385 ipair = ipair + 1
386 IF (drij > rab2_max) cycle
387 drij = sqrt(drij)
388 CALL siepmann_energy(pot_loc, siepmann, r_last_update_pbc, atom_a, atom_b, nloc_size, &
389 glob_loc_list(:, ifirst:ilast), cell_v, cell, drij, &
390 particle_set, nr_oh, nr_h3o, nr_o)
391 pot_manybody = pot_manybody + pot_loc
392 END DO
393 ifirst = ilast + 1
394 IF (ipair <= npairs) junique = sort_list(1, ipair)
395 END DO
396 DEALLOCATE (sort_list, work_list)
397 END IF
398 END DO
399 END DO kind_group_loop_2
400 END DO
401 CALL destroy_siepmann_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
402 CALL print_nr_ions_siepmann(nr_oh, mm_section, para_env, print_oh=.true., &
403 print_h3o=.false., print_o=.false.)
404 CALL print_nr_ions_siepmann(nr_h3o, mm_section, para_env, print_oh=.false., &
405 print_h3o=.true., print_o=.false.)
406 CALL print_nr_ions_siepmann(nr_o, mm_section, para_env, print_oh=.false., &
407 print_h3o=.false., print_o=.true.)
408 END IF
409
410 !GAL19 POTENTIAL
411 IF (any_gal) THEN
412 NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
413 CALL setup_gal_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
414 DO ilist = 1, nonbonded%nlists
415 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
416 npairs = neighbor_kind_pair%npairs
417 IF (npairs == 0) cycle
418 kind_group_loop_3: DO igrp = 1, neighbor_kind_pair%ngrp_kind
419 istart = neighbor_kind_pair%grp_kind_start(igrp)
420 iend = neighbor_kind_pair%grp_kind_end(igrp)
421 ikind = neighbor_kind_pair%ij_kind(1, igrp)
422 jkind = neighbor_kind_pair%ij_kind(2, igrp)
423 list => neighbor_kind_pair%list
424 cvi = neighbor_kind_pair%cell_vector
425 pot => potparm%pot(ikind, jkind)%pot
426 DO i = 1, SIZE(pot%type)
427 IF (pot%type(i) /= gal_type) cycle
428 rab2_max = pot%set(i)%gal%rcutsq
429 cell_v = matmul(cell%hmat, cvi)
430 pot => potparm%pot(ikind, jkind)%pot
431 gal => pot%set(i)%gal
432 npairs = iend - istart + 1
433 IF (npairs /= 0) THEN
434 ALLOCATE (sort_list(2, npairs), work_list(npairs))
435 sort_list = list(:, istart:iend)
436 ! Sort the list of neighbors, this increases the efficiency for single
437 ! potential contributions
438 CALL sort(sort_list(1, :), npairs, work_list)
439 DO ipair = 1, npairs
440 work_list(ipair) = sort_list(2, work_list(ipair))
441 END DO
442 sort_list(2, :) = work_list
443 ! find number of unique elements of array index 1
444 nunique = 1
445 DO ipair = 1, npairs - 1
446 IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
447 END DO
448 ipair = 1
449 junique = sort_list(1, ipair)
450 ifirst = 1
451 DO iunique = 1, nunique
452 atom_a = junique
453 IF (glob_loc_list_a(ifirst) > atom_a) cycle
454 DO mpair = ifirst, SIZE(glob_loc_list_a)
455 IF (glob_loc_list_a(mpair) == atom_a) EXIT
456 END DO
457 ifirst = mpair
458 DO mpair = ifirst, SIZE(glob_loc_list_a)
459 IF (glob_loc_list_a(mpair) /= atom_a) EXIT
460 END DO
461 ilast = mpair - 1
462 nloc_size = 0
463 IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
464 DO WHILE (ipair <= npairs)
465 IF (sort_list(1, ipair) /= junique) EXIT
466 atom_b = sort_list(2, ipair)
467 ! Energy terms
468 pot_loc = 0.0_dp
469 rij(:) = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
470 drij = dot_product(rij, rij)
471 ipair = ipair + 1
472 IF (drij > rab2_max) cycle
473 drij = sqrt(drij)
474 CALL gal_energy(pot_loc, gal, r_last_update_pbc, atom_a, atom_b, &
475 cell, particle_set, mm_section)
476
477 pot_manybody = pot_manybody + pot_loc
478 END DO
479 ifirst = ilast + 1
480 IF (ipair <= npairs) junique = sort_list(1, ipair)
481 END DO
482 DEALLOCATE (sort_list, work_list)
483 END IF
484 END DO
485 END DO kind_group_loop_3
486 END DO
487 CALL destroy_gal_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
488 END IF
489
490 !GAL21 POTENTIAL
491 IF (any_gal21) THEN
492 NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
493 CALL setup_gal21_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
494 DO ilist = 1, nonbonded%nlists
495 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
496 npairs = neighbor_kind_pair%npairs
497 IF (npairs == 0) cycle
498 kind_group_loop_5: DO igrp = 1, neighbor_kind_pair%ngrp_kind
499 istart = neighbor_kind_pair%grp_kind_start(igrp)
500 iend = neighbor_kind_pair%grp_kind_end(igrp)
501 ikind = neighbor_kind_pair%ij_kind(1, igrp)
502 jkind = neighbor_kind_pair%ij_kind(2, igrp)
503 list => neighbor_kind_pair%list
504 cvi = neighbor_kind_pair%cell_vector
505 pot => potparm%pot(ikind, jkind)%pot
506 DO i = 1, SIZE(pot%type)
507 IF (pot%type(i) /= gal21_type) cycle
508 rab2_max = pot%set(i)%gal21%rcutsq
509 cell_v = matmul(cell%hmat, cvi)
510 pot => potparm%pot(ikind, jkind)%pot
511 gal21 => pot%set(i)%gal21
512 npairs = iend - istart + 1
513 IF (npairs /= 0) THEN
514 ALLOCATE (sort_list(2, npairs), work_list(npairs))
515 sort_list = list(:, istart:iend)
516 ! Sort the list of neighbors, this increases the efficiency for single
517 ! potential contributions
518 CALL sort(sort_list(1, :), npairs, work_list)
519 DO ipair = 1, npairs
520 work_list(ipair) = sort_list(2, work_list(ipair))
521 END DO
522 sort_list(2, :) = work_list
523 ! find number of unique elements of array index 1
524 nunique = 1
525 DO ipair = 1, npairs - 1
526 IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
527 END DO
528 ipair = 1
529 junique = sort_list(1, ipair)
530 ifirst = 1
531 DO iunique = 1, nunique
532 atom_a = junique
533 IF (glob_loc_list_a(ifirst) > atom_a) cycle
534 DO mpair = ifirst, SIZE(glob_loc_list_a)
535 IF (glob_loc_list_a(mpair) == atom_a) EXIT
536 END DO
537 ifirst = mpair
538 DO mpair = ifirst, SIZE(glob_loc_list_a)
539 IF (glob_loc_list_a(mpair) /= atom_a) EXIT
540 END DO
541 ilast = mpair - 1
542 nloc_size = 0
543 IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
544 DO WHILE (ipair <= npairs)
545 IF (sort_list(1, ipair) /= junique) EXIT
546 atom_b = sort_list(2, ipair)
547 ! Energy terms
548 pot_loc = 0.0_dp
549 rij(:) = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
550 drij = dot_product(rij, rij)
551 ipair = ipair + 1
552 IF (drij > rab2_max) cycle
553 drij = sqrt(drij)
554 CALL gal21_energy(pot_loc, gal21, r_last_update_pbc, atom_a, atom_b, &
555 cell, particle_set, mm_section)
556
557 pot_manybody = pot_manybody + pot_loc
558 END DO
559 ifirst = ilast + 1
560 IF (ipair <= npairs) junique = sort_list(1, ipair)
561 END DO
562 DEALLOCATE (sort_list, work_list)
563 END IF
564 END DO
565 END DO kind_group_loop_5
566 END DO
567 CALL destroy_gal21_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
568 END IF
569
570 CALL timestop(handle)
571 END SUBROUTINE energy_manybody
572
573! **************************************************************************************************
574!> \brief ...
575!> \param fist_nonbond_env ...
576!> \param particle_set ...
577!> \param cell ...
578!> \param f_nonbond ...
579!> \param pv_nonbond ...
580!> \param use_virial ...
581!> \par History
582!> Fast implementation of the tersoff potential - [tlaino] 2007
583!> \author I-Feng W. Kuo, Teodoro Laino
584! **************************************************************************************************
585 SUBROUTINE force_nonbond_manybody(fist_nonbond_env, particle_set, cell, &
586 f_nonbond, pv_nonbond, use_virial)
587
588 TYPE(fist_nonbond_env_type), POINTER :: fist_nonbond_env
589 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
590 TYPE(cell_type), POINTER :: cell
591 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT) :: f_nonbond, pv_nonbond
592 LOGICAL, INTENT(IN) :: use_virial
593
594 CHARACTER(LEN=*), PARAMETER :: routinen = 'force_nonbond_manybody'
595
596 INTEGER :: atom_a, atom_b, handle, i, i_a, i_b, iend, ifirst, igrp, ikind, ilast, ilist, &
597 ipair, istart, iunique, jkind, junique, kind_a, kind_b, mpair, nkinds, nloc_size, npairs, &
598 nunique
599 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: eam_kinds_index
600 INTEGER, DIMENSION(:), POINTER :: glob_loc_list_a, work_list
601 INTEGER, DIMENSION(:, :), POINTER :: glob_loc_list, list, sort_list
602 LOGICAL :: any_ace, any_allegro, any_deepmd, &
603 any_gal, any_gal21, any_nequip, &
604 any_quip, any_siepmann, any_tersoff
605 REAL(kind=dp) :: f_eam, fac, fr(3), ptens11, ptens12, ptens13, ptens21, ptens22, ptens23, &
606 ptens31, ptens32, ptens33, rab(3), rab2, rab2_max, rtmp(3)
607 REAL(kind=dp), DIMENSION(3) :: cell_v, cvi
608 REAL(kind=dp), DIMENSION(:, :), POINTER :: glob_cell_v
609 TYPE(eam_pot_type), POINTER :: eam_a, eam_b
610 TYPE(eam_type), DIMENSION(:), POINTER :: eam_data
611 TYPE(fist_neighbor_type), POINTER :: nonbonded
612 TYPE(gal21_pot_type), POINTER :: gal21
613 TYPE(gal_pot_type), POINTER :: gal
614 TYPE(neighbor_kind_pairs_type), POINTER :: neighbor_kind_pair
615 TYPE(pair_potential_pp_type), POINTER :: potparm
616 TYPE(pair_potential_single_type), POINTER :: pot
617 TYPE(pos_type), DIMENSION(:), POINTER :: r_last_update_pbc
618 TYPE(siepmann_pot_type), POINTER :: siepmann
619 TYPE(tersoff_pot_type), POINTER :: tersoff
620
621 any_tersoff = .false.
622 any_quip = .false.
623 any_nequip = .false.
624 any_allegro = .false.
625 any_siepmann = .false.
626 any_ace = .false.
627 any_deepmd = .false.
628 any_gal = .false.
629 any_gal21 = .false.
630 CALL timeset(routinen, handle)
631 NULLIFY (eam_a, eam_b, tersoff, siepmann, gal, gal21)
632
633 CALL fist_nonbond_env_get(fist_nonbond_env, nonbonded=nonbonded, potparm=potparm, &
634 natom_types=nkinds, eam_data=eam_data, r_last_update_pbc=r_last_update_pbc)
635
636 ! Initializing the potential energy, pressure tensor and force
637 IF (use_virial) THEN
638 ptens11 = 0.0_dp; ptens12 = 0.0_dp; ptens13 = 0.0_dp
639 ptens21 = 0.0_dp; ptens22 = 0.0_dp; ptens23 = 0.0_dp
640 ptens31 = 0.0_dp; ptens32 = 0.0_dp; ptens33 = 0.0_dp
641 END IF
642
643 nkinds = SIZE(potparm%pot, 1)
644 ALLOCATE (eam_kinds_index(nkinds, nkinds))
645 eam_kinds_index = -1
646 DO ikind = 1, nkinds
647 DO jkind = ikind, nkinds
648 DO i = 1, SIZE(potparm%pot(ikind, jkind)%pot%type)
649 IF (potparm%pot(ikind, jkind)%pot%type(i) == ea_type) THEN
650 ! At the moment we allow only 1 EAM per each kinds pair..
651 cpassert(eam_kinds_index(ikind, jkind) == -1)
652 cpassert(eam_kinds_index(jkind, ikind) == -1)
653 eam_kinds_index(ikind, jkind) = i
654 eam_kinds_index(jkind, ikind) = i
655 END IF
656 END DO
657 END DO
658 END DO
659 DO ikind = 1, nkinds
660 DO jkind = ikind, nkinds
661 any_ace = any_ace .OR. any(potparm%pot(ikind, jkind)%pot%type == ace_type)
662 END DO
663 END DO
664 ! ACE
665 IF (any_ace) &
666 CALL ace_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
667
668 DO ikind = 1, nkinds
669 DO jkind = ikind, nkinds
670 any_deepmd = any_deepmd .OR. any(potparm%pot(ikind, jkind)%pot%type == deepmd_type)
671 END DO
672 END DO
673 ! DEEPMD
674 IF (any_deepmd) &
675 CALL deepmd_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
676
677 ! QUIP
678 IF (use_virial) &
679 CALL quip_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond)
680
681 ! starting the force loop
682 DO ilist = 1, nonbonded%nlists
683 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
684 npairs = neighbor_kind_pair%npairs
685 IF (npairs == 0) cycle
686 kind_group_loop1: DO igrp = 1, neighbor_kind_pair%ngrp_kind
687 istart = neighbor_kind_pair%grp_kind_start(igrp)
688 iend = neighbor_kind_pair%grp_kind_end(igrp)
689 ikind = neighbor_kind_pair%ij_kind(1, igrp)
690 jkind = neighbor_kind_pair%ij_kind(2, igrp)
691 list => neighbor_kind_pair%list
692 cvi = neighbor_kind_pair%cell_vector
693 pot => potparm%pot(ikind, jkind)%pot
694 IF (pot%no_mb) cycle
695 rab2_max = pot%rcutsq
696 cell_v = matmul(cell%hmat, cvi)
697 any_tersoff = any_tersoff .OR. any(pot%type == tersoff_type)
698 any_siepmann = any_siepmann .OR. any(pot%type == siepmann_type)
699 any_ace = any_ace .OR. any(pot%type == ace_type)
700 any_deepmd = any_deepmd .OR. any(pot%type == deepmd_type)
701 any_gal = any_gal .OR. any(pot%type == gal_type)
702 any_gal21 = any_gal21 .OR. any(pot%type == gal21_type)
703 any_nequip = any_nequip .OR. any(pot%type == nequip_type)
704 any_allegro = any_allegro .OR. any(pot%type == allegro_type)
705 i = eam_kinds_index(ikind, jkind)
706 IF (i == -1) cycle
707 ! EAM
708 cpassert(ASSOCIATED(eam_data))
709 DO ipair = istart, iend
710 atom_a = list(1, ipair)
711 atom_b = list(2, ipair)
712 fac = 1.0_dp
713 IF (atom_a == atom_b) fac = 0.5_dp
714 kind_a = particle_set(atom_a)%atomic_kind%kind_number
715 kind_b = particle_set(atom_b)%atomic_kind%kind_number
716 i_a = eam_kinds_index(kind_a, kind_a)
717 i_b = eam_kinds_index(kind_b, kind_b)
718 eam_a => potparm%pot(kind_a, kind_a)%pot%set(i_a)%eam
719 eam_b => potparm%pot(kind_b, kind_b)%pot%set(i_b)%eam
720
721 !set this outside the potential type in case need multiple potentials
722 !Do everything necessary for EAM here
723 rab = r_last_update_pbc(atom_b)%r - r_last_update_pbc(atom_a)%r
724 rab = rab + cell_v
725 rab2 = rab(1)*rab(1) + rab(2)*rab(2) + rab(3)*rab(3)
726 IF (rab2 <= rab2_max) THEN
727 CALL get_force_eam(rab2, eam_a, eam_b, eam_data, atom_a, atom_b, f_eam)
728 f_eam = f_eam*fac
729
730 fr(1) = -f_eam*rab(1)
731 fr(2) = -f_eam*rab(2)
732 fr(3) = -f_eam*rab(3)
733 f_nonbond(1, atom_a) = f_nonbond(1, atom_a) - fr(1)
734 f_nonbond(2, atom_a) = f_nonbond(2, atom_a) - fr(2)
735 f_nonbond(3, atom_a) = f_nonbond(3, atom_a) - fr(3)
736
737 f_nonbond(1, atom_b) = f_nonbond(1, atom_b) + fr(1)
738 f_nonbond(2, atom_b) = f_nonbond(2, atom_b) + fr(2)
739 f_nonbond(3, atom_b) = f_nonbond(3, atom_b) + fr(3)
740 IF (use_virial) THEN
741 ptens11 = ptens11 + rab(1)*fr(1)
742 ptens21 = ptens21 + rab(2)*fr(1)
743 ptens31 = ptens31 + rab(3)*fr(1)
744 ptens12 = ptens12 + rab(1)*fr(2)
745 ptens22 = ptens22 + rab(2)*fr(2)
746 ptens32 = ptens32 + rab(3)*fr(2)
747 ptens13 = ptens13 + rab(1)*fr(3)
748 ptens23 = ptens23 + rab(2)*fr(3)
749 ptens33 = ptens33 + rab(3)*fr(3)
750 END IF
751 END IF
752 END DO
753 END DO kind_group_loop1
754 END DO
755 DEALLOCATE (eam_kinds_index)
756
757 ! Special way of handling the tersoff potential..
758 IF (any_tersoff) THEN
759 NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
760 CALL setup_tersoff_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
761 DO ilist = 1, nonbonded%nlists
762 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
763 npairs = neighbor_kind_pair%npairs
764 IF (npairs == 0) cycle
765 kind_group_loop2: DO igrp = 1, neighbor_kind_pair%ngrp_kind
766 istart = neighbor_kind_pair%grp_kind_start(igrp)
767 iend = neighbor_kind_pair%grp_kind_end(igrp)
768 ikind = neighbor_kind_pair%ij_kind(1, igrp)
769 jkind = neighbor_kind_pair%ij_kind(2, igrp)
770 list => neighbor_kind_pair%list
771 cvi = neighbor_kind_pair%cell_vector
772 pot => potparm%pot(ikind, jkind)%pot
773
774 IF (pot%no_mb) cycle
775 rab2_max = pot%rcutsq
776 cell_v = matmul(cell%hmat, cvi)
777 DO i = 1, SIZE(pot%type)
778 ! TERSOFF
779 IF (pot%type(i) == tersoff_type) THEN
780 npairs = iend - istart + 1
781 tersoff => pot%set(i)%tersoff
782 ALLOCATE (sort_list(2, npairs), work_list(npairs))
783 sort_list = list(:, istart:iend)
784 ! Sort the list of neighbors, this increases the efficiency for single
785 ! potential contributions
786 CALL sort(sort_list(1, :), npairs, work_list)
787 DO ipair = 1, npairs
788 work_list(ipair) = sort_list(2, work_list(ipair))
789 END DO
790 sort_list(2, :) = work_list
791 ! find number of unique elements of array index 1
792 nunique = 1
793 DO ipair = 1, npairs - 1
794 IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
795 END DO
796 ipair = 1
797 junique = sort_list(1, ipair)
798 ifirst = 1
799 DO iunique = 1, nunique
800 atom_a = junique
801 IF (glob_loc_list_a(ifirst) > atom_a) cycle
802 DO mpair = ifirst, SIZE(glob_loc_list_a)
803 IF (glob_loc_list_a(mpair) == atom_a) EXIT
804 END DO
805 ifirst = mpair
806 DO mpair = ifirst, SIZE(glob_loc_list_a)
807 IF (glob_loc_list_a(mpair) /= atom_a) EXIT
808 END DO
809 ilast = mpair - 1
810 nloc_size = 0
811 IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
812 DO WHILE (ipair <= npairs)
813 IF (sort_list(1, ipair) /= junique) EXIT
814 atom_b = sort_list(2, ipair)
815 ! Derivative terms
816 rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
817 ipair = ipair + 1
818 IF (dot_product(rtmp, rtmp) <= tersoff%rcutsq) THEN
819 CALL tersoff_forces(tersoff, r_last_update_pbc, cell_v, &
820 nloc_size, glob_loc_list(:, ifirst:ilast), glob_cell_v(:, ifirst:ilast), &
821 atom_a, atom_b, f_nonbond, pv_nonbond, use_virial, tersoff%rcutsq)
822 END IF
823 END DO
824 ifirst = ilast + 1
825 IF (ipair <= npairs) junique = sort_list(1, ipair)
826 END DO
827 DEALLOCATE (sort_list, work_list)
828 END IF
829 END DO
830 END DO kind_group_loop2
831 END DO
832 CALL destroy_tersoff_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
833 END IF
834 ! Special way of handling the siepmann potential..
835 IF (any_siepmann) THEN
836 NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
837 CALL setup_siepmann_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
838 DO ilist = 1, nonbonded%nlists
839 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
840 npairs = neighbor_kind_pair%npairs
841 IF (npairs == 0) cycle
842 kind_group_loop3: DO igrp = 1, neighbor_kind_pair%ngrp_kind
843 istart = neighbor_kind_pair%grp_kind_start(igrp)
844 iend = neighbor_kind_pair%grp_kind_end(igrp)
845 ikind = neighbor_kind_pair%ij_kind(1, igrp)
846 jkind = neighbor_kind_pair%ij_kind(2, igrp)
847 list => neighbor_kind_pair%list
848 cvi = neighbor_kind_pair%cell_vector
849 pot => potparm%pot(ikind, jkind)%pot
850
851 IF (pot%no_mb) cycle
852 rab2_max = pot%rcutsq
853 cell_v = matmul(cell%hmat, cvi)
854 DO i = 1, SIZE(pot%type)
855 ! SIEPMANN
856 IF (pot%type(i) == siepmann_type) THEN
857 npairs = iend - istart + 1
858 siepmann => pot%set(i)%siepmann
859 ALLOCATE (sort_list(2, npairs), work_list(npairs))
860 sort_list = list(:, istart:iend)
861 ! Sort the list of neighbors, this increases the efficiency for single
862 ! potential contributions
863 CALL sort(sort_list(1, :), npairs, work_list)
864 DO ipair = 1, npairs
865 work_list(ipair) = sort_list(2, work_list(ipair))
866 END DO
867 sort_list(2, :) = work_list
868 ! find number of unique elements of array index 1
869 nunique = 1
870 DO ipair = 1, npairs - 1
871 IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
872 END DO
873 ipair = 1
874 junique = sort_list(1, ipair)
875 ifirst = 1
876 DO iunique = 1, nunique
877 atom_a = junique
878 IF (glob_loc_list_a(ifirst) > atom_a) cycle
879 DO mpair = ifirst, SIZE(glob_loc_list_a)
880 IF (glob_loc_list_a(mpair) == atom_a) EXIT
881 END DO
882 ifirst = mpair
883 DO mpair = ifirst, SIZE(glob_loc_list_a)
884 IF (glob_loc_list_a(mpair) /= atom_a) EXIT
885 END DO
886 ilast = mpair - 1
887 nloc_size = 0
888 IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
889 DO WHILE (ipair <= npairs)
890 IF (sort_list(1, ipair) /= junique) EXIT
891 atom_b = sort_list(2, ipair)
892 ! Derivative terms
893 rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
894 ipair = ipair + 1
895 IF (dot_product(rtmp, rtmp) <= siepmann%rcutsq) THEN
896 CALL siepmann_forces_v2(siepmann, r_last_update_pbc, cell_v, cell, &
897 atom_a, atom_b, f_nonbond, use_virial, siepmann%rcutsq, &
898 particle_set)
899 CALL siepmann_forces_v3(siepmann, r_last_update_pbc, cell_v, &
900 nloc_size, glob_loc_list(:, ifirst:ilast), &
901 atom_a, atom_b, f_nonbond, use_virial, siepmann%rcutsq, &
902 cell, particle_set)
903 END IF
904 END DO
905 ifirst = ilast + 1
906 IF (ipair <= npairs) junique = sort_list(1, ipair)
907 END DO
908 DEALLOCATE (sort_list, work_list)
909 END IF
910 END DO
911 END DO kind_group_loop3
912 END DO
913 CALL destroy_siepmann_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
914 END IF
915
916 ! GAL19 potential..
917 IF (any_gal) THEN
918 NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
919 CALL setup_gal_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
920 DO ilist = 1, nonbonded%nlists
921 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
922 npairs = neighbor_kind_pair%npairs
923 IF (npairs == 0) cycle
924 kind_group_loop4: DO igrp = 1, neighbor_kind_pair%ngrp_kind
925 istart = neighbor_kind_pair%grp_kind_start(igrp)
926 iend = neighbor_kind_pair%grp_kind_end(igrp)
927 ikind = neighbor_kind_pair%ij_kind(1, igrp)
928 jkind = neighbor_kind_pair%ij_kind(2, igrp)
929 list => neighbor_kind_pair%list
930 cvi = neighbor_kind_pair%cell_vector
931 pot => potparm%pot(ikind, jkind)%pot
932
933 IF (pot%no_mb) cycle
934 rab2_max = pot%rcutsq
935 cell_v = matmul(cell%hmat, cvi)
936 DO i = 1, SIZE(pot%type)
937 ! GAL19
938 IF (pot%type(i) == gal_type) THEN
939 npairs = iend - istart + 1
940 gal => pot%set(i)%gal
941 ALLOCATE (sort_list(2, npairs), work_list(npairs))
942 sort_list = list(:, istart:iend)
943 ! Sort the list of neighbors, this increases the efficiency for single
944 ! potential contributions
945 CALL sort(sort_list(1, :), npairs, work_list)
946 DO ipair = 1, npairs
947 work_list(ipair) = sort_list(2, work_list(ipair))
948 END DO
949 sort_list(2, :) = work_list
950 ! find number of unique elements of array index 1
951 nunique = 1
952 DO ipair = 1, npairs - 1
953 IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
954 END DO
955 ipair = 1
956 junique = sort_list(1, ipair)
957 ifirst = 1
958 DO iunique = 1, nunique
959 atom_a = junique
960 IF (glob_loc_list_a(ifirst) > atom_a) cycle
961 DO mpair = ifirst, SIZE(glob_loc_list_a)
962 IF (glob_loc_list_a(mpair) == atom_a) EXIT
963 END DO
964 ifirst = mpair
965 DO mpair = ifirst, SIZE(glob_loc_list_a)
966 IF (glob_loc_list_a(mpair) /= atom_a) EXIT
967 END DO
968 ilast = mpair - 1
969 nloc_size = 0
970 IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
971 DO WHILE (ipair <= npairs)
972 IF (sort_list(1, ipair) /= junique) EXIT
973 atom_b = sort_list(2, ipair)
974 ! Derivative terms
975 rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
976 ipair = ipair + 1
977 IF (dot_product(rtmp, rtmp) <= gal%rcutsq) THEN
978 CALL gal_forces(gal, r_last_update_pbc, &
979 atom_a, atom_b, f_nonbond, use_virial, &
980 cell, particle_set)
981 END IF
982 END DO
983 ifirst = ilast + 1
984 IF (ipair <= npairs) junique = sort_list(1, ipair)
985 END DO
986 DEALLOCATE (sort_list, work_list)
987 END IF
988 END DO
989 END DO kind_group_loop4
990 END DO
991 CALL destroy_gal_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
992 END IF
993
994 ! GAL21 potential..
995 IF (any_gal21) THEN
996 NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
997 CALL setup_gal21_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
998 DO ilist = 1, nonbonded%nlists
999 neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
1000 npairs = neighbor_kind_pair%npairs
1001 IF (npairs == 0) cycle
1002 kind_group_loop6: DO igrp = 1, neighbor_kind_pair%ngrp_kind
1003 istart = neighbor_kind_pair%grp_kind_start(igrp)
1004 iend = neighbor_kind_pair%grp_kind_end(igrp)
1005 ikind = neighbor_kind_pair%ij_kind(1, igrp)
1006 jkind = neighbor_kind_pair%ij_kind(2, igrp)
1007 list => neighbor_kind_pair%list
1008 cvi = neighbor_kind_pair%cell_vector
1009 pot => potparm%pot(ikind, jkind)%pot
1010
1011 IF (pot%no_mb) cycle
1012 rab2_max = pot%rcutsq
1013 cell_v = matmul(cell%hmat, cvi)
1014 DO i = 1, SIZE(pot%type)
1015 ! GAL21
1016 IF (pot%type(i) == gal21_type) THEN
1017 npairs = iend - istart + 1
1018 gal21 => pot%set(i)%gal21
1019 ALLOCATE (sort_list(2, npairs), work_list(npairs))
1020 sort_list = list(:, istart:iend)
1021 ! Sort the list of neighbors, this increases the efficiency for single
1022 ! potential contributions
1023 CALL sort(sort_list(1, :), npairs, work_list)
1024 DO ipair = 1, npairs
1025 work_list(ipair) = sort_list(2, work_list(ipair))
1026 END DO
1027 sort_list(2, :) = work_list
1028 ! find number of unique elements of array index 1
1029 nunique = 1
1030 DO ipair = 1, npairs - 1
1031 IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
1032 END DO
1033 ipair = 1
1034 junique = sort_list(1, ipair)
1035 ifirst = 1
1036 DO iunique = 1, nunique
1037 atom_a = junique
1038 IF (glob_loc_list_a(ifirst) > atom_a) cycle
1039 DO mpair = ifirst, SIZE(glob_loc_list_a)
1040 IF (glob_loc_list_a(mpair) == atom_a) EXIT
1041 END DO
1042 ifirst = mpair
1043 DO mpair = ifirst, SIZE(glob_loc_list_a)
1044 IF (glob_loc_list_a(mpair) /= atom_a) EXIT
1045 END DO
1046 ilast = mpair - 1
1047 nloc_size = 0
1048 IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
1049 DO WHILE (ipair <= npairs)
1050 IF (sort_list(1, ipair) /= junique) EXIT
1051 atom_b = sort_list(2, ipair)
1052 ! Derivative terms
1053 rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
1054 ipair = ipair + 1
1055 IF (dot_product(rtmp, rtmp) <= gal21%rcutsq) THEN
1056 CALL gal21_forces(gal21, r_last_update_pbc, &
1057 atom_a, atom_b, f_nonbond, pv_nonbond, use_virial, &
1058 cell, particle_set)
1059 END IF
1060 END DO
1061 ifirst = ilast + 1
1062 IF (ipair <= npairs) junique = sort_list(1, ipair)
1063 END DO
1064 DEALLOCATE (sort_list, work_list)
1065 END IF
1066 END DO
1067 END DO kind_group_loop6
1068 END DO
1069 CALL destroy_gal_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
1070 END IF
1071
1072 ! NEQUIP
1073 IF (any_nequip) THEN
1074 CALL nequip_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
1075 END IF
1076
1077 ! ALLEGRO
1078 IF (any_allegro) THEN
1079 CALL allegro_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
1080 END IF
1081
1082 IF (use_virial) THEN
1083 pv_nonbond(1, 1) = pv_nonbond(1, 1) + ptens11
1084 pv_nonbond(1, 2) = pv_nonbond(1, 2) + ptens12
1085 pv_nonbond(1, 3) = pv_nonbond(1, 3) + ptens13
1086 pv_nonbond(2, 1) = pv_nonbond(2, 1) + ptens21
1087 pv_nonbond(2, 2) = pv_nonbond(2, 2) + ptens22
1088 pv_nonbond(2, 3) = pv_nonbond(2, 3) + ptens23
1089 pv_nonbond(3, 1) = pv_nonbond(3, 1) + ptens31
1090 pv_nonbond(3, 2) = pv_nonbond(3, 2) + ptens32
1091 pv_nonbond(3, 3) = pv_nonbond(3, 3) + ptens33
1092 END IF
1093 CALL timestop(handle)
1094 END SUBROUTINE force_nonbond_manybody
1095
1096END MODULE manybody_potential
1097
static GRID_HOST_DEVICE double fac(const int i)
Factorial function, e.g. fac(5) = 5! = 120.
Definition grid_common.h:51
Define the atomic kind types and their sub types.
Handles all functions related to the CELL.
Definition cell_types.F:15
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
Define the neighbor list data types and the corresponding functionality.
subroutine, public fist_nonbond_env_get(fist_nonbond_env, potparm14, potparm, nonbonded, rlist_cut, rlist_lowsq, aup, lup, ei_scale14, vdw_scale14, shift_cutoff, do_electrostatics, r_last_update, r_last_update_pbc, rshell_last_update_pbc, rcore_last_update_pbc, cell_last_update, num_update, last_update, counter, natom_types, long_range_correction, ij_kind_full_fac, eam_data, quip_data, nequip_data, allegro_data, deepmd_data, ace_data, charges)
sets a fist_nonbond_env
objects that represent the structure of input sections and the data contained in an input section
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
subroutine, public ace_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, fist_nonbond_env, pot_ace)
... >
subroutine, public ace_add_force_virial(fist_nonbond_env, force, pv_nonbond, use_virial)
...
subroutine, public setup_allegro_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, unique_list_a, cell)
...
subroutine, public allegro_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
...
subroutine, public allegro_energy_store_force_virial(nonbonded, particle_set, cell, atomic_kind_set, potparm, allegro, glob_loc_list_a, r_last_update_pbc, pot_allegro, fist_nonbond_env, unique_list_a, para_env, use_virial)
...
subroutine, public destroy_allegro_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a, unique_list_a)
...
subroutine, public deepmd_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, fist_nonbond_env, pot_deepmd, para_env)
...
subroutine, public deepmd_add_force_virial(fist_nonbond_env, force, pv_nonbond, use_virial)
...
subroutine, public get_force_eam(rab2, eam_a, eam_b, eam_data, atom_a, atom_b, f_eam)
...
Implementation of the GAL21 potential.
subroutine, public destroy_gal21_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
...
subroutine, public gal21_forces(gal21, r_last_update_pbc, iparticle, jparticle, f_nonbond, pv_nonbond, use_virial, cell, particle_set)
forces generated by the GAL2119 potential
subroutine, public setup_gal21_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
...
subroutine, public gal21_energy(pot_loc, gal21, r_last_update_pbc, iparticle, jparticle, cell, particle_set, mm_section)
Main part of the energy evaluation of GAL2119.
Implementation of the GAL19 potential.
subroutine, public destroy_gal_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
...
subroutine, public setup_gal_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
...
subroutine, public gal_energy(pot_loc, gal, r_last_update_pbc, iparticle, jparticle, cell, particle_set, mm_section)
Main part of the energy evaluation of GAL19.
subroutine, public gal_forces(gal, r_last_update_pbc, iparticle, jparticle, f_nonbond, use_virial, cell, particle_set)
forces generated by the GAL19 potential
subroutine, public nequip_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
...
subroutine, public destroy_nequip_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
...
subroutine, public nequip_energy_store_force_virial(nonbonded, particle_set, cell, atomic_kind_set, potparm, nequip, glob_loc_list_a, r_last_update_pbc, pot_nequip, fist_nonbond_env, para_env, use_virial)
...
subroutine, public setup_nequip_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
...
subroutine, public force_nonbond_manybody(fist_nonbond_env, particle_set, cell, f_nonbond, pv_nonbond, use_virial)
...
subroutine, public energy_manybody(fist_nonbond_env, atomic_kind_set, local_particles, particle_set, cell, pot_manybody, para_env, mm_section, use_virial)
computes the embedding contribution to the energy
subroutine, public quip_add_force_virial(fist_nonbond_env, force, virial)
...
subroutine, public quip_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, fist_nonbond_env, pot_quip, para_env)
...
implementation of dipole and three-body part of Siepmann-Sprik potential dipole term: 3rd term in Eq....
subroutine, public siepmann_energy(pot_loc, siepmann, r_last_update_pbc, atom_a, atom_b, nloc_size, full_loc_list, cell_v, cell, drij, particle_set, nr_oh, nr_h3o, nr_o)
energy of two-body dipole term and three-body term
subroutine, public setup_siepmann_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
...
subroutine, public siepmann_forces_v2(siepmann, r_last_update_pbc, cell_v, cell, iparticle, jparticle, f_nonbond, use_virial, rcutsq, particle_set)
forces generated by the dipole term
subroutine, public siepmann_forces_v3(siepmann, r_last_update_pbc, cell_v, n_loc_size, full_loc_list, iparticle, jparticle, f_nonbond, use_virial, rcutsq, cell, particle_set)
forces generated by the three-body term
subroutine, public print_nr_ions_siepmann(nr_ions, mm_section, para_env, print_oh, print_h3o, print_o)
prints the number of OH- ions or H3O+ ions near surface
subroutine, public destroy_siepmann_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
...
subroutine, public setup_tersoff_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
...
subroutine, public tersoff_forces(tersoff, r_last_update_pbc, cell_v, n_loc_size, full_loc_list, loc_cell_v, iparticle, jparticle, f_nonbond, pv_nonbond, use_virial, rcutsq)
...
subroutine, public destroy_tersoff_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
...
subroutine, public tersoff_energy(pot_loc, tersoff, r_last_update_pbc, atom_a, atom_b, nloc_size, full_loc_list, loc_cell_v, cell_v, drij)
...
Interface to the message passing library MPI.
integer, parameter, public allegro_type
integer, parameter, public gal_type
integer, parameter, public nequip_type
integer, parameter, public deepmd_type
integer, parameter, public quip_type
integer, parameter, public siepmann_type
integer, parameter, public ace_type
integer, parameter, public gal21_type
integer, parameter, public ea_type
integer, parameter, public tersoff_type
Define the data structure for the particle information.
All kind of helpful little routines.
Definition util.F:14
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
structure to store local (to a processor) ordered lists of integers.
stores all the informations relevant to an mpi environment