LCOV - code coverage report
Current view: top level - src - manybody_quip.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 40.0 % 5 2
Test Date: 2025-07-25 12:55:17 Functions: 50.0 % 2 1

            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              : MODULE manybody_quip
       9              : 
      10              :    USE cp_log_handling, ONLY: cp_logger_get_default_io_unit
      11              :    USE atomic_kind_types, ONLY: atomic_kind_type
      12              :    USE bibliography, ONLY: QUIP_ref, &
      13              :                            cite_reference
      14              :    USE cell_types, ONLY: cell_type
      15              :    USE message_passing, ONLY: mp_para_env_type
      16              :    USE fist_nonbond_env_types, ONLY: fist_nonbond_env_get, &
      17              :                                      fist_nonbond_env_set, &
      18              :                                      fist_nonbond_env_type, &
      19              :                                      quip_data_type
      20              :    USE kinds, ONLY: dp
      21              :    USE pair_potential_types, ONLY: pair_potential_pp_type, &
      22              :                                    pair_potential_single_type, &
      23              :                                    quip_pot_type, &
      24              :                                    quip_type
      25              :    USE particle_types, ONLY: particle_type
      26              :    USE physcon, ONLY: angstrom, &
      27              :                       evolt
      28              : #ifdef __QUIP
      29              :    USE quip_unified_wrapper_module, ONLY: quip_unified_wrapper
      30              : #endif
      31              : 
      32              : #include "./base/base_uses.f90"
      33              : 
      34              :    IMPLICIT NONE
      35              : 
      36              :    PRIVATE
      37              : 
      38              :    PUBLIC quip_energy_store_force_virial, quip_add_force_virial
      39              : 
      40              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'manybody_quip'
      41              : 
      42              : CONTAINS
      43              : 
      44              : ! **************************************************************************************************
      45              : !> \brief ...
      46              : !> \param particle_set ...
      47              : !> \param cell ...
      48              : !> \param atomic_kind_set ...
      49              : !> \param potparm ...
      50              : !> \param fist_nonbond_env ...
      51              : !> \param pot_quip ...
      52              : !> \param para_env ...
      53              : ! **************************************************************************************************
      54            0 :    SUBROUTINE quip_energy_store_force_virial(particle_set, cell, atomic_kind_set, potparm, fist_nonbond_env, &
      55              :                                              pot_quip, para_env)
      56              :       TYPE(particle_type), POINTER             :: particle_set(:)
      57              :       TYPE(cell_type), POINTER                 :: cell
      58              :       TYPE(atomic_kind_type), POINTER          :: atomic_kind_set(:)
      59              :       TYPE(pair_potential_pp_type), POINTER    :: potparm
      60              :       TYPE(fist_nonbond_env_type), POINTER     :: fist_nonbond_env
      61              :       REAL(kind=dp)                            :: pot_quip
      62              :       TYPE(mp_para_env_type), OPTIONAL, &
      63              :          POINTER                                :: para_env
      64              : 
      65              : #ifdef __QUIP
      66              :       CHARACTER(len=2), ALLOCATABLE            :: elem_symbol(:)
      67              :       INTEGER                                  :: i, iat, iat_use, ikind, &
      68              :                                                   jkind, n_atoms, n_atoms_use, &
      69              :                                                   output_unit
      70              :       LOGICAL                                  :: do_parallel
      71              :       LOGICAL, ALLOCATABLE                     :: use_atom(:)
      72              :       REAL(kind=dp)                            :: lattice(3, 3), virial(3, 3)
      73              :       REAL(kind=dp), ALLOCATABLE               :: force(:, :), pos(:, :)
      74              :       TYPE(pair_potential_single_type), &
      75              :          POINTER                                :: pot
      76              :       TYPE(quip_data_type), POINTER            :: quip_data
      77              :       TYPE(quip_pot_type), POINTER             :: quip
      78              : 
      79              : #endif
      80              : #ifndef __QUIP
      81              :       MARK_USED(particle_set)
      82              :       MARK_USED(cell)
      83              :       MARK_USED(atomic_kind_set)
      84              :       MARK_USED(potparm)
      85              :       MARK_USED(fist_nonbond_env)
      86              :       MARK_USED(pot_quip)
      87              :       MARK_USED(para_env)
      88              :       CALL cp_abort(__LOCATION__, "In order to use QUIP you need to download "// &
      89            0 :                     "and install the libAtoms/QUIP library (check CP2K manual for details)")
      90              : #else
      91              :       n_atoms = SIZE(particle_set)
      92              :       ALLOCATE (use_atom(n_atoms))
      93              :       use_atom = .FALSE.
      94              : 
      95              :       NULLIFY (quip)
      96              : 
      97              :       DO ikind = 1, SIZE(atomic_kind_set)
      98              :       DO jkind = 1, SIZE(atomic_kind_set)
      99              :          pot => potparm%pot(ikind, jkind)%pot
     100              :          DO i = 1, SIZE(pot%type)
     101              :             IF (pot%type(i) /= quip_type) CYCLE
     102              :             IF (.NOT. ASSOCIATED(quip)) quip => pot%set(i)%quip
     103              :             DO iat = 1, n_atoms
     104              :                IF (particle_set(iat)%atomic_kind%kind_number == ikind .OR. &
     105              :                    particle_set(iat)%atomic_kind%kind_number == jkind) use_atom(iat) = .TRUE.
     106              :             END DO ! iat
     107              :          END DO ! i
     108              :       END DO ! jkind
     109              :       END DO ! ikind
     110              :       n_atoms_use = COUNT(use_atom)
     111              :       ALLOCATE (pos(3, n_atoms_use), force(3, n_atoms_use), elem_symbol(n_atoms_use))
     112              : 
     113              :       iat_use = 0
     114              :       DO iat = 1, n_atoms
     115              :          IF (.NOT. use_atom(iat)) CYCLE
     116              :          iat_use = iat_use + 1
     117              :          pos(1:3, iat_use) = particle_set(iat)%r*angstrom
     118              :          elem_symbol(iat_use) = particle_set(iat)%atomic_kind%element_symbol
     119              :       END DO
     120              :       IF (iat_use > 0) CALL cite_reference(QUIP_ref)
     121              :       output_unit = cp_logger_get_default_io_unit()
     122              :       lattice = cell%hmat*angstrom
     123              :       do_parallel = .FALSE.
     124              :       IF (PRESENT(para_env)) THEN
     125              :          do_parallel = para_env%num_pe > 1
     126              :       END IF
     127              :       IF (do_parallel) THEN
     128              :          CALL quip_unified_wrapper( &
     129              :             N=n_atoms_use, pos=pos, lattice=lattice, symbol=elem_symbol, &
     130              :             quip_param_file=TRIM(quip%quip_file_name), &
     131              :             quip_param_file_len=LEN_TRIM(quip%quip_file_name), &
     132              :             init_args_str=TRIM(quip%init_args), &
     133              :             init_args_str_len=LEN_TRIM(quip%init_args), &
     134              :             calc_args_str=TRIM(quip%calc_args), &
     135              :             calc_args_str_len=LEN_TRIM(quip%calc_args), &
     136              :             energy=pot_quip, force=force, virial=virial, &
     137              :             output_unit=output_unit, mpi_communicator=para_env%get_handle())
     138              :       ELSE
     139              :          CALL quip_unified_wrapper( &
     140              :             N=n_atoms_use, pos=pos, lattice=lattice, symbol=elem_symbol, &
     141              :             quip_param_file=TRIM(quip%quip_file_name), &
     142              :             quip_param_file_len=LEN_TRIM(quip%quip_file_name), &
     143              :             init_args_str=TRIM(quip%init_args), &
     144              :             init_args_str_len=LEN_TRIM(quip%init_args), &
     145              :             calc_args_str=TRIM(quip%calc_args), &
     146              :             calc_args_str_len=LEN_TRIM(quip%calc_args), &
     147              :             energy=pot_quip, force=force, virial=virial, output_unit=output_unit)
     148              :       END IF
     149              :       ! convert units
     150              :       pot_quip = pot_quip/evolt
     151              :       force = force/(evolt/angstrom)
     152              :       virial = virial/evolt
     153              :       ! account for double counting from multiple MPI processes
     154              :       IF (PRESENT(para_env)) pot_quip = pot_quip/REAL(para_env%num_pe, dp)
     155              :       IF (PRESENT(para_env)) force = force/REAL(para_env%num_pe, dp)
     156              :       IF (PRESENT(para_env)) virial = virial/REAL(para_env%num_pe, dp)
     157              :       ! get quip_data to save force, virial info
     158              :       CALL fist_nonbond_env_get(fist_nonbond_env, quip_data=quip_data)
     159              :       IF (.NOT. ASSOCIATED(quip_data)) THEN
     160              :          ALLOCATE (quip_data)
     161              :          CALL fist_nonbond_env_set(fist_nonbond_env, quip_data=quip_data)
     162              :          NULLIFY (quip_data%use_indices, quip_data%force)
     163              :       END IF
     164              :       IF (ASSOCIATED(quip_data%force)) THEN
     165              :          IF (SIZE(quip_data%force, 2) /= n_atoms_use) THEN
     166              :             DEALLOCATE (quip_data%force, quip_data%use_indices)
     167              :          END IF
     168              :       END IF
     169              :       IF (.NOT. ASSOCIATED(quip_data%force)) THEN
     170              :          ALLOCATE (quip_data%force(3, n_atoms_use))
     171              :          ALLOCATE (quip_data%use_indices(n_atoms_use))
     172              :       END IF
     173              :       ! save force, virial info
     174              :       iat_use = 0
     175              :       DO iat = 1, n_atoms
     176              :          IF (use_atom(iat)) THEN
     177              :             iat_use = iat_use + 1
     178              :             quip_data%use_indices(iat_use) = iat
     179              :          END IF
     180              :       END DO
     181              :       quip_data%force = force
     182              :       quip_data%virial = virial
     183              : 
     184              :       DEALLOCATE (use_atom, pos, force, elem_symbol)
     185              : #endif
     186            0 :    END SUBROUTINE quip_energy_store_force_virial
     187              : 
     188              : ! **************************************************************************************************
     189              : !> \brief ...
     190              : !> \param fist_nonbond_env ...
     191              : !> \param force ...
     192              : !> \param virial ...
     193              : ! **************************************************************************************************
     194         9350 :    SUBROUTINE quip_add_force_virial(fist_nonbond_env, force, virial)
     195              :       TYPE(fist_nonbond_env_type), POINTER     :: fist_nonbond_env
     196              :       REAL(KIND=dp)                            :: force(:, :), virial(3, 3)
     197              : 
     198              : #ifdef __QUIP
     199              :       INTEGER                                  :: iat, iat_use
     200              :       TYPE(quip_data_type), POINTER            :: quip_data
     201              : #endif
     202              : 
     203              : #ifndef __QUIP
     204              :       MARK_USED(fist_nonbond_env)
     205              :       MARK_USED(force)
     206              :       MARK_USED(virial)
     207         9350 :       RETURN
     208              : #else
     209              :       CALL fist_nonbond_env_get(fist_nonbond_env, quip_data=quip_data)
     210              :       IF (.NOT. ASSOCIATED(quip_data)) RETURN
     211              : 
     212              :       DO iat_use = 1, SIZE(quip_data%use_indices)
     213              :          iat = quip_data%use_indices(iat_use)
     214              :          CPASSERT(iat >= 1 .AND. iat <= SIZE(force, 2))
     215              :          force(1:3, iat) = force(1:3, iat) + quip_data%force(1:3, iat_use)
     216              :       END DO
     217              :       virial = virial + quip_data%virial
     218              : #endif
     219              :    END SUBROUTINE quip_add_force_virial
     220              : 
     221              : END MODULE manybody_quip
        

Generated by: LCOV version 2.0-1