LCOV - code coverage report
Current view: top level - src - fist_neighbor_list_control.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:d3e36fe) Lines: 104 106 98.1 %
Date: 2025-06-06 07:12:22 Functions: 1 1 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \par History
      10             : !>      Harald Forbert (Dec-2000): Changes for multiple linked lists
      11             : !>                                 linklist_internal_data_type
      12             : !>      07.02.2005: using real coordinates for r_last_update; cleaned (MK)
      13             : !> \author CJM,MK
      14             : ! **************************************************************************************************
      15             : MODULE fist_neighbor_list_control
      16             : 
      17             :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      18             :                                               get_atomic_kind_set
      19             :    USE cell_methods,                    ONLY: cell_create
      20             :    USE cell_types,                      ONLY: cell_clone,&
      21             :                                               cell_release,&
      22             :                                               cell_type,&
      23             :                                               pbc,&
      24             :                                               real_to_scaled,&
      25             :                                               scaled_to_real
      26             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      27             :                                               cp_logger_type
      28             :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      29             :                                               cp_print_key_unit_nr
      30             :    USE distribution_1d_types,           ONLY: distribution_1d_type
      31             :    USE exclusion_types,                 ONLY: exclusion_type
      32             :    USE fist_neighbor_list_types,        ONLY: fist_neighbor_type
      33             :    USE fist_neighbor_lists,             ONLY: build_fist_neighbor_lists
      34             :    USE fist_nonbond_env_types,          ONLY: fist_nonbond_env_get,&
      35             :                                               fist_nonbond_env_set,&
      36             :                                               fist_nonbond_env_type,&
      37             :                                               pos_type
      38             :    USE input_section_types,             ONLY: section_vals_type,&
      39             :                                               section_vals_val_get
      40             :    USE kinds,                           ONLY: dp
      41             :    USE message_passing,                 ONLY: mp_para_env_type
      42             :    USE pair_potential_types,            ONLY: ace_type,&
      43             :                                               allegro_type,&
      44             :                                               gal21_type,&
      45             :                                               gal_type,&
      46             :                                               nequip_type,&
      47             :                                               pair_potential_pp_type,&
      48             :                                               siepmann_type,&
      49             :                                               tersoff_type
      50             :    USE particle_types,                  ONLY: particle_type
      51             : #include "./base/base_uses.f90"
      52             : 
      53             :    IMPLICIT NONE
      54             : 
      55             :    PRIVATE
      56             : 
      57             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'fist_neighbor_list_control'
      58             : 
      59             :    PUBLIC :: list_control
      60             : 
      61             : !***
      62             : 
      63             : CONTAINS
      64             : 
      65             : ! to decide whether the neighbor list is to be updated or not
      66             : ! based on a displacement criterion;
      67             : ! if any particle has moved by 0.5*verlet_skin from the previous
      68             : ! list update, then the list routine is called.
      69             : 
      70             : ! **************************************************************************************************
      71             : !> \brief ...
      72             : !> \param atomic_kind_set ...
      73             : !> \param particle_set ...
      74             : !> \param local_particles ...
      75             : !> \param cell ...
      76             : !> \param fist_nonbond_env ...
      77             : !> \param para_env ...
      78             : !> \param mm_section ...
      79             : !> \param shell_particle_set ...
      80             : !> \param core_particle_set ...
      81             : !> \param force_update ...
      82             : !> \param exclusions ...
      83             : ! **************************************************************************************************
      84      415110 :    SUBROUTINE list_control(atomic_kind_set, particle_set, local_particles, &
      85             :                            cell, fist_nonbond_env, para_env, mm_section, shell_particle_set, &
      86       83022 :                            core_particle_set, force_update, exclusions)
      87             : 
      88             :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind_set(:)
      89             :       TYPE(particle_type), POINTER                       :: particle_set(:)
      90             :       TYPE(distribution_1d_type), POINTER                :: local_particles
      91             :       TYPE(cell_type), POINTER                           :: cell
      92             :       TYPE(fist_nonbond_env_type), POINTER               :: fist_nonbond_env
      93             :       TYPE(mp_para_env_type), POINTER                    :: para_env
      94             :       TYPE(section_vals_type), POINTER                   :: mm_section
      95             :       TYPE(particle_type), OPTIONAL, POINTER             :: shell_particle_set(:), &
      96             :                                                             core_particle_set(:)
      97             :       LOGICAL, INTENT(IN), OPTIONAL                      :: force_update
      98             :       TYPE(exclusion_type), DIMENSION(:), OPTIONAL       :: exclusions
      99             : 
     100             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'list_control'
     101             : 
     102             :       INTEGER :: counter, handle, ikind, iparticle, iparticle_kind, iparticle_local, ishell, &
     103             :          jkind, last_update, nparticle, nparticle_kind, nparticle_local, nshell, num_update, &
     104             :          output_unit
     105             :       LOGICAL                                            :: build_from_scratch, geo_check, &
     106             :                                                             shell_adiabatic, shell_present, &
     107             :                                                             update_neighbor_lists
     108       83022 :       LOGICAL, DIMENSION(:, :), POINTER                  :: full_nl
     109             :       REAL(KIND=dp)                                      :: aup, dr2, dr2_max, ei_scale14, lup, &
     110             :                                                             vdw_scale14, verlet_skin
     111             :       REAL(KIND=dp), DIMENSION(3)                        :: dr, rab, rab_last_update, s, s2r
     112       83022 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: rlist_cut, rlist_lowsq
     113             :       TYPE(cell_type), POINTER                           :: cell_last_update
     114             :       TYPE(cp_logger_type), POINTER                      :: logger
     115             :       TYPE(fist_neighbor_type), POINTER                  :: nonbonded
     116             :       TYPE(pair_potential_pp_type), POINTER              :: potparm
     117       83022 :       TYPE(pos_type), DIMENSION(:), POINTER              :: r_last_update, r_last_update_pbc, &
     118       83022 :                                                             rcore_last_update_pbc, &
     119       83022 :                                                             rshell_last_update_pbc
     120             : 
     121       83022 :       CALL timeset(routineN, handle)
     122       83022 :       NULLIFY (logger)
     123       83022 :       logger => cp_get_default_logger()
     124             : 
     125             :       ! *** Assigning local pointers ***
     126             :       CALL fist_nonbond_env_get(fist_nonbond_env, &
     127             :                                 nonbonded=nonbonded, &
     128             :                                 rlist_cut=rlist_cut, &
     129             :                                 rlist_lowsq=rlist_lowsq, &
     130             :                                 aup=aup, &
     131             :                                 lup=lup, &
     132             :                                 ei_scale14=ei_scale14, &
     133             :                                 vdw_scale14=vdw_scale14, &
     134             :                                 counter=counter, &
     135             :                                 r_last_update=r_last_update, &
     136             :                                 r_last_update_pbc=r_last_update_pbc, &
     137             :                                 rshell_last_update_pbc=rshell_last_update_pbc, &
     138             :                                 rcore_last_update_pbc=rcore_last_update_pbc, &
     139             :                                 cell_last_update=cell_last_update, &
     140             :                                 num_update=num_update, &
     141             :                                 potparm=potparm, &
     142       83022 :                                 last_update=last_update)
     143             : 
     144       83022 :       nparticle = SIZE(particle_set)
     145       83022 :       nparticle_kind = SIZE(atomic_kind_set)
     146       83022 :       nshell = 0
     147             :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
     148       83022 :                                shell_present=shell_present, shell_adiabatic=shell_adiabatic)
     149       83022 :       IF (shell_present) THEN
     150        9230 :          nshell = SIZE(shell_particle_set)
     151             :       END IF
     152             : 
     153             :       ! *** Check, if the neighbor lists have to be built or updated ***
     154       83022 :       update_neighbor_lists = .FALSE.
     155             :       CALL section_vals_val_get(mm_section, "NEIGHBOR_LISTS%NEIGHBOR_LISTS_FROM_SCRATCH", &
     156       83022 :                                 l_val=build_from_scratch)
     157             :       CALL section_vals_val_get(mm_section, "NEIGHBOR_LISTS%GEO_CHECK", &
     158       83022 :                                 l_val=geo_check)
     159       83022 :       IF (ASSOCIATED(r_last_update)) THEN
     160             :          ! Determine the maximum of the squared displacement, compared to
     161             :          ! r_last_update.
     162             :          CALL section_vals_val_get(mm_section, "NEIGHBOR_LISTS%VERLET_SKIN", &
     163       80517 :                                    r_val=verlet_skin)
     164       80517 :          dr2_max = 0.0_dp
     165      305685 :          DO iparticle_kind = 1, nparticle_kind
     166      225168 :             nparticle_local = local_particles%n_el(iparticle_kind)
     167     4650053 :             DO iparticle_local = 1, nparticle_local
     168     4344368 :                iparticle = local_particles%list(iparticle_kind)%array(iparticle_local)
     169    17377472 :                s2r = r_last_update(iparticle)%r
     170    17377472 :                s = particle_set(iparticle)%r(:)
     171    17377472 :                dr(:) = s2r - s
     172     4344368 :                dr2 = dr(1)*dr(1) + dr(2)*dr(2) + dr(3)*dr(3)
     173     4569536 :                dr2_max = MAX(dr2_max, dr2)
     174             :             END DO
     175             :          END DO
     176             : 
     177       80517 :          CALL para_env%max(dr2_max)
     178             : 
     179             :          ! If the maximum distplacement is too large, ...
     180       80517 :          IF (dr2_max > 0.25_dp*verlet_skin**2 .OR. build_from_scratch) THEN
     181      573889 :             DO iparticle = 1, nparticle
     182     4530422 :                r_last_update(iparticle)%r = particle_set(iparticle)%r(:)
     183             :             END DO
     184             :             update_neighbor_lists = .TRUE.
     185             :          END IF
     186             :       ELSE
     187             :          ! There is no r_last_update to compare with. Neighbor lists from scratch.
     188      615224 :          ALLOCATE (r_last_update(nparticle))
     189      602699 :          DO iparticle = 1, nparticle
     190     4804057 :             r_last_update(iparticle)%r = particle_set(iparticle)%r(:)
     191             :          END DO
     192             : 
     193        2505 :          update_neighbor_lists = .TRUE.
     194        2505 :          build_from_scratch = .TRUE.
     195             :       END IF
     196             :       ! Force Update
     197       83022 :       IF (PRESENT(force_update)) THEN
     198           0 :          IF (force_update) update_neighbor_lists = .TRUE.
     199             :       END IF
     200             : 
     201             :       ! Allocate the r_last_update_pbc, rshell_last_update_pbc, rcore_last_update_pbc
     202       83022 :       IF (.NOT. ASSOCIATED(r_last_update_pbc)) THEN
     203      615224 :          ALLOCATE (r_last_update_pbc(nparticle))
     204             :       END IF
     205       83022 :       IF (shell_present .AND. .NOT. ASSOCIATED(rshell_last_update_pbc)) THEN
     206       28934 :          ALLOCATE (rshell_last_update_pbc(nshell))
     207             :       END IF
     208       83022 :       IF (shell_present .AND. .NOT. ASSOCIATED(rcore_last_update_pbc)) THEN
     209       28934 :          ALLOCATE (rcore_last_update_pbc(nshell))
     210             :       END IF
     211             : 
     212             :       ! update the neighbor lists
     213       83022 :       IF (update_neighbor_lists) THEN
     214             :          ! determine which pairs of atom kinds need full neighbor lists. Full
     215             :          ! means that atom a is in the neighbor list of atom b and vice versa.
     216       44700 :          ALLOCATE (full_nl(nparticle_kind, nparticle_kind))
     217       11175 :          IF (ASSOCIATED(potparm)) THEN
     218       61308 :             DO ikind = 1, nparticle_kind
     219      741399 :                DO jkind = ikind, nparticle_kind
     220      680091 :                   full_nl(ikind, jkind) = .FALSE.
     221     1360058 :                   IF (ANY(potparm%pot(ikind, jkind)%pot%type == tersoff_type)) THEN
     222         132 :                      full_nl(ikind, jkind) = .TRUE.
     223             :                   END IF
     224     1360185 :                   IF (ANY(potparm%pot(ikind, jkind)%pot%type == siepmann_type)) THEN
     225           5 :                      full_nl(ikind, jkind) = .TRUE.
     226             :                   END IF
     227     1360189 :                   IF (ANY(potparm%pot(ikind, jkind)%pot%type == gal_type)) THEN
     228           1 :                      full_nl(ikind, jkind) = .TRUE.
     229             :                   END IF
     230     1360189 :                   IF (ANY(potparm%pot(ikind, jkind)%pot%type == gal21_type)) THEN
     231           1 :                      full_nl(ikind, jkind) = .TRUE.
     232             :                   END IF
     233     1360178 :                   IF (ANY(potparm%pot(ikind, jkind)%pot%type == nequip_type)) THEN
     234          12 :                      full_nl(ikind, jkind) = .TRUE.
     235             :                   END IF
     236     1360182 :                   IF (ANY(potparm%pot(ikind, jkind)%pot%type == allegro_type)) THEN
     237           8 :                      full_nl(ikind, jkind) = .TRUE.
     238             :                   END IF
     239     1360148 :                   IF (ANY(potparm%pot(ikind, jkind)%pot%type == ace_type)) THEN
     240          42 :                      full_nl(ikind, jkind) = .TRUE.
     241             :                   END IF
     242      730254 :                   full_nl(jkind, ikind) = full_nl(ikind, jkind)
     243             :                END DO
     244             :             END DO
     245             :          ELSE
     246         178 :             full_nl = .FALSE.
     247             :          END IF
     248             :          CALL build_fist_neighbor_lists(atomic_kind_set, particle_set, &
     249             :                                         local_particles, cell, rlist_cut, rlist_lowsq, ei_scale14, &
     250             :                                         vdw_scale14, nonbonded, para_env, &
     251             :                                         build_from_scratch=build_from_scratch, geo_check=geo_check, &
     252             :                                         mm_section=mm_section, full_nl=full_nl, &
     253       11507 :                                         exclusions=exclusions)
     254             : 
     255       11175 :          CALL cell_release(cell_last_update)
     256       11175 :          CALL cell_create(cell_last_update)
     257       11175 :          CALL cell_clone(cell, cell_last_update)
     258             : 
     259       11175 :          IF (counter > 0) THEN
     260        8670 :             num_update = num_update + 1
     261        8670 :             lup = counter + 1 - last_update
     262        8670 :             last_update = counter + 1
     263        8670 :             aup = aup + (lup - aup)/REAL(num_update, KIND=dp)
     264             :          ELSE
     265        2505 :             num_update = 0
     266        2505 :             lup = 0
     267        2505 :             last_update = 1
     268        2505 :             aup = 0.0_dp
     269             :          END IF
     270             : 
     271             :          CALL fist_nonbond_env_set(fist_nonbond_env, &
     272             :                                    lup=lup, &
     273             :                                    aup=aup, &
     274             :                                    r_last_update=r_last_update, &
     275             :                                    r_last_update_pbc=r_last_update_pbc, &
     276             :                                    rshell_last_update_pbc=rshell_last_update_pbc, &
     277             :                                    rcore_last_update_pbc=rcore_last_update_pbc, &
     278             :                                    nonbonded=nonbonded, &
     279             :                                    num_update=num_update, &
     280             :                                    last_update=last_update, &
     281       11175 :                                    cell_last_update=cell_last_update)
     282             : 
     283             :          output_unit = cp_print_key_unit_nr(logger, mm_section, "PRINT%NEIGHBOR_LISTS", &
     284       11175 :                                             extension=".mmLog")
     285       11175 :          IF (output_unit > 0) THEN
     286             :             WRITE (UNIT=output_unit, &
     287             :                    FMT="(/,T2,A,/,T52,A,/,A,T31,A,T49,2(1X,F15.2),/,T2,A,/)") &
     288         177 :                REPEAT("*", 79), "INSTANTANEOUS        AVERAGES", &
     289         354 :                " LIST UPDATES[steps]", "= ", lup, aup, REPEAT("*", 79)
     290             :          END IF
     291             :          CALL cp_print_key_finished_output(output_unit, logger, mm_section, &
     292       11175 :                                            "PRINT%NEIGHBOR_LISTS")
     293       11175 :          DEALLOCATE (full_nl)
     294             :       END IF
     295             : 
     296             :       ! Store particle positions after the last update, translated to the
     297             :       ! primitive cell, in r_last_update_pbc.
     298     8366211 :       DO iparticle = 1, nparticle
     299             :          ! The pbc algorithm is sensitive to numeric noise and compiler optimization because of ANINT.
     300             :          ! Therefore we need to call here exactly the same routine as in build_neighbor_lists.
     301    33132756 :          rab_last_update = pbc(r_last_update(iparticle)%r, cell_last_update) - r_last_update(iparticle)%r
     302     8283189 :          CALL real_to_scaled(s, rab_last_update, cell_last_update)
     303     8283189 :          CALL scaled_to_real(rab, s, cell)
     304             : 
     305    66265512 :          r_last_update_pbc(iparticle)%r = particle_set(iparticle)%r + rab
     306             :          ! Use the same translation for core and shell.
     307     8283189 :          ishell = particle_set(iparticle)%shell_index
     308     8366211 :          IF (ishell /= 0) THEN
     309     6086768 :             rshell_last_update_pbc(ishell)%r = rab + shell_particle_set(ishell)%r(:)
     310      760846 :             IF (shell_adiabatic) THEN
     311     6086768 :                rcore_last_update_pbc(ishell)%r = rab + core_particle_set(ishell)%r(:)
     312             :             ELSE
     313           0 :                rcore_last_update_pbc(ishell)%r = r_last_update_pbc(iparticle)%r(:)
     314             :             END IF
     315             :          END IF
     316             :       END DO
     317             : 
     318       83022 :       counter = counter + 1
     319       83022 :       CALL fist_nonbond_env_set(fist_nonbond_env, counter=counter)
     320       83022 :       CALL timestop(handle)
     321             : 
     322       83022 :    END SUBROUTINE list_control
     323             : 
     324             : END MODULE fist_neighbor_list_control

Generated by: LCOV version 1.15