LCOV - code coverage report
Current view: top level - src - manybody_potential.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:ca6acae) Lines: 100.0 % 667 667
Test Date: 2026-01-02 06:29:53 Functions: 100.0 % 2 2

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

Generated by: LCOV version 2.0-1