LCOV - code coverage report
Current view: top level - src - manybody_ace.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 98.9 % 87 86
Test Date: 2025-12-04 06:27:48 Functions: 100.0 % 3 3

            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              : !>      HAF (16-Apr-2025) : Import into CP2K
      11              : !> \author HAF and yury-lysogorskiy and ralf-drautz
      12              : ! **************************************************************************************************
      13              : 
      14              : MODULE manybody_ace
      15              : 
      16              :    USE ISO_C_BINDING,                   ONLY: C_ASSOCIATED
      17              :    USE ace_nlist,                       ONLY: ace_interface
      18              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      19              :                                               get_atomic_kind
      20              :    USE bibliography,                    ONLY: Bochkarev2024,&
      21              :                                               Drautz2019,&
      22              :                                               Lysogorskiy2021,&
      23              :                                               cite_reference
      24              :    USE cell_types,                      ONLY: cell_type
      25              :    USE fist_nonbond_env_types,          ONLY: ace_data_type,&
      26              :                                               fist_nonbond_env_get,&
      27              :                                               fist_nonbond_env_set,&
      28              :                                               fist_nonbond_env_type
      29              :    USE kinds,                           ONLY: dp
      30              :    USE pair_potential_types,            ONLY: ace_type,&
      31              :                                               pair_potential_pp_type,&
      32              :                                               pair_potential_single_type
      33              :    USE particle_types,                  ONLY: particle_type
      34              :    USE physcon,                         ONLY: angstrom,&
      35              :                                               evolt
      36              : #include "./base/base_uses.f90"
      37              : 
      38              :    IMPLICIT NONE
      39              : 
      40              :    PRIVATE
      41              :    PUBLIC ace_energy_store_force_virial, ace_add_force_virial
      42              : 
      43              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'manybody_ace'
      44              : 
      45              : CONTAINS
      46              : 
      47              : ! **************************************************************************************************
      48              : !> \brief ...
      49              : !> \param particle_set ...
      50              : !> \param atomic_kind_set ...
      51              : !> \param potparm ...
      52              : !> \param ace_data ...
      53              : ! **************************************************************************************************
      54            6 :    SUBROUTINE init_ace_data(particle_set, atomic_kind_set, potparm, &
      55              :                             ace_data)
      56              : 
      57              :       TYPE(particle_type), POINTER                       :: particle_set(:)
      58              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind_set(:)
      59              :       TYPE(pair_potential_pp_type), POINTER              :: potparm
      60              :       TYPE(ace_data_type), POINTER                       :: ace_data
      61              : 
      62              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'init_ace_data'
      63              : 
      64              :       CHARACTER(2)                                       :: element_symbol
      65              :       INTEGER                                            :: ace_natom, handle, i, iat, iat_use, &
      66              :                                                             ikind, jkind, lkind, n_atoms
      67            6 :       INTEGER, ALLOCATABLE                               :: use_atom_type(:)
      68            6 :       INTEGER, DIMENSION(:), POINTER                     :: ak_alist
      69            6 :       LOGICAL, ALLOCATABLE                               :: use_atom(:)
      70              :       TYPE(pair_potential_single_type), POINTER          :: pot
      71              : 
      72            6 :       CALL timeset(routineN, handle)
      73              : 
      74              :       ! init ace_data
      75            6 :       IF (.NOT. ASSOCIATED(ace_data)) THEN
      76            0 :          ALLOCATE (ace_data)
      77              :       END IF
      78              : 
      79            6 :       n_atoms = SIZE(particle_set)
      80           18 :       ALLOCATE (use_atom(n_atoms))
      81           12 :       ALLOCATE (use_atom_type(n_atoms))
      82          996 :       use_atom = .FALSE.
      83          996 :       use_atom_type = 0
      84              : 
      85           18 :       DO ikind = 1, SIZE(atomic_kind_set)
      86           12 :          pot => potparm%pot(ikind, ikind)%pot
      87           30 :          DO i = 1, SIZE(pot%type)
      88           12 :             IF (pot%type(i) /= ace_type) CYCLE
      89              :             CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), &
      90              :                                  element_symbol=element_symbol, &
      91           12 :                                  natom=lkind, atom_list=ak_alist)
      92           12 :             IF (lkind < 1) CYCLE
      93           12 :             ace_data%model = pot%set(i)%ace%model
      94           12 :             jkind = 0
      95           18 :             DO iat = 1, SIZE(ace_data%model%symbolc)
      96           18 :                IF (element_symbol == ace_data%model%symbolc(iat)) THEN
      97              :                   jkind = iat
      98              :                   EXIT
      99              :                END IF
     100              :             END DO
     101           12 :             CPASSERT(jkind > 0)
     102         1026 :             DO iat = 1, lkind
     103          990 :                use_atom_type(ak_alist(iat)) = jkind
     104         1002 :                use_atom(ak_alist(iat)) = .TRUE.
     105              :             END DO
     106              :          END DO ! i
     107              :       END DO ! ikind
     108            6 :       CPASSERT(C_ASSOCIATED(ace_data%model%c_ptr))
     109              : 
     110          996 :       ace_natom = COUNT(use_atom)
     111              : 
     112            6 :       IF (.NOT. ALLOCATED(ace_data%uctype)) THEN
     113           18 :          ALLOCATE (ace_data%uctype(1:ace_natom))
     114              :       END IF
     115              : 
     116              :       iat_use = 0
     117          996 :       DO iat = 1, n_atoms
     118          990 :          IF (.NOT. use_atom(iat)) CYCLE
     119          990 :          iat_use = iat_use + 1
     120          996 :          ace_data%uctype(iat_use) = use_atom_type(iat)
     121              :       END DO
     122              : 
     123            6 :       IF (iat_use > 0) THEN
     124            6 :          CALL cite_reference(Drautz2019)
     125            6 :          CALL cite_reference(Lysogorskiy2021)
     126            6 :          CALL cite_reference(Bochkarev2024)
     127              :       END IF
     128              : 
     129            6 :       IF (.NOT. ALLOCATED(ace_data%force)) THEN
     130           18 :          ALLOCATE (ace_data%force(3, ace_natom))
     131           18 :          ALLOCATE (ace_data%use_indices(ace_natom))
     132           12 :          ALLOCATE (ace_data%inverse_index_map(n_atoms))
     133              :       END IF
     134            6 :       CPASSERT(SIZE(ace_data%force, 2) == ace_natom)
     135              : 
     136            6 :       iat_use = 0
     137          996 :       ace_data%inverse_index_map(:) = 0
     138          996 :       DO iat = 1, n_atoms
     139          996 :          IF (use_atom(iat)) THEN
     140          990 :             iat_use = iat_use + 1
     141          990 :             ace_data%use_indices(iat_use) = iat
     142          990 :             ace_data%inverse_index_map(iat) = iat_use
     143              :          END IF
     144              :       END DO
     145            6 :       ace_data%natom = ace_natom
     146            6 :       DEALLOCATE (use_atom, use_atom_type)
     147              : 
     148            6 :       CALL timestop(handle)
     149              : 
     150            6 :    END SUBROUTINE init_ace_data
     151              : 
     152              : ! **************************************************************************************************
     153              : !> \brief ...
     154              : !>     > \param particle_set ...
     155              : !> \param particle_set ...
     156              : !> \param cell ...
     157              : !> \param atomic_kind_set ...
     158              : !> \param potparm ...
     159              : !> \param fist_nonbond_env ...
     160              : !> \param pot_ace ...
     161              : ! **************************************************************************************************
     162          412 :    SUBROUTINE ace_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, &
     163              :                                             fist_nonbond_env, pot_ace)
     164              : 
     165              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     166              :       TYPE(cell_type), POINTER                           :: cell
     167              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind_set(:)
     168              :       TYPE(pair_potential_pp_type), POINTER              :: potparm
     169              :       TYPE(fist_nonbond_env_type), POINTER               :: fist_nonbond_env
     170              :       REAL(kind=dp), INTENT(OUT)                         :: pot_ace
     171              : 
     172              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'ace_energy_store_force_virial'
     173              : 
     174              :       INTEGER                                            :: handle
     175              :       REAL(kind=dp)                                      :: ace_virial(1:6)
     176              :       TYPE(ace_data_type), POINTER                       :: ace_data
     177              : 
     178          206 :       CALL timeset(routineN, handle)
     179              : 
     180              :       ! get ace_data to save force, virial info
     181          206 :       CALL fist_nonbond_env_get(fist_nonbond_env, ace_data=ace_data)
     182          206 :       IF (.NOT. ASSOCIATED(ace_data)) THEN
     183           84 :          ALLOCATE (ace_data)
     184              :          !initialize ace_data:
     185            6 :          CALL init_ace_data(particle_set, atomic_kind_set, potparm, ace_data)
     186            6 :          CALL fist_nonbond_env_set(fist_nonbond_env, ace_data=ace_data)
     187              :       END IF
     188              : 
     189              :       CALL ace_interface(ace_data%natom, ace_data%uctype, &
     190              :                          pot_ace, ace_data%force, ace_virial, &
     191          206 :                          fist_nonbond_env, cell, ace_data)
     192              : 
     193              :       ! convert units
     194          206 :       pot_ace = pot_ace/evolt
     195       157766 :       ace_data%force = ace_data%force/(evolt/angstrom)
     196         1442 :       ace_virial = ace_virial/evolt
     197              : 
     198              :       ! minus sign due to CP2K conventions
     199          206 :       ace_data%virial(1, 1) = -ace_virial(1)
     200          206 :       ace_data%virial(2, 2) = -ace_virial(2)
     201          206 :       ace_data%virial(3, 3) = -ace_virial(3)
     202          206 :       ace_data%virial(1, 2) = -ace_virial(4)
     203          206 :       ace_data%virial(2, 1) = -ace_virial(4)
     204          206 :       ace_data%virial(1, 3) = -ace_virial(5)
     205          206 :       ace_data%virial(3, 1) = -ace_virial(5)
     206          206 :       ace_data%virial(2, 3) = -ace_virial(6)
     207          206 :       ace_data%virial(3, 2) = -ace_virial(6)
     208              : 
     209          206 :       CALL timestop(handle)
     210          206 :    END SUBROUTINE ace_energy_store_force_virial
     211              : 
     212              : ! **************************************************************************************************
     213              : !> \brief ...
     214              : !> \param fist_nonbond_env ...
     215              : !> \param force ...
     216              : !> \param pv_nonbond ...
     217              : !> \param use_virial ...
     218              : ! **************************************************************************************************
     219          206 :    SUBROUTINE ace_add_force_virial(fist_nonbond_env, force, pv_nonbond, use_virial)
     220              :       TYPE(fist_nonbond_env_type), POINTER               :: fist_nonbond_env
     221              :       REAL(KIND=dp), INTENT(INOUT)                       :: force(:, :), pv_nonbond(3, 3)
     222              :       LOGICAL, OPTIONAL                                  :: use_virial
     223              : 
     224              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'ace_add_force_virial'
     225              : 
     226              :       INTEGER                                            :: handle, iat, iat_use
     227              :       TYPE(ace_data_type), POINTER                       :: ace_data
     228              : 
     229          206 :       CALL timeset(routineN, handle)
     230              : 
     231          206 :       CALL fist_nonbond_env_get(fist_nonbond_env, ace_data=ace_data)
     232              : 
     233          206 :       IF (.NOT. ASSOCIATED(ace_data)) RETURN
     234              : 
     235        39596 :       DO iat_use = 1, SIZE(ace_data%use_indices)
     236        39390 :          iat = ace_data%use_indices(iat_use)
     237        39390 :          CPASSERT(iat >= 1 .AND. iat <= SIZE(force, 2))
     238       157766 :          force(1:3, iat) = force(1:3, iat) + ace_data%force(1:3, iat_use)
     239              :       END DO
     240              : 
     241          206 :       IF (use_virial) THEN
     242           26 :          pv_nonbond = pv_nonbond + ace_data%virial
     243              :       END IF
     244              : 
     245          206 :       CALL timestop(handle)
     246              :    END SUBROUTINE ace_add_force_virial
     247              : 
     248              : END MODULE manybody_ace
        

Generated by: LCOV version 2.0-1