LCOV - code coverage report
Current view: top level - src/subsys - particle_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:85b8a9b) Lines: 76.6 % 64 49
Test Date: 2026-06-14 06:48:14 Functions: 83.3 % 6 5

            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              : !> \brief Define the data structure for the particle information.
      10              : !> \par History
      11              : !>      - Atomic kind added in particle_type (MK,08.01.2002)
      12              : !>      - Functionality for particle_type added (MK,14.01.2002)
      13              : !>      - Allow for general coordinate input (MK,13.09.2003)
      14              : !>      - Molecule concept introduced (MK,26.09.2003)
      15              : !>      - Last atom information added (jgh,23.05.2004)
      16              : !>      - particle_type cleaned (MK,03.02.2005)
      17              : !> \author CJM, MK
      18              : ! **************************************************************************************************
      19              : MODULE particle_types
      20              :    USE atomic_kind_types,               ONLY: atomic_kind_type
      21              :    USE kinds,                           ONLY: dp
      22              :    USE message_passing,                 ONLY: mp_comm_type
      23              : #include "../base/base_uses.f90"
      24              : 
      25              :    IMPLICIT NONE
      26              : 
      27              :    PRIVATE
      28              : 
      29              :    ! Global parameters (in this module)
      30              : 
      31              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'particle_types'
      32              : 
      33              :    ! Data types
      34              : ! **************************************************************************************************
      35              :    TYPE particle_type
      36              :       TYPE(atomic_kind_type), POINTER       :: atomic_kind => Null() ! atomic kind information
      37              :       REAL(KIND=dp), DIMENSION(3)           :: f = 0.0_dp, & ! force
      38              :                                                r = 0.0_dp, & ! position
      39              :                                                v = 0.0_dp ! velocity
      40              :       ! Particle dependent terms for shell-model
      41              :       INTEGER                               :: atom_index = 0, &
      42              :                                                t_region_index = 0, &
      43              :                                                shell_index = 0, &
      44              :                                                fragment_index = 0
      45              :    END TYPE particle_type
      46              : 
      47              :    ! Public data types
      48              : 
      49              :    PUBLIC :: particle_type
      50              : 
      51              :    ! Public subroutines
      52              : 
      53              :    PUBLIC :: allocate_particle_set, &
      54              :              deallocate_particle_set, &
      55              :              update_particle_set, &
      56              :              update_particle_pos_or_vel, &
      57              :              get_particle_pos_or_vel
      58              : 
      59              : CONTAINS
      60              : 
      61              : ! **************************************************************************************************
      62              : !> \brief   Allocate a particle set.
      63              : !> \param particle_set ...
      64              : !> \param nparticle ...
      65              : !> \date    14.01.2002
      66              : !> \author  MK
      67              : !> \version 1.0
      68              : ! **************************************************************************************************
      69        22368 :    SUBROUTINE allocate_particle_set(particle_set, nparticle)
      70              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
      71              :       INTEGER, INTENT(IN)                                :: nparticle
      72              : 
      73        22368 :       IF (ASSOCIATED(particle_set)) THEN
      74            0 :          CALL deallocate_particle_set(particle_set)
      75              :       END IF
      76      1366622 :       ALLOCATE (particle_set(nparticle))
      77              : 
      78        22368 :    END SUBROUTINE allocate_particle_set
      79              : 
      80              : ! **************************************************************************************************
      81              : !> \brief   Deallocate a particle set.
      82              : !> \param particle_set ...
      83              : !> \date    14.01.2002
      84              : !> \author  MK
      85              : !> \version 1.0
      86              : ! **************************************************************************************************
      87        22368 :    SUBROUTINE deallocate_particle_set(particle_set)
      88              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
      89              : 
      90        22368 :       IF (ASSOCIATED(particle_set)) THEN
      91        22368 :          DEALLOCATE (particle_set)
      92              :          NULLIFY (particle_set)
      93              :       END IF
      94              : 
      95        22368 :    END SUBROUTINE deallocate_particle_set
      96              : 
      97              : ! **************************************************************************************************
      98              : !> \brief ...
      99              : !> \param particle_set ...
     100              : !> \param int_group ...
     101              : !> \param pos ...
     102              : !> \param vel ...
     103              : !> \param for ...
     104              : !> \param add ...
     105              : ! **************************************************************************************************
     106        92520 :    SUBROUTINE update_particle_set(particle_set, int_group, pos, vel, for, add)
     107              : 
     108              :       TYPE(particle_type), INTENT(INOUT)                 :: particle_set(:)
     109              : 
     110              :       CLASS(mp_comm_type), INTENT(IN)                     :: int_group
     111              :       REAL(KIND=dp), INTENT(INOUT), OPTIONAL             :: pos(:, :), vel(:, :), for(:, :)
     112              :       LOGICAL, INTENT(IN), OPTIONAL                      :: add
     113              : 
     114              :       CHARACTER(len=*), PARAMETER :: routineN = 'update_particle_set'
     115              : 
     116              :       INTEGER                                            :: handle, iparticle, nparticle
     117              :       LOGICAL                                            :: my_add, update_for, update_pos, &
     118              :                                                             update_vel
     119              : 
     120        92520 :       CALL timeset(routineN, handle)
     121              : 
     122        92520 :       nparticle = SIZE(particle_set)
     123        92520 :       update_pos = PRESENT(pos)
     124        92520 :       update_vel = PRESENT(vel)
     125        92520 :       update_for = PRESENT(for)
     126        92520 :       my_add = .FALSE.
     127        92520 :       IF (PRESENT(add)) my_add = add
     128              : 
     129        92520 :       IF (update_pos) THEN
     130     51940587 :          CALL int_group%sum(pos)
     131        44939 :          IF (my_add) THEN
     132            0 :             DO iparticle = 1, nparticle
     133            0 :                particle_set(iparticle)%r(:) = particle_set(iparticle)%r(:) + pos(:, iparticle)
     134              :             END DO
     135              :          ELSE
     136      6531895 :             DO iparticle = 1, nparticle
     137     25992763 :                particle_set(iparticle)%r(:) = pos(:, iparticle)
     138              :             END DO
     139              :          END IF
     140              :       END IF
     141        92520 :       IF (update_vel) THEN
     142     51811091 :          CALL int_group%sum(vel)
     143        46051 :          IF (my_add) THEN
     144            0 :             DO iparticle = 1, nparticle
     145            0 :                particle_set(iparticle)%v(:) = particle_set(iparticle)%v(:) + vel(:, iparticle)
     146              :             END DO
     147              :          ELSE
     148      6516681 :             DO iparticle = 1, nparticle
     149     25928571 :                particle_set(iparticle)%v(:) = vel(:, iparticle)
     150              :             END DO
     151              :          END IF
     152              :       END IF
     153        92520 :       IF (update_for) THEN
     154       131466 :          CALL int_group%sum(for)
     155         1530 :          IF (my_add) THEN
     156        17772 :             DO iparticle = 1, nparticle
     157        66498 :                particle_set(iparticle)%f(:) = particle_set(iparticle)%f(:) + for(:, iparticle)
     158              :             END DO
     159              :          ELSE
     160            0 :             DO iparticle = 1, nparticle
     161            0 :                particle_set(iparticle)%f(:) = for(:, iparticle)
     162              :             END DO
     163              :          END IF
     164              :       END IF
     165              : 
     166        92520 :       CALL timestop(handle)
     167              : 
     168        92520 :    END SUBROUTINE update_particle_set
     169              : 
     170              : ! **************************************************************************************************
     171              : !> \brief   Return the atomic position or velocity of atom iatom in x from a
     172              : !>          packed vector even if core-shell particles are present
     173              : !> \param iatom ...
     174              : !> \param particle_set ...
     175              : !> \param vector ...
     176              : !> \return ...
     177              : !> \date    25.11.2010
     178              : !> \author  Matthias Krack
     179              : !> \version 1.0
     180              : ! **************************************************************************************************
     181       363175 :    PURE FUNCTION get_particle_pos_or_vel(iatom, particle_set, vector) RESULT(x)
     182              : 
     183              :       INTEGER, INTENT(IN)                                :: iatom
     184              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     185              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: vector
     186              :       REAL(KIND=dp), DIMENSION(3)                        :: x
     187              : 
     188              :       INTEGER                                            :: ic, is
     189              :       REAL(KIND=dp)                                      :: fc, fs, mass
     190              : 
     191       363175 :       ic = 3*(iatom - 1)
     192       363175 :       IF (particle_set(iatom)%shell_index == 0) THEN
     193       758820 :          x(1:3) = vector(ic + 1:ic + 3)
     194              :       ELSE
     195       173470 :          is = 3*(SIZE(particle_set) + particle_set(iatom)%shell_index - 1)
     196       173470 :          mass = particle_set(iatom)%atomic_kind%mass
     197       173470 :          fc = particle_set(iatom)%atomic_kind%shell%mass_core/mass
     198       173470 :          fs = particle_set(iatom)%atomic_kind%shell%mass_shell/mass
     199       693880 :          x(1:3) = fc*vector(ic + 1:ic + 3) + fs*vector(is + 1:is + 3)
     200              :       END IF
     201              : 
     202       363175 :    END FUNCTION get_particle_pos_or_vel
     203              : 
     204              : ! **************************************************************************************************
     205              : !> \brief   Update the atomic position or velocity by x and return the updated
     206              : !>          atomic position or velocity in x even if core-shell particles are
     207              : !>          present
     208              : !> \param iatom ...
     209              : !> \param particle_set ...
     210              : !> \param x ...
     211              : !> \param vector ...
     212              : !> \date    26.11.2010
     213              : !> \author  Matthias Krack
     214              : !> \version 1.0
     215              : !> \note    particle-set is not changed, only the positions or velocities in
     216              : !>          the packed vector are updated
     217              : ! **************************************************************************************************
     218         1020 :    PURE SUBROUTINE update_particle_pos_or_vel(iatom, particle_set, x, vector)
     219              : 
     220              :       INTEGER, INTENT(IN)                                :: iatom
     221              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     222              :       REAL(KIND=dp), DIMENSION(3), INTENT(INOUT)         :: x
     223              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: vector
     224              : 
     225              :       INTEGER                                            :: ic, is
     226              :       REAL(KIND=dp)                                      :: fc, fs, mass
     227              : 
     228         1020 :       ic = 3*(iatom - 1)
     229         1020 :       IF (particle_set(iatom)%shell_index == 0) THEN
     230         4080 :          vector(ic + 1:ic + 3) = vector(ic + 1:ic + 3) + x(1:3)
     231         4080 :          x(1:3) = vector(ic + 1:ic + 3)
     232              :       ELSE
     233            0 :          is = 3*(SIZE(particle_set) + particle_set(iatom)%shell_index - 1)
     234            0 :          mass = particle_set(iatom)%atomic_kind%mass
     235            0 :          fc = particle_set(iatom)%atomic_kind%shell%mass_core/mass
     236            0 :          fs = particle_set(iatom)%atomic_kind%shell%mass_shell/mass
     237            0 :          vector(ic + 1:ic + 3) = vector(ic + 1:ic + 3) + x(1:3)
     238            0 :          vector(is + 1:is + 3) = vector(is + 1:is + 3) + x(1:3)
     239            0 :          x(1:3) = fc*vector(ic + 1:ic + 3) + fs*vector(is + 1:is + 3)
     240              :       END IF
     241              : 
     242         1020 :    END SUBROUTINE update_particle_pos_or_vel
     243              : 
     244            0 : END MODULE particle_types
        

Generated by: LCOV version 2.0-1