LCOV - code coverage report
Current view: top level - src - fist_neighbor_list_control.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:262480d) Lines: 102 104 98.1 %
Date: 2024-11-22 07:00:40 Functions: 1 1 100.0 %

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

Generated by: LCOV version 1.15