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