(git:c28f603)
Loading...
Searching...
No Matches
particle_types.F
Go to the documentation of this file.
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! **************************************************************************************************
21 USE kinds, ONLY: dp
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! **************************************************************************************************
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, &
58
59CONTAINS
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 SUBROUTINE allocate_particle_set(particle_set, nparticle)
70 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
71 INTEGER, INTENT(IN) :: nparticle
72
73 IF (ASSOCIATED(particle_set)) THEN
74 CALL deallocate_particle_set(particle_set)
75 END IF
76 ALLOCATE (particle_set(nparticle))
77
78 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 SUBROUTINE deallocate_particle_set(particle_set)
88 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
89
90 IF (ASSOCIATED(particle_set)) THEN
91 DEALLOCATE (particle_set)
92 NULLIFY (particle_set)
93 END IF
94
95 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 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 CALL timeset(routinen, handle)
121
122 nparticle = SIZE(particle_set)
123 update_pos = PRESENT(pos)
124 update_vel = PRESENT(vel)
125 update_for = PRESENT(for)
126 my_add = .false.
127 IF (PRESENT(add)) my_add = add
128
129 IF (update_pos) THEN
130 CALL int_group%sum(pos)
131 IF (my_add) THEN
132 DO iparticle = 1, nparticle
133 particle_set(iparticle)%r(:) = particle_set(iparticle)%r(:) + pos(:, iparticle)
134 END DO
135 ELSE
136 DO iparticle = 1, nparticle
137 particle_set(iparticle)%r(:) = pos(:, iparticle)
138 END DO
139 END IF
140 END IF
141 IF (update_vel) THEN
142 CALL int_group%sum(vel)
143 IF (my_add) THEN
144 DO iparticle = 1, nparticle
145 particle_set(iparticle)%v(:) = particle_set(iparticle)%v(:) + vel(:, iparticle)
146 END DO
147 ELSE
148 DO iparticle = 1, nparticle
149 particle_set(iparticle)%v(:) = vel(:, iparticle)
150 END DO
151 END IF
152 END IF
153 IF (update_for) THEN
154 CALL int_group%sum(for)
155 IF (my_add) THEN
156 DO iparticle = 1, nparticle
157 particle_set(iparticle)%f(:) = particle_set(iparticle)%f(:) + for(:, iparticle)
158 END DO
159 ELSE
160 DO iparticle = 1, nparticle
161 particle_set(iparticle)%f(:) = for(:, iparticle)
162 END DO
163 END IF
164 END IF
165
166 CALL timestop(handle)
167
168 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 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 ic = 3*(iatom - 1)
192 IF (particle_set(iatom)%shell_index == 0) THEN
193 x(1:3) = vector(ic + 1:ic + 3)
194 ELSE
195 is = 3*(SIZE(particle_set) + particle_set(iatom)%shell_index - 1)
196 mass = particle_set(iatom)%atomic_kind%mass
197 fc = particle_set(iatom)%atomic_kind%shell%mass_core/mass
198 fs = particle_set(iatom)%atomic_kind%shell%mass_shell/mass
199 x(1:3) = fc*vector(ic + 1:ic + 3) + fs*vector(is + 1:is + 3)
200 END IF
201
202 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 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 ic = 3*(iatom - 1)
229 IF (particle_set(iatom)%shell_index == 0) THEN
230 vector(ic + 1:ic + 3) = vector(ic + 1:ic + 3) + x(1:3)
231 x(1:3) = vector(ic + 1:ic + 3)
232 ELSE
233 is = 3*(SIZE(particle_set) + particle_set(iatom)%shell_index - 1)
234 mass = particle_set(iatom)%atomic_kind%mass
235 fc = particle_set(iatom)%atomic_kind%shell%mass_core/mass
236 fs = particle_set(iatom)%atomic_kind%shell%mass_shell/mass
237 vector(ic + 1:ic + 3) = vector(ic + 1:ic + 3) + x(1:3)
238 vector(is + 1:is + 3) = vector(is + 1:is + 3) + x(1:3)
239 x(1:3) = fc*vector(ic + 1:ic + 3) + fs*vector(is + 1:is + 3)
240 END IF
241
242 END SUBROUTINE update_particle_pos_or_vel
243
244END MODULE particle_types
for(int lxp=0;lxp<=lp;lxp++)
Define the atomic kind types and their sub types.
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Interface to the message passing library MPI.
Define the data structure for the particle information.
pure subroutine, public update_particle_pos_or_vel(iatom, particle_set, x, vector)
Update the atomic position or velocity by x and return the updated atomic position or velocity in x e...
subroutine, public deallocate_particle_set(particle_set)
Deallocate a particle set.
pure real(kind=dp) function, dimension(3), public get_particle_pos_or_vel(iatom, particle_set, vector)
Return the atomic position or velocity of atom iatom in x from a packed vector even if core-shell par...
subroutine, public update_particle_set(particle_set, int_group, pos, vel, for, add)
...
subroutine, public allocate_particle_set(particle_set, nparticle)
Allocate a particle set.
Provides all information about an atomic kind.