LCOV - code coverage report
Current view: top level - src - manybody_potential.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:e7e05ae) Lines: 664 664 100.0 %
Date: 2024-04-18 06:59:28 Functions: 2 2 100.0 %

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

Generated by: LCOV version 1.15