LCOV - code coverage report
Current view: top level - src - manybody_potential.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 100.0 % 679 679
Test Date: 2026-07-25 06:35:44 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_deepmd,                 ONLY: deepmd_add_force_virial,&
      32              :                                               deepmd_energy_store_force_virial
      33              :    USE manybody_e3nn,                   ONLY: e3nn_add_force_virial,&
      34              :                                               e3nn_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_siepmann,               ONLY: destroy_siepmann_arrays,&
      45              :                                               print_nr_ions_siepmann,&
      46              :                                               setup_siepmann_arrays,&
      47              :                                               siepmann_energy,&
      48              :                                               siepmann_forces_v2,&
      49              :                                               siepmann_forces_v3
      50              :    USE manybody_tersoff,                ONLY: destroy_tersoff_arrays,&
      51              :                                               setup_tersoff_arrays,&
      52              :                                               tersoff_energy,&
      53              :                                               tersoff_forces
      54              :    USE message_passing,                 ONLY: mp_para_env_type
      55              :    USE pair_potential_types,            ONLY: &
      56              :         ace_type, allegro_type, deepmd_type, ea_type, eam_pot_type, gal21_pot_type, gal21_type, &
      57              :         gal_pot_type, gal_type, mace_type, nequip_type, pair_potential_pp_type, &
      58              :         pair_potential_single_type, siepmann_pot_type, siepmann_type, tersoff_pot_type, &
      59              :         tersoff_type
      60              :    USE particle_types,                  ONLY: particle_type
      61              :    USE util,                            ONLY: sort
      62              : #include "./base/base_uses.f90"
      63              : 
      64              :    IMPLICIT NONE
      65              : 
      66              :    PRIVATE
      67              :    PUBLIC :: energy_manybody
      68              :    PUBLIC :: force_nonbond_manybody
      69              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'manybody_potential'
      70              : 
      71              : CONTAINS
      72              : 
      73              : ! **************************************************************************************************
      74              : !> \brief computes the embedding contribution to the energy
      75              : !> \param fist_nonbond_env ...
      76              : !> \param atomic_kind_set ...
      77              : !> \param local_particles ...
      78              : !> \param particle_set ...
      79              : !> \param cell ...
      80              : !> \param pot_manybody ...
      81              : !> \param para_env ...
      82              : !> \param mm_section ...
      83              : !> \param use_virial ...
      84              : !> \par History
      85              : !>      tlaino [2007] - New algorithm for tersoff potential
      86              : !> \author CJM, I-Feng W. Kuo, Teodoro Laino
      87              : ! **************************************************************************************************
      88        77140 :    SUBROUTINE energy_manybody(fist_nonbond_env, atomic_kind_set, local_particles, &
      89              :                               particle_set, cell, pot_manybody, para_env, mm_section, use_virial)
      90              : 
      91              :       TYPE(fist_nonbond_env_type), POINTER               :: fist_nonbond_env
      92              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind_set(:)
      93              :       TYPE(distribution_1d_type), POINTER                :: local_particles
      94              :       TYPE(particle_type), POINTER                       :: particle_set(:)
      95              :       TYPE(cell_type), POINTER                           :: cell
      96              :       REAL(dp), INTENT(INOUT)                            :: pot_manybody
      97              :       TYPE(mp_para_env_type), OPTIONAL, POINTER          :: para_env
      98              :       TYPE(section_vals_type), POINTER                   :: mm_section
      99              :       LOGICAL, INTENT(IN)                                :: use_virial
     100              : 
     101              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'energy_manybody'
     102              : 
     103              :       INTEGER :: atom_a, atom_b, handle, i, iend, ifirst, igrp, ikind, ilast, ilist, indexa, &
     104              :          ipair, iparticle, iparticle_local, istart, iunique, jkind, junique, mpair, nkinds, &
     105              :          nloc_size, npairs, nparticle, nparticle_local, nr_h3O, nr_o, nr_oh, nunique
     106        77140 :       INTEGER, DIMENSION(:), POINTER                     :: glob_loc_list_a, work_list
     107        77140 :       INTEGER, DIMENSION(:, :), POINTER                  :: glob_loc_list, list, sort_list
     108              :       LOGICAL                                            :: any_ace, any_allegro, any_deepmd, &
     109              :                                                             any_gal, any_gal21, any_mace, &
     110              :                                                             any_nequip, any_siepmann, any_tersoff
     111              :       REAL(KIND=dp)                                      :: drij, embed, pot_ace, pot_allegro, &
     112              :                                                             pot_deepmd, pot_loc, pot_mace, &
     113              :                                                             pot_nequip, qr, rab2_max, rij(3)
     114              :       REAL(KIND=dp), DIMENSION(3)                        :: cell_v, cvi
     115        77140 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: glob_cell_v
     116        77140 :       REAL(KIND=dp), POINTER                             :: fembed(:)
     117              :       TYPE(eam_pot_type), POINTER                        :: eam
     118        77140 :       TYPE(eam_type), DIMENSION(:), POINTER              :: eam_data
     119              :       TYPE(fist_neighbor_type), POINTER                  :: nonbonded
     120              :       TYPE(gal21_pot_type), POINTER                      :: gal21
     121              :       TYPE(gal_pot_type), POINTER                        :: gal
     122              :       TYPE(neighbor_kind_pairs_type), POINTER            :: neighbor_kind_pair
     123              :       TYPE(pair_potential_pp_type), POINTER              :: potparm
     124              :       TYPE(pair_potential_single_type), POINTER          :: pot
     125        77140 :       TYPE(pos_type), DIMENSION(:), POINTER              :: r_last_update_pbc
     126              :       TYPE(siepmann_pot_type), POINTER                   :: siepmann
     127              :       TYPE(tersoff_pot_type), POINTER                    :: tersoff
     128              : 
     129        77140 :       NULLIFY (eam, siepmann, tersoff, gal, gal21)
     130        77140 :       any_tersoff = .FALSE.
     131        77140 :       any_siepmann = .FALSE.
     132        77140 :       any_gal = .FALSE.
     133        77140 :       any_gal21 = .FALSE.
     134        77140 :       any_allegro = .FALSE.
     135        77140 :       any_nequip = .FALSE.
     136        77140 :       any_mace = .FALSE.
     137        77140 :       any_ace = .FALSE.
     138        77140 :       any_deepmd = .FALSE.
     139        77140 :       CALL timeset(routineN, handle)
     140              :       CALL fist_nonbond_env_get(fist_nonbond_env, r_last_update_pbc=r_last_update_pbc, &
     141        77140 :                                 potparm=potparm, eam_data=eam_data)
     142              :       ! EAM requires a single loop
     143       304504 :       DO ikind = 1, SIZE(atomic_kind_set)
     144       227364 :          pot => potparm%pot(ikind, ikind)%pot
     145       531916 :          DO i = 1, SIZE(pot%type)
     146       227412 :             IF (pot%type(i) /= ea_type) CYCLE
     147          488 :             eam => pot%set(i)%eam
     148          488 :             nparticle = SIZE(particle_set)
     149         1464 :             ALLOCATE (fembed(nparticle))
     150        14258 :             fembed(:) = 0._dp
     151          488 :             CPASSERT(ASSOCIATED(eam_data))
     152              :             ! computation of embedding function and energy
     153          488 :             nparticle_local = local_particles%n_el(ikind)
     154         4136 :             DO iparticle_local = 1, nparticle_local
     155         3648 :                iparticle = local_particles%list(ikind)%array(iparticle_local)
     156         3648 :                indexa = INT(eam_data(iparticle)%rho/eam%drhoar) + 1
     157         3648 :                IF (indexa > eam%npoints - 1) indexa = eam%npoints - 1
     158         3648 :                qr = eam_data(iparticle)%rho - eam%rhoval(indexa)
     159              : 
     160         3648 :                embed = eam%frho(indexa) + qr*eam%frhop(indexa)
     161         3648 :                fembed(iparticle) = eam%frhop(indexa) + qr*(eam%frhop(indexa + 1) - eam%frhop(indexa))/eam%drhoar
     162              : 
     163         4136 :                pot_manybody = pot_manybody + embed
     164              :             END DO
     165              :             ! communicate data
     166        28028 :             CALL para_env%sum(fembed)
     167        14258 :             DO iparticle = 1, nparticle
     168        14258 :                IF (particle_set(iparticle)%atomic_kind%kind_number == ikind) THEN
     169         7296 :                   eam_data(iparticle)%f_embed = fembed(iparticle)
     170              :                END IF
     171              :             END DO
     172              : 
     173       454776 :             DEALLOCATE (fembed)
     174              :          END DO
     175              :       END DO
     176              :       ! Other manybody potential
     177       304504 :       DO ikind = 1, SIZE(atomic_kind_set)
     178      1773650 :          DO jkind = ikind, SIZE(atomic_kind_set)
     179      1469146 :             pot => potparm%pot(ikind, jkind)%pot
     180      2935368 :             any_tersoff = any_tersoff .OR. ANY(pot%type == tersoff_type)
     181      2938334 :             any_nequip = any_nequip .OR. ANY(pot%type == nequip_type)
     182      2938338 :             any_mace = any_mace .OR. ANY(pot%type == mace_type)
     183      2937722 :             any_ace = any_ace .OR. ANY(pot%type == ace_type)
     184      2938334 :             any_allegro = any_allegro .OR. ANY(pot%type == allegro_type)
     185      2938334 :             any_deepmd = any_deepmd .OR. ANY(pot%type == deepmd_type)
     186      2938319 :             any_siepmann = any_siepmann .OR. ANY(pot%type == siepmann_type)
     187      2938339 :             any_gal = any_gal .OR. ANY(pot%type == gal_type)
     188      3165703 :             any_gal21 = any_gal21 .OR. ANY(pot%type == gal21_type)
     189              :          END DO
     190              :       END DO
     191        77140 :       CALL fist_nonbond_env_get(fist_nonbond_env, nonbonded=nonbonded, natom_types=nkinds)
     192              :       ! NEQUIP
     193        77140 :       IF (any_nequip) THEN
     194            2 :          NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
     195              :          CALL e3nn_energy_store_force_virial(nonbonded, particle_set, local_particles, cell, &
     196              :                                              atomic_kind_set, potparm, r_last_update_pbc, &
     197              :                                              pot_nequip, fist_nonbond_env, &
     198            2 :                                              para_env, use_virial, nequip_type)
     199            2 :          pot_manybody = pot_manybody + pot_nequip
     200              :       END IF
     201              :       ! ALLEGRO
     202        77140 :       IF (any_allegro) THEN
     203            2 :          NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
     204              :          CALL e3nn_energy_store_force_virial(nonbonded, particle_set, local_particles, cell, &
     205              :                                              atomic_kind_set, potparm, r_last_update_pbc, &
     206              :                                              pot_allegro, fist_nonbond_env, &
     207            2 :                                              para_env, use_virial, allegro_type)
     208            2 :          pot_manybody = pot_manybody + pot_allegro
     209              :       END IF
     210              :       ! MACE (reuses the NequIP message-passing evaluation path)
     211        77140 :       IF (any_mace) THEN
     212            2 :          NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
     213              :          CALL e3nn_energy_store_force_virial(nonbonded, particle_set, local_particles, cell, &
     214              :                                              atomic_kind_set, potparm, r_last_update_pbc, &
     215              :                                              pot_mace, fist_nonbond_env, &
     216            2 :                                              para_env, use_virial, mace_type)
     217            2 :          pot_manybody = pot_manybody + pot_mace
     218              :       END IF
     219              :       ! ACE
     220        77140 :       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        77140 :       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        77140 :       IF (any_tersoff) THEN
     234         2664 :          NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
     235         2664 :          CALL setup_tersoff_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
     236       101052 :          DO ilist = 1, nonbonded%nlists
     237        98388 :             neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
     238        98388 :             npairs = neighbor_kind_pair%npairs
     239        98388 :             IF (npairs == 0) CYCLE
     240        68185 :             Kind_Group_Loop: DO igrp = 1, neighbor_kind_pair%ngrp_kind
     241        33321 :                istart = neighbor_kind_pair%grp_kind_start(igrp)
     242        33321 :                iend = neighbor_kind_pair%grp_kind_end(igrp)
     243        33321 :                ikind = neighbor_kind_pair%ij_kind(1, igrp)
     244        33321 :                jkind = neighbor_kind_pair%ij_kind(2, igrp)
     245        33321 :                list => neighbor_kind_pair%list
     246       133284 :                cvi = neighbor_kind_pair%cell_vector
     247        33321 :                pot => potparm%pot(ikind, jkind)%pot
     248       165032 :                DO i = 1, SIZE(pot%type)
     249        33323 :                   IF (pot%type(i) /= tersoff_type) CYCLE
     250        33280 :                   rab2_max = pot%set(i)%tersoff%rcutsq
     251       432640 :                   cell_v = MATMUL(cell%hmat, cvi)
     252        33280 :                   pot => potparm%pot(ikind, jkind)%pot
     253        33280 :                   tersoff => pot%set(i)%tersoff
     254        33280 :                   npairs = iend - istart + 1
     255        66601 :                   IF (npairs /= 0) THEN
     256       166400 :                      ALLOCATE (sort_list(2, npairs), work_list(npairs))
     257     29009284 :                      sort_list = list(:, istart:iend)
     258              :                      ! Sort the list of neighbors, this increases the efficiency for single
     259              :                      ! potential contributions
     260        33280 :                      CALL sort(sort_list(1, :), npairs, work_list)
     261      4862614 :                      DO ipair = 1, npairs
     262      4862614 :                         work_list(ipair) = sort_list(2, work_list(ipair))
     263              :                      END DO
     264      9691948 :                      sort_list(2, :) = work_list
     265              :                      ! find number of unique elements of array index 1
     266        33280 :                      nunique = 1
     267      4829334 :                      DO ipair = 1, npairs - 1
     268      4829334 :                         IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
     269              :                      END DO
     270        33280 :                      ipair = 1
     271        33280 :                      junique = sort_list(1, ipair)
     272        33280 :                      ifirst = 1
     273       344350 :                      DO iunique = 1, nunique
     274       311070 :                         atom_a = junique
     275       311070 :                         IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
     276     61587820 :                         DO mpair = ifirst, SIZE(glob_loc_list_a)
     277     61587820 :                            IF (glob_loc_list_a(mpair) == atom_a) EXIT
     278              :                         END DO
     279     70828815 :                         ifirst = mpair
     280     70828815 :                         DO mpair = ifirst, SIZE(glob_loc_list_a)
     281     70828815 :                            IF (glob_loc_list_a(mpair) /= atom_a) EXIT
     282              :                         END DO
     283       311070 :                         ilast = mpair - 1
     284       311070 :                         nloc_size = 0
     285       311070 :                         IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
     286      5140404 :                         DO WHILE (ipair <= npairs)
     287      5107124 :                            IF (sort_list(1, ipair) /= junique) EXIT
     288      4829334 :                            atom_b = sort_list(2, ipair)
     289              :                            ! Energy terms
     290      4829334 :                            pot_loc = 0.0_dp
     291     19317336 :                            rij(:) = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
     292     19317336 :                            drij = DOT_PRODUCT(rij, rij)
     293      4829334 :                            ipair = ipair + 1
     294      4829334 :                            IF (drij > rab2_max) CYCLE
     295       250380 :                            drij = SQRT(drij)
     296              :                            CALL tersoff_energy(pot_loc, tersoff, r_last_update_pbc, atom_a, atom_b, nloc_size, &
     297       250380 :                                                glob_loc_list(:, ifirst:ilast), glob_cell_v(:, ifirst:ilast), cell_v, drij)
     298      5107124 :                            pot_manybody = pot_manybody + 0.5_dp*pot_loc
     299              :                         END DO
     300       311070 :                         ifirst = ilast + 1
     301       344350 :                         IF (ipair <= npairs) junique = sort_list(1, ipair)
     302              :                      END DO
     303        33280 :                      DEALLOCATE (sort_list, work_list)
     304              :                   END IF
     305              :                END DO
     306              :             END DO Kind_Group_Loop
     307              :          END DO
     308         2664 :          CALL destroy_tersoff_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
     309              :       END IF
     310              : 
     311              :       !SIEPMANN POTENTIAL
     312        77140 :       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        77140 :       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        77140 :       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              :                         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              :                            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        77140 :       CALL timestop(handle)
     561        77140 :    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        66832 :    SUBROUTINE force_nonbond_manybody(fist_nonbond_env, particle_set, cell, &
     576        66832 :                                      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        66832 :       INTEGER, ALLOCATABLE, DIMENSION(:, :)              :: eam_kinds_index
     590        66832 :       INTEGER, DIMENSION(:), POINTER                     :: glob_loc_list_a, work_list
     591        66832 :       INTEGER, DIMENSION(:, :), POINTER                  :: glob_loc_list, list, sort_list
     592              :       LOGICAL                                            :: any_ace, any_allegro, any_deepmd, &
     593              :                                                             any_gal, any_gal21, any_mace, &
     594              :                                                             any_nequip, any_siepmann, any_tersoff
     595              :       REAL(KIND=dp) :: f_eam, fac, fr(3), ptens11, ptens12, ptens13, ptens21, ptens22, ptens23, &
     596              :          ptens31, ptens32, ptens33, rab(3), rab2, rab2_max, rtmp(3)
     597              :       REAL(KIND=dp), DIMENSION(3)                        :: cell_v, cvi
     598        66832 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: glob_cell_v
     599              :       TYPE(eam_pot_type), POINTER                        :: eam_a, eam_b
     600        66832 :       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        66832 :       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        66832 :       any_tersoff = .FALSE.
     612        66832 :       any_allegro = .FALSE.
     613        66832 :       any_nequip = .FALSE.
     614        66832 :       any_mace = .FALSE.
     615        66832 :       any_siepmann = .FALSE.
     616        66832 :       any_ace = .FALSE.
     617        66832 :       any_deepmd = .FALSE.
     618        66832 :       any_gal = .FALSE.
     619        66832 :       any_gal21 = .FALSE.
     620        66832 :       CALL timeset(routineN, handle)
     621        66832 :       NULLIFY (eam_a, eam_b, tersoff, siepmann, gal, gal21)
     622              : 
     623              :       CALL fist_nonbond_env_get(fist_nonbond_env, nonbonded=nonbonded, potparm=potparm, &
     624        66832 :                                 natom_types=nkinds, eam_data=eam_data, r_last_update_pbc=r_last_update_pbc)
     625              : 
     626              :       ! Initializing the potential energy, pressure tensor and force
     627              :       IF (use_virial) THEN
     628              :          ptens11 = 0.0_dp; ptens12 = 0.0_dp; ptens13 = 0.0_dp
     629              :          ptens21 = 0.0_dp; ptens22 = 0.0_dp; ptens23 = 0.0_dp
     630              :          ptens31 = 0.0_dp; ptens32 = 0.0_dp; ptens33 = 0.0_dp
     631              :       END IF
     632              : 
     633        66832 :       nkinds = SIZE(potparm%pot, 1)
     634       267328 :       ALLOCATE (eam_kinds_index(nkinds, nkinds))
     635      2943336 :       eam_kinds_index = -1
     636       273598 :       DO ikind = 1, nkinds
     637      1711850 :          DO jkind = ikind, nkinds
     638      3083318 :             DO i = 1, SIZE(potparm%pot(ikind, jkind)%pot%type)
     639      2876552 :                IF (potparm%pot(ikind, jkind)%pot%type(i) == ea_type) THEN
     640              :                   ! At the moment we allow only 1 EAM per each kinds pair..
     641          692 :                   CPASSERT(eam_kinds_index(ikind, jkind) == -1)
     642          692 :                   CPASSERT(eam_kinds_index(jkind, ikind) == -1)
     643          692 :                   eam_kinds_index(ikind, jkind) = i
     644          692 :                   eam_kinds_index(jkind, ikind) = i
     645              :                END IF
     646              :             END DO
     647              :          END DO
     648              :       END DO
     649       273598 :       DO ikind = 1, nkinds
     650      1711850 :          DO jkind = ikind, nkinds
     651      3082700 :             any_ace = any_ace .OR. ANY(potparm%pot(ikind, jkind)%pot%type == ace_type)
     652              :          END DO
     653              :       END DO
     654              :       ! ACE
     655        66832 :       IF (any_ace) THEN
     656          206 :          CALL ace_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
     657              :       END IF
     658              : 
     659       273598 :       DO ikind = 1, nkinds
     660      1711850 :          DO jkind = ikind, nkinds
     661      3083312 :             any_deepmd = any_deepmd .OR. ANY(potparm%pot(ikind, jkind)%pot%type == deepmd_type)
     662              :          END DO
     663              :       END DO
     664              :       ! DEEPMD
     665        66832 :       IF (any_deepmd) THEN
     666            2 :          CALL deepmd_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
     667              :       END IF
     668              : 
     669              :       ! NEQUIP
     670       273598 :       DO ikind = 1, nkinds
     671      1711850 :          DO jkind = ikind, nkinds
     672      3083312 :             any_nequip = any_nequip .OR. ANY(potparm%pot(ikind, jkind)%pot%type == nequip_type)
     673              :          END DO
     674              :       END DO
     675        66832 :       IF (any_nequip) THEN
     676            2 :          CALL e3nn_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
     677              :       END IF
     678              : 
     679              :       ! ALLEGRO
     680       273598 :       DO ikind = 1, nkinds
     681      1711850 :          DO jkind = ikind, nkinds
     682      3083312 :             any_allegro = any_allegro .OR. ANY(potparm%pot(ikind, jkind)%pot%type == allegro_type)
     683              :          END DO
     684              :       END DO
     685        66832 :       IF (any_allegro) THEN
     686            2 :          CALL e3nn_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
     687              :       END IF
     688              : 
     689              :       ! MACE (reuses the NequIP force/virial accumulation)
     690       273598 :       DO ikind = 1, nkinds
     691      1711850 :          DO jkind = ikind, nkinds
     692      3083316 :             any_mace = any_mace .OR. ANY(potparm%pot(ikind, jkind)%pot%type == mace_type)
     693              :          END DO
     694              :       END DO
     695        66832 :       IF (any_mace) THEN
     696            2 :          CALL e3nn_add_force_virial(fist_nonbond_env, f_nonbond, pv_nonbond, use_virial)
     697              :       END IF
     698              : 
     699              :       ! starting the force loop
     700      7332466 :       DO ilist = 1, nonbonded%nlists
     701      7265634 :          neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
     702      7265634 :          npairs = neighbor_kind_pair%npairs
     703      7265634 :          IF (npairs == 0) CYCLE
     704      9469821 :          Kind_Group_Loop1: DO igrp = 1, neighbor_kind_pair%ngrp_kind
     705      7284498 :             istart = neighbor_kind_pair%grp_kind_start(igrp)
     706      7284498 :             iend = neighbor_kind_pair%grp_kind_end(igrp)
     707      7284498 :             ikind = neighbor_kind_pair%ij_kind(1, igrp)
     708      7284498 :             jkind = neighbor_kind_pair%ij_kind(2, igrp)
     709      7284498 :             list => neighbor_kind_pair%list
     710     29137992 :             cvi = neighbor_kind_pair%cell_vector
     711      7284498 :             pot => potparm%pot(ikind, jkind)%pot
     712      7284498 :             IF (pot%no_mb) CYCLE Kind_Group_Loop1
     713        63830 :             rab2_max = pot%rcutsq
     714       829790 :             cell_v = MATMUL(cell%hmat, cvi)
     715        94382 :             any_tersoff = any_tersoff .OR. ANY(pot%type == tersoff_type)
     716       127497 :             any_siepmann = any_siepmann .OR. ANY(pot%type == siepmann_type)
     717       111148 :             any_ace = any_ace .OR. ANY(pot%type == ace_type)
     718       127660 :             any_deepmd = any_deepmd .OR. ANY(pot%type == deepmd_type)
     719       127653 :             any_gal = any_gal .OR. ANY(pot%type == gal_type)
     720       127653 :             any_gal21 = any_gal21 .OR. ANY(pot%type == gal21_type)
     721       127530 :             any_nequip = any_nequip .OR. ANY(pot%type == nequip_type)
     722       127530 :             any_allegro = any_allegro .OR. ANY(pot%type == allegro_type)
     723        63830 :             i = eam_kinds_index(ikind, jkind)
     724        63830 :             IF (i == -1) CYCLE Kind_Group_Loop1
     725              :             ! EAM
     726        13535 :             CPASSERT(ASSOCIATED(eam_data))
     727      7437070 :             DO ipair = istart, iend
     728       157901 :                atom_a = list(1, ipair)
     729       157901 :                atom_b = list(2, ipair)
     730       157901 :                fac = 1.0_dp
     731       157901 :                IF (atom_a == atom_b) fac = 0.5_dp
     732       157901 :                kind_a = particle_set(atom_a)%atomic_kind%kind_number
     733       157901 :                kind_b = particle_set(atom_b)%atomic_kind%kind_number
     734       157901 :                i_a = eam_kinds_index(kind_a, kind_a)
     735       157901 :                i_b = eam_kinds_index(kind_b, kind_b)
     736       157901 :                eam_a => potparm%pot(kind_a, kind_a)%pot%set(i_a)%eam
     737       157901 :                eam_b => potparm%pot(kind_b, kind_b)%pot%set(i_b)%eam
     738              : 
     739              :                !set this outside the potential type in case need multiple potentials
     740              :                !Do everything necessary for EAM here
     741       631604 :                rab = r_last_update_pbc(atom_b)%r - r_last_update_pbc(atom_a)%r
     742       631604 :                rab = rab + cell_v
     743       157901 :                rab2 = rab(1)*rab(1) + rab(2)*rab(2) + rab(3)*rab(3)
     744      7442399 :                IF (rab2 <= rab2_max) THEN
     745        97493 :                   CALL get_force_eam(rab2, eam_a, eam_b, eam_data, atom_a, atom_b, f_eam)
     746        97493 :                   f_eam = f_eam*fac
     747              : 
     748        97493 :                   fr(1) = -f_eam*rab(1)
     749        97493 :                   fr(2) = -f_eam*rab(2)
     750        97493 :                   fr(3) = -f_eam*rab(3)
     751        97493 :                   f_nonbond(1, atom_a) = f_nonbond(1, atom_a) - fr(1)
     752        97493 :                   f_nonbond(2, atom_a) = f_nonbond(2, atom_a) - fr(2)
     753        97493 :                   f_nonbond(3, atom_a) = f_nonbond(3, atom_a) - fr(3)
     754              : 
     755        97493 :                   f_nonbond(1, atom_b) = f_nonbond(1, atom_b) + fr(1)
     756        97493 :                   f_nonbond(2, atom_b) = f_nonbond(2, atom_b) + fr(2)
     757        97493 :                   f_nonbond(3, atom_b) = f_nonbond(3, atom_b) + fr(3)
     758        97493 :                   IF (use_virial) THEN
     759         4112 :                      ptens11 = ptens11 + rab(1)*fr(1)
     760         4112 :                      ptens21 = ptens21 + rab(2)*fr(1)
     761         4112 :                      ptens31 = ptens31 + rab(3)*fr(1)
     762         4112 :                      ptens12 = ptens12 + rab(1)*fr(2)
     763         4112 :                      ptens22 = ptens22 + rab(2)*fr(2)
     764         4112 :                      ptens32 = ptens32 + rab(3)*fr(2)
     765         4112 :                      ptens13 = ptens13 + rab(1)*fr(3)
     766         4112 :                      ptens23 = ptens23 + rab(2)*fr(3)
     767         4112 :                      ptens33 = ptens33 + rab(3)*fr(3)
     768              :                   END IF
     769              :                END IF
     770              :             END DO
     771              :          END DO Kind_Group_Loop1
     772              :       END DO
     773        66832 :       DEALLOCATE (eam_kinds_index)
     774              : 
     775              :       ! Special way of handling the tersoff potential..
     776        66832 :       IF (any_tersoff) THEN
     777         2664 :          NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
     778         2664 :          CALL setup_tersoff_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
     779       101052 :          DO ilist = 1, nonbonded%nlists
     780        98388 :             neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
     781        98388 :             npairs = neighbor_kind_pair%npairs
     782        98388 :             IF (npairs == 0) CYCLE
     783        68185 :             Kind_Group_Loop2: DO igrp = 1, neighbor_kind_pair%ngrp_kind
     784        33321 :                istart = neighbor_kind_pair%grp_kind_start(igrp)
     785        33321 :                iend = neighbor_kind_pair%grp_kind_end(igrp)
     786        33321 :                ikind = neighbor_kind_pair%ij_kind(1, igrp)
     787        33321 :                jkind = neighbor_kind_pair%ij_kind(2, igrp)
     788        33321 :                list => neighbor_kind_pair%list
     789       133284 :                cvi = neighbor_kind_pair%cell_vector
     790        33321 :                pot => potparm%pot(ikind, jkind)%pot
     791              : 
     792        33321 :                IF (pot%no_mb) CYCLE Kind_Group_Loop2
     793        33285 :                rab2_max = pot%rcutsq
     794       432705 :                cell_v = MATMUL(cell%hmat, cvi)
     795       164960 :                DO i = 1, SIZE(pot%type)
     796              :                   ! TERSOFF
     797        66608 :                   IF (pot%type(i) == tersoff_type) THEN
     798        33280 :                      npairs = iend - istart + 1
     799        33280 :                      tersoff => pot%set(i)%tersoff
     800       166400 :                      ALLOCATE (sort_list(2, npairs), work_list(npairs))
     801     29042564 :                      sort_list = list(:, istart:iend)
     802              :                      ! Sort the list of neighbors, this increases the efficiency for single
     803              :                      ! potential contributions
     804        33280 :                      CALL sort(sort_list(1, :), npairs, work_list)
     805      4862614 :                      DO ipair = 1, npairs
     806      4862614 :                         work_list(ipair) = sort_list(2, work_list(ipair))
     807              :                      END DO
     808      9725228 :                      sort_list(2, :) = work_list
     809              :                      ! find number of unique elements of array index 1
     810        33280 :                      nunique = 1
     811      4829334 :                      DO ipair = 1, npairs - 1
     812      4829334 :                         IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
     813              :                      END DO
     814        33280 :                      ipair = 1
     815        33280 :                      junique = sort_list(1, ipair)
     816        33280 :                      ifirst = 1
     817       344350 :                      DO iunique = 1, nunique
     818       311070 :                         atom_a = junique
     819       311070 :                         IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
     820     61587820 :                         DO mpair = ifirst, SIZE(glob_loc_list_a)
     821     61587820 :                            IF (glob_loc_list_a(mpair) == atom_a) EXIT
     822              :                         END DO
     823     70828815 :                         ifirst = mpair
     824     70828815 :                         DO mpair = ifirst, SIZE(glob_loc_list_a)
     825     70828815 :                            IF (glob_loc_list_a(mpair) /= atom_a) EXIT
     826              :                         END DO
     827       311070 :                         ilast = mpair - 1
     828       311070 :                         nloc_size = 0
     829       311070 :                         IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
     830      5140404 :                         DO WHILE (ipair <= npairs)
     831      5107124 :                            IF (sort_list(1, ipair) /= junique) EXIT
     832      4829334 :                            atom_b = sort_list(2, ipair)
     833              :                            ! Derivative terms
     834     19317336 :                            rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
     835      4829334 :                            ipair = ipair + 1
     836     19628406 :                            IF (DOT_PRODUCT(rtmp, rtmp) <= tersoff%rcutsq) THEN
     837              :                               CALL tersoff_forces(tersoff, r_last_update_pbc, cell_v, &
     838              :                                                   nloc_size, glob_loc_list(:, ifirst:ilast), glob_cell_v(:, ifirst:ilast), &
     839       250380 :                                                   atom_a, atom_b, f_nonbond, pv_nonbond, use_virial, tersoff%rcutsq)
     840              :                            END IF
     841              :                         END DO
     842       311070 :                         ifirst = ilast + 1
     843       344350 :                         IF (ipair <= npairs) junique = sort_list(1, ipair)
     844              :                      END DO
     845        33280 :                      DEALLOCATE (sort_list, work_list)
     846              :                   END IF
     847              :                END DO
     848              :             END DO Kind_Group_Loop2
     849              :          END DO
     850         2664 :          CALL destroy_tersoff_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
     851              :       END IF
     852              :       ! Special way of handling the siepmann potential..
     853        66832 :       IF (any_siepmann) THEN
     854           21 :          NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
     855           21 :          CALL setup_siepmann_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
     856          588 :          DO ilist = 1, nonbonded%nlists
     857          567 :             neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
     858          567 :             npairs = neighbor_kind_pair%npairs
     859          567 :             IF (npairs == 0) CYCLE
     860          918 :             Kind_Group_Loop3: DO igrp = 1, neighbor_kind_pair%ngrp_kind
     861          708 :                istart = neighbor_kind_pair%grp_kind_start(igrp)
     862          708 :                iend = neighbor_kind_pair%grp_kind_end(igrp)
     863          708 :                ikind = neighbor_kind_pair%ij_kind(1, igrp)
     864          708 :                jkind = neighbor_kind_pair%ij_kind(2, igrp)
     865          708 :                list => neighbor_kind_pair%list
     866         2832 :                cvi = neighbor_kind_pair%cell_vector
     867          708 :                pot => potparm%pot(ikind, jkind)%pot
     868              : 
     869          708 :                IF (pot%no_mb) CYCLE Kind_Group_Loop3
     870          165 :                rab2_max = pot%rcutsq
     871         2145 :                cell_v = MATMUL(cell%hmat, cvi)
     872          897 :                DO i = 1, SIZE(pot%type)
     873              :                   ! SIEPMANN
     874          873 :                   IF (pot%type(i) == siepmann_type) THEN
     875          165 :                      npairs = iend - istart + 1
     876          165 :                      siepmann => pot%set(i)%siepmann
     877          825 :                      ALLOCATE (sort_list(2, npairs), work_list(npairs))
     878       109698 :                      sort_list = list(:, istart:iend)
     879              :                      ! Sort the list of neighbors, this increases the efficiency for single
     880              :                      ! potential contributions
     881          165 :                      CALL sort(sort_list(1, :), npairs, work_list)
     882        18393 :                      DO ipair = 1, npairs
     883        18393 :                         work_list(ipair) = sort_list(2, work_list(ipair))
     884              :                      END DO
     885        36786 :                      sort_list(2, :) = work_list
     886              :                      ! find number of unique elements of array index 1
     887          165 :                      nunique = 1
     888        18228 :                      DO ipair = 1, npairs - 1
     889        18228 :                         IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
     890              :                      END DO
     891          165 :                      ipair = 1
     892          165 :                      junique = sort_list(1, ipair)
     893          165 :                      ifirst = 1
     894         5340 :                      DO iunique = 1, nunique
     895         5175 :                         atom_a = junique
     896         5175 :                         IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
     897        91602 :                         DO mpair = ifirst, SIZE(glob_loc_list_a)
     898        91602 :                            IF (glob_loc_list_a(mpair) == atom_a) EXIT
     899              :                         END DO
     900        62187 :                         ifirst = mpair
     901        62187 :                         DO mpair = ifirst, SIZE(glob_loc_list_a)
     902        62187 :                            IF (glob_loc_list_a(mpair) /= atom_a) EXIT
     903              :                         END DO
     904         5175 :                         ilast = mpair - 1
     905         5175 :                         nloc_size = 0
     906         5175 :                         IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
     907        23403 :                         DO WHILE (ipair <= npairs)
     908        23238 :                            IF (sort_list(1, ipair) /= junique) EXIT
     909        18228 :                            atom_b = sort_list(2, ipair)
     910              :                            ! Derivative terms
     911        72912 :                            rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
     912        18228 :                            ipair = ipair + 1
     913        78087 :                            IF (DOT_PRODUCT(rtmp, rtmp) <= siepmann%rcutsq) THEN
     914              :                               CALL siepmann_forces_v2(siepmann, r_last_update_pbc, cell_v, cell, &
     915              :                                                       atom_a, atom_b, f_nonbond, use_virial, siepmann%rcutsq, &
     916          318 :                                                       particle_set)
     917              :                               CALL siepmann_forces_v3(siepmann, r_last_update_pbc, cell_v, &
     918              :                                                       nloc_size, glob_loc_list(:, ifirst:ilast), &
     919              :                                                       atom_a, atom_b, f_nonbond, use_virial, siepmann%rcutsq, &
     920          318 :                                                       cell, particle_set)
     921              :                            END IF
     922              :                         END DO
     923         5175 :                         ifirst = ilast + 1
     924         5340 :                         IF (ipair <= npairs) junique = sort_list(1, ipair)
     925              :                      END DO
     926          165 :                      DEALLOCATE (sort_list, work_list)
     927              :                   END IF
     928              :                END DO
     929              :             END DO Kind_Group_Loop3
     930              :          END DO
     931           21 :          CALL destroy_siepmann_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
     932              :       END IF
     933              : 
     934              :       ! GAL19 potential..
     935        66832 :       IF (any_gal) THEN
     936            1 :          NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
     937            1 :          CALL setup_gal_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
     938           28 :          DO ilist = 1, nonbonded%nlists
     939           27 :             neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
     940           27 :             npairs = neighbor_kind_pair%npairs
     941           27 :             IF (npairs == 0) CYCLE
     942          168 :             Kind_Group_Loop4: DO igrp = 1, neighbor_kind_pair%ngrp_kind
     943          158 :                istart = neighbor_kind_pair%grp_kind_start(igrp)
     944          158 :                iend = neighbor_kind_pair%grp_kind_end(igrp)
     945          158 :                ikind = neighbor_kind_pair%ij_kind(1, igrp)
     946          158 :                jkind = neighbor_kind_pair%ij_kind(2, igrp)
     947          158 :                list => neighbor_kind_pair%list
     948          632 :                cvi = neighbor_kind_pair%cell_vector
     949          158 :                pot => potparm%pot(ikind, jkind)%pot
     950              : 
     951          158 :                IF (pot%no_mb) CYCLE Kind_Group_Loop4
     952            9 :                rab2_max = pot%rcutsq
     953          117 :                cell_v = MATMUL(cell%hmat, cvi)
     954           45 :                DO i = 1, SIZE(pot%type)
     955              :                   ! GAL19
     956          167 :                   IF (pot%type(i) == gal_type) THEN
     957            9 :                      npairs = iend - istart + 1
     958            9 :                      gal => pot%set(i)%gal
     959           45 :                      ALLOCATE (sort_list(2, npairs), work_list(npairs))
     960        45618 :                      sort_list = list(:, istart:iend)
     961              :                      ! Sort the list of neighbors, this increases the efficiency for single
     962              :                      ! potential contributions
     963            9 :                      CALL sort(sort_list(1, :), npairs, work_list)
     964         7609 :                      DO ipair = 1, npairs
     965         7609 :                         work_list(ipair) = sort_list(2, work_list(ipair))
     966              :                      END DO
     967        15218 :                      sort_list(2, :) = work_list
     968              :                      ! find number of unique elements of array index 1
     969            9 :                      nunique = 1
     970         7600 :                      DO ipair = 1, npairs - 1
     971         7600 :                         IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
     972              :                      END DO
     973            9 :                      ipair = 1
     974            9 :                      junique = sort_list(1, ipair)
     975            9 :                      ifirst = 1
     976          659 :                      DO iunique = 1, nunique
     977          650 :                         atom_a = junique
     978          650 :                         IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
     979        36198 :                         DO mpair = ifirst, SIZE(glob_loc_list_a)
     980        36198 :                            IF (glob_loc_list_a(mpair) == atom_a) EXIT
     981              :                         END DO
     982        24581 :                         ifirst = mpair
     983        24581 :                         DO mpair = ifirst, SIZE(glob_loc_list_a)
     984        24581 :                            IF (glob_loc_list_a(mpair) /= atom_a) EXIT
     985              :                         END DO
     986          650 :                         ilast = mpair - 1
     987          650 :                         nloc_size = 0
     988          650 :                         IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
     989         8250 :                         DO WHILE (ipair <= npairs)
     990         8241 :                            IF (sort_list(1, ipair) /= junique) EXIT
     991         7600 :                            atom_b = sort_list(2, ipair)
     992              :                            ! Derivative terms
     993        30400 :                            rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
     994         7600 :                            ipair = ipair + 1
     995        31050 :                            IF (DOT_PRODUCT(rtmp, rtmp) <= gal%rcutsq) THEN
     996              :                               CALL gal_forces(gal, r_last_update_pbc, &
     997              :                                               atom_a, atom_b, f_nonbond, use_virial, &
     998         2004 :                                               cell, particle_set)
     999              :                            END IF
    1000              :                         END DO
    1001          650 :                         ifirst = ilast + 1
    1002          659 :                         IF (ipair <= npairs) junique = sort_list(1, ipair)
    1003              :                      END DO
    1004            9 :                      DEALLOCATE (sort_list, work_list)
    1005              :                   END IF
    1006              :                END DO
    1007              :             END DO Kind_Group_Loop4
    1008              :          END DO
    1009            1 :          CALL destroy_gal_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
    1010              :       END IF
    1011              : 
    1012              :       ! GAL21 potential..
    1013        66832 :       IF (any_gal21) THEN
    1014            1 :          NULLIFY (glob_loc_list, glob_cell_v, glob_loc_list_a)
    1015            1 :          CALL setup_gal21_arrays(nonbonded, potparm, glob_loc_list, glob_cell_v, glob_loc_list_a, cell)
    1016           28 :          DO ilist = 1, nonbonded%nlists
    1017           27 :             neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
    1018           27 :             npairs = neighbor_kind_pair%npairs
    1019           27 :             IF (npairs == 0) CYCLE
    1020          168 :             Kind_Group_Loop6: DO igrp = 1, neighbor_kind_pair%ngrp_kind
    1021          158 :                istart = neighbor_kind_pair%grp_kind_start(igrp)
    1022          158 :                iend = neighbor_kind_pair%grp_kind_end(igrp)
    1023          158 :                ikind = neighbor_kind_pair%ij_kind(1, igrp)
    1024          158 :                jkind = neighbor_kind_pair%ij_kind(2, igrp)
    1025          158 :                list => neighbor_kind_pair%list
    1026          632 :                cvi = neighbor_kind_pair%cell_vector
    1027          158 :                pot => potparm%pot(ikind, jkind)%pot
    1028              : 
    1029          158 :                IF (pot%no_mb) CYCLE Kind_Group_Loop6
    1030            9 :                rab2_max = pot%rcutsq
    1031          117 :                cell_v = MATMUL(cell%hmat, cvi)
    1032           45 :                DO i = 1, SIZE(pot%type)
    1033              :                   ! GAL21
    1034          167 :                   IF (pot%type(i) == gal21_type) THEN
    1035            9 :                      npairs = iend - istart + 1
    1036            9 :                      gal21 => pot%set(i)%gal21
    1037           45 :                      ALLOCATE (sort_list(2, npairs), work_list(npairs))
    1038        52818 :                      sort_list = list(:, istart:iend)
    1039              :                      ! Sort the list of neighbors, this increases the efficiency for single
    1040              :                      ! potential contributions
    1041            9 :                      CALL sort(sort_list(1, :), npairs, work_list)
    1042         8809 :                      DO ipair = 1, npairs
    1043         8809 :                         work_list(ipair) = sort_list(2, work_list(ipair))
    1044              :                      END DO
    1045        17618 :                      sort_list(2, :) = work_list
    1046              :                      ! find number of unique elements of array index 1
    1047            9 :                      nunique = 1
    1048         8800 :                      DO ipair = 1, npairs - 1
    1049         8800 :                         IF (sort_list(1, ipair + 1) /= sort_list(1, ipair)) nunique = nunique + 1
    1050              :                      END DO
    1051            9 :                      ipair = 1
    1052            9 :                      junique = sort_list(1, ipair)
    1053            9 :                      ifirst = 1
    1054          710 :                      DO iunique = 1, nunique
    1055          701 :                         atom_a = junique
    1056          701 :                         IF (glob_loc_list_a(ifirst) > atom_a) CYCLE
    1057        42242 :                         DO mpair = ifirst, SIZE(glob_loc_list_a)
    1058        42242 :                            IF (glob_loc_list_a(mpair) == atom_a) EXIT
    1059              :                         END DO
    1060        30069 :                         ifirst = mpair
    1061        30069 :                         DO mpair = ifirst, SIZE(glob_loc_list_a)
    1062        30069 :                            IF (glob_loc_list_a(mpair) /= atom_a) EXIT
    1063              :                         END DO
    1064          701 :                         ilast = mpair - 1
    1065          701 :                         nloc_size = 0
    1066          701 :                         IF (ifirst /= 0) nloc_size = ilast - ifirst + 1
    1067         9501 :                         DO WHILE (ipair <= npairs)
    1068         9492 :                            IF (sort_list(1, ipair) /= junique) EXIT
    1069         8800 :                            atom_b = sort_list(2, ipair)
    1070              :                            ! Derivative terms
    1071        35200 :                            rtmp = r_last_update_pbc(atom_b)%r(:) - r_last_update_pbc(atom_a)%r(:) + cell_v
    1072         8800 :                            ipair = ipair + 1
    1073        35901 :                            IF (DOT_PRODUCT(rtmp, rtmp) <= gal21%rcutsq) THEN
    1074              :                               CALL gal21_forces(gal21, r_last_update_pbc, &
    1075              :                                                 atom_a, atom_b, f_nonbond, pv_nonbond, use_virial, &
    1076         5732 :                                                 cell, particle_set)
    1077              :                            END IF
    1078              :                         END DO
    1079          701 :                         ifirst = ilast + 1
    1080          710 :                         IF (ipair <= npairs) junique = sort_list(1, ipair)
    1081              :                      END DO
    1082            9 :                      DEALLOCATE (sort_list, work_list)
    1083              :                   END IF
    1084              :                END DO
    1085              :             END DO Kind_Group_Loop6
    1086              :          END DO
    1087            1 :          CALL destroy_gal_arrays(glob_loc_list, glob_cell_v, glob_loc_list_a)
    1088              :       END IF
    1089              : 
    1090        66832 :       IF (use_virial) THEN
    1091         5242 :          pv_nonbond(1, 1) = pv_nonbond(1, 1) + ptens11
    1092         5242 :          pv_nonbond(1, 2) = pv_nonbond(1, 2) + ptens12
    1093         5242 :          pv_nonbond(1, 3) = pv_nonbond(1, 3) + ptens13
    1094         5242 :          pv_nonbond(2, 1) = pv_nonbond(2, 1) + ptens21
    1095         5242 :          pv_nonbond(2, 2) = pv_nonbond(2, 2) + ptens22
    1096         5242 :          pv_nonbond(2, 3) = pv_nonbond(2, 3) + ptens23
    1097         5242 :          pv_nonbond(3, 1) = pv_nonbond(3, 1) + ptens31
    1098         5242 :          pv_nonbond(3, 2) = pv_nonbond(3, 2) + ptens32
    1099         5242 :          pv_nonbond(3, 3) = pv_nonbond(3, 3) + ptens33
    1100              :       END IF
    1101        66832 :       CALL timestop(handle)
    1102        66832 :    END SUBROUTINE force_nonbond_manybody
    1103              : 
    1104              : END MODULE manybody_potential
    1105              : 
        

Generated by: LCOV version 2.0-1