(git:374b731)
Loading...
Searching...
No Matches
extended_system_dynamics.F
Go to the documentation of this file.
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!> CJM 20-Feb-2001: Now npt_ifo is allocated to zero when not used
11!> CJM 11-apr-2001: adding routines to thermostat ao_type
12!> CJM 02-Aug-2003: renamed
13!> \author CJM
14! **************************************************************************************************
16
23 USE kinds, ONLY: dp
35#include "../../base/base_uses.f90"
36
37 IMPLICIT NONE
38
39 PRIVATE
40 LOGICAL, PARAMETER :: debug_this_module = .false.
41 PUBLIC :: shell_scale_comv, &
45
46 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'extended_system_dynamics'
47
48CONTAINS
49
50! **************************************************************************************************
51!> \brief ...
52!> \param nhc ...
53!> \param npt ...
54!> \param group ...
55!> \date 13-DEC-2000
56!> \par History
57!> none
58!> \author CJM
59! **************************************************************************************************
60 SUBROUTINE lnhc_barostat(nhc, npt, group)
61
62 TYPE(lnhc_parameters_type), POINTER :: nhc
63 TYPE(npt_info_type), DIMENSION(:, :), &
64 INTENT(INOUT) :: npt
65 TYPE(mp_comm_type), INTENT(IN) :: group
66
67 CHARACTER(len=*), PARAMETER :: routinen = 'lnhc_barostat'
68
69 INTEGER :: handle
70 TYPE(map_info_type), POINTER :: map_info
71
72 CALL timeset(routinen, handle)
73 map_info => nhc%map_info
74
75 ! Compute the kinetic energy of the barostat
76 CALL ke_region_baro(map_info, npt, group)
77
78 ! Calculate forces on the Nose-Hoover Thermostat and apply chains
79 CALL do_nhc(nhc, map_info)
80
81 ! Now scale the particle velocities
82 CALL vel_rescale_baro(map_info, npt)
83
84 CALL timestop(handle)
85 END SUBROUTINE lnhc_barostat
86
87! **************************************************************************************************
88!> \brief ...
89!> \param nhc ...
90!> \param molecule_kind_set ...
91!> \param molecule_set ...
92!> \param particle_set ...
93!> \param local_molecules ...
94!> \param group ...
95!> \param shell_adiabatic ...
96!> \param shell_particle_set ...
97!> \param core_particle_set ...
98!> \param vel ...
99!> \param shell_vel ...
100!> \param core_vel ...
101!> \date 14-NOV-2000
102!> \par History
103!> none
104! **************************************************************************************************
105 SUBROUTINE lnhc_particles(nhc, molecule_kind_set, molecule_set, &
106 particle_set, local_molecules, group, shell_adiabatic, &
107 shell_particle_set, core_particle_set, vel, shell_vel, core_vel)
108
109 TYPE(lnhc_parameters_type), POINTER :: nhc
110 TYPE(molecule_kind_type), POINTER :: molecule_kind_set(:)
111 TYPE(molecule_type), POINTER :: molecule_set(:)
112 TYPE(particle_type), POINTER :: particle_set(:)
113 TYPE(distribution_1d_type), POINTER :: local_molecules
114 TYPE(mp_comm_type), INTENT(IN) :: group
115 LOGICAL, INTENT(IN), OPTIONAL :: shell_adiabatic
116 TYPE(particle_type), OPTIONAL, POINTER :: shell_particle_set(:), &
117 core_particle_set(:)
118 REAL(kind=dp), INTENT(INOUT), OPTIONAL :: vel(:, :), shell_vel(:, :), &
119 core_vel(:, :)
120
121 CHARACTER(len=*), PARAMETER :: routinen = 'lnhc_particles'
122
123 INTEGER :: handle
124 LOGICAL :: my_shell_adiabatic
125 TYPE(map_info_type), POINTER :: map_info
126
127 CALL timeset(routinen, handle)
128 my_shell_adiabatic = .false.
129 IF (PRESENT(shell_adiabatic)) my_shell_adiabatic = shell_adiabatic
130 map_info => nhc%map_info
131
132 ! Compute the kinetic energy for the region to thermostat
133 CALL ke_region_particles(map_info, particle_set, molecule_kind_set, &
134 local_molecules, molecule_set, group, vel)
135
136 ! Calculate forces on the Nose-Hoover Thermostat and apply chains
137 CALL do_nhc(nhc, map_info)
138
139 ! Now scale the particle velocities
140 CALL vel_rescale_particles(map_info, molecule_kind_set, molecule_set, particle_set, &
141 local_molecules, my_shell_adiabatic, shell_particle_set, core_particle_set, &
142 vel, shell_vel, core_vel)
143
144 CALL timestop(handle)
145 END SUBROUTINE lnhc_particles
146
147! **************************************************************************************************
148!> \brief ...
149!> \param nhc ...
150!> \param atomic_kind_set ...
151!> \param particle_set ...
152!> \param local_particles ...
153!> \param group ...
154!> \param shell_particle_set ...
155!> \param core_particle_set ...
156!> \param vel ...
157!> \param shell_vel ...
158!> \param core_vel ...
159!> \date 14-NOV-2000
160!> \par History
161!> none
162! **************************************************************************************************
163 SUBROUTINE lnhc_shells(nhc, atomic_kind_set, particle_set, local_particles, &
164 group, shell_particle_set, core_particle_set, vel, shell_vel, core_vel)
165
166 TYPE(lnhc_parameters_type), POINTER :: nhc
167 TYPE(atomic_kind_type), POINTER :: atomic_kind_set(:)
168 TYPE(particle_type), POINTER :: particle_set(:)
169 TYPE(distribution_1d_type), POINTER :: local_particles
170 TYPE(mp_comm_type), INTENT(IN) :: group
171 TYPE(particle_type), OPTIONAL, POINTER :: shell_particle_set(:), &
172 core_particle_set(:)
173 REAL(kind=dp), INTENT(INOUT), OPTIONAL :: vel(:, :), shell_vel(:, :), &
174 core_vel(:, :)
175
176 CHARACTER(len=*), PARAMETER :: routinen = 'lnhc_shells'
177
178 INTEGER :: handle
179 TYPE(map_info_type), POINTER :: map_info
180
181 CALL timeset(routinen, handle)
182 map_info => nhc%map_info
183
184 ! Compute the kinetic energy of the region to thermostat
185 CALL ke_region_shells(map_info, particle_set, atomic_kind_set, local_particles, &
186 group, core_particle_set, shell_particle_set, core_vel, shell_vel)
187
188 ! Calculate forces on the Nose-Hoover Thermostat and apply chains
189 CALL do_nhc(nhc, map_info)
190
191 ! Now scale the particle velocities
192 CALL vel_rescale_shells(map_info, atomic_kind_set, particle_set, local_particles, &
193 shell_particle_set, core_particle_set, shell_vel, core_vel, vel)
194
195 CALL timestop(handle)
196 END SUBROUTINE lnhc_shells
197
198! **************************************************************************************************
199!> \brief ...
200!> \param nhc ...
201!> \param map_info ...
202!> \author 10.2007 [tlaino] - Teodoro Laino - University of Zurich
203! **************************************************************************************************
204 SUBROUTINE do_nhc(nhc, map_info)
205 TYPE(lnhc_parameters_type), POINTER :: nhc
206 TYPE(map_info_type), POINTER :: map_info
207
208 INTEGER :: imap, n
209
210! Force on the first bead in every thermostat chain
211
212 DO n = 1, nhc%loc_num_nhc
213 imap = nhc%map_info%map_index(n)
214 IF (nhc%nvt(1, n)%nkt == 0.0_dp) cycle
215 nhc%nvt(1, n)%f = (map_info%s_kin(imap) - nhc%nvt(1, n)%nkt)/nhc%nvt(1, n)%mass
216 END DO
217
218 ! Perform multiple time stepping using Yoshida
219 CALL multiple_step_yoshida(nhc)
220
221 END SUBROUTINE do_nhc
222
223! **************************************************************************************************
224!> \brief ...
225!> \param atomic_kind_set ...
226!> \param local_particles ...
227!> \param particle_set ...
228!> \param com_vel ...
229!> \param shell_vel ...
230!> \param core_vel ...
231!> \date 14-NOV-2000
232!> \par History
233!> none
234! **************************************************************************************************
235 SUBROUTINE shell_scale_comv(atomic_kind_set, local_particles, particle_set, &
236 com_vel, shell_vel, core_vel)
237
238 TYPE(atomic_kind_type), POINTER :: atomic_kind_set(:)
239 TYPE(distribution_1d_type), POINTER :: local_particles
240 TYPE(particle_type), POINTER :: particle_set(:)
241 REAL(kind=dp), INTENT(IN) :: com_vel(:, :)
242 REAL(kind=dp), INTENT(INOUT) :: shell_vel(:, :), core_vel(:, :)
243
244 INTEGER :: iparticle, iparticle_kind, &
245 iparticle_local, nparticle_kind, &
246 nparticle_local, shell_index
247 LOGICAL :: is_shell
248 REAL(kind=dp) :: fac_massc, fac_masss, mass, vc(3), vs(3)
249 TYPE(atomic_kind_type), POINTER :: atomic_kind
250 TYPE(shell_kind_type), POINTER :: shell
251
252 nparticle_kind = SIZE(atomic_kind_set)
253
254 DO iparticle_kind = 1, nparticle_kind
255 atomic_kind => atomic_kind_set(iparticle_kind)
256 CALL get_atomic_kind(atomic_kind=atomic_kind, mass=mass, &
257 shell_active=is_shell, shell=shell)
258 IF (is_shell) THEN
259 fac_masss = shell%mass_shell/mass
260 fac_massc = shell%mass_core/mass
261 nparticle_local = local_particles%n_el(iparticle_kind)
262 DO iparticle_local = 1, nparticle_local
263 iparticle = local_particles%list(iparticle_kind)%array(iparticle_local)
264 shell_index = particle_set(iparticle)%shell_index
265 vs(1:3) = shell_vel(1:3, shell_index)
266 vc(1:3) = core_vel(1:3, shell_index)
267 shell_vel(1, shell_index) = com_vel(1, iparticle) + fac_massc*(vs(1) - vc(1))
268 shell_vel(2, shell_index) = com_vel(2, iparticle) + fac_massc*(vs(2) - vc(2))
269 shell_vel(3, shell_index) = com_vel(3, iparticle) + fac_massc*(vs(3) - vc(3))
270 core_vel(1, shell_index) = com_vel(1, iparticle) + fac_masss*(vc(1) - vs(1))
271 core_vel(2, shell_index) = com_vel(2, iparticle) + fac_masss*(vc(2) - vs(2))
272 core_vel(3, shell_index) = com_vel(3, iparticle) + fac_masss*(vc(3) - vs(3))
273 END DO
274 END IF ! is_shell
275 END DO ! iparticle_kind
276 END SUBROUTINE shell_scale_comv
277
278! **************************************************************************************************
279!> \brief ...
280!> \param nhc ...
281!> \date 14-NOV-2000
282!> \par History
283!> none
284! **************************************************************************************************
285 SUBROUTINE multiple_step_yoshida(nhc)
286
287 TYPE(lnhc_parameters_type), POINTER :: nhc
288
289 INTEGER :: imap, inc, inhc, iyosh, n, nx1, nx2
290 REAL(kind=dp) :: scale
291 TYPE(map_info_type), POINTER :: map_info
292
293 nx1 = SIZE(nhc%nvt, 1)
294 nx2 = SIZE(nhc%nvt, 2)
295 map_info => nhc%map_info
296 ! perform multiple time stepping using Yoshida
297 ncloop: DO inc = 1, nhc%nc
298 yosh: DO iyosh = 1, nhc%nyosh
299
300 ! update velocity on the last thermostat in the chain ! O1
301 nhc%nvt(nhc%nhc_len, :)%v = nhc%nvt(nhc%nhc_len, :)%v + &
302 nhc%nvt(nhc%nhc_len, :)%f*0.25_dp*nhc%dt_yosh(iyosh)*nhc%dt_fact
303
304 ! update velocity of other thermostats on chain (from nhc_len-1 to 1) ! O2
305 DO n = 1, nhc%loc_num_nhc
306 IF (nhc%nvt(1, n)%nkt == 0.0_dp) cycle
307 DO inhc = nhc%nhc_len - 1, 1, -1
308 scale = exp(-0.125_dp*nhc%nvt(inhc + 1, n)%v*nhc%dt_yosh(iyosh)*nhc%dt_fact)
309 nhc%nvt(inhc, n)%v = nhc%nvt(inhc, n)%v*scale ! scale
310 nhc%nvt(inhc, n)%v = nhc%nvt(inhc, n)%v + &
311 nhc%nvt(inhc, n)%f*0.25_dp*nhc%dt_yosh(iyosh)*nhc%dt_fact ! shift
312 nhc%nvt(inhc, n)%v = nhc%nvt(inhc, n)%v*scale ! scale
313 END DO
314 END DO
315
316 ! the core of the operator ----- START------
317 ! update nhc positions
318 nhc%nvt(:, :)%eta = nhc%nvt(:, :)%eta + &
319 0.5_dp*nhc%nvt(:, :)%v*nhc%dt_yosh(iyosh)*nhc%dt_fact
320
321 ! now accumulate the scale factor for particle velocities
322 DO n = 1, nhc%loc_num_nhc
323 imap = nhc%map_info%map_index(n)
324 IF (nhc%nvt(1, n)%nkt == 0.0_dp) cycle
325 map_info%v_scale(imap) = map_info%v_scale(imap)*exp(-0.5_dp*nhc%dt_yosh(iyosh)*nhc%dt_fact*nhc%nvt(1, n)%v)
326 END DO
327 ! the core of the operator ------ END ------
328
329 ! update the force on first thermostat again (since particle velocities changed)
330 DO n = 1, nhc%loc_num_nhc
331 imap = nhc%map_info%map_index(n)
332 IF (nhc%nvt(1, n)%nkt == 0.0_dp) cycle
333 nhc%nvt(1, n)%f = (map_info%s_kin(imap)*map_info%v_scale(imap)* &
334 map_info%v_scale(imap) - nhc%nvt(1, n)%nkt)/nhc%nvt(1, n)%mass
335 END DO
336
337 ! update velocity of other thermostats on chain (from 1 to nhc_len-1) ! O2
338 DO inhc = 1, nhc%nhc_len - 1
339 DO n = 1, nhc%loc_num_nhc
340 IF (nhc%nvt(1, n)%nkt == 0.0_dp) cycle
341 scale = exp(-0.125_dp*nhc%nvt(inhc + 1, n)%v*nhc%dt_yosh(iyosh)*nhc%dt_fact)
342 nhc%nvt(inhc, n)%v = nhc%nvt(inhc, n)%v*scale ! scale
343 nhc%nvt(inhc, n)%v = nhc%nvt(inhc, n)%v + &
344 nhc%nvt(inhc, n)%f*0.25_dp*nhc%dt_yosh(iyosh)*nhc%dt_fact ! shift
345 nhc%nvt(inhc, n)%v = nhc%nvt(inhc, n)%v*scale ! scale
346 END DO
347
348 ! updating the forces on all the thermostats
349 DO n = 1, nhc%loc_num_nhc
350 IF (nhc%nvt(1, n)%nkt == 0.0_dp) cycle
351 nhc%nvt(inhc + 1, n)%f = (nhc%nvt(inhc, n)%mass*nhc%nvt(inhc, n)%v &
352 *nhc%nvt(inhc, n)%v - nhc%nvt(inhc + 1, n)%nkt)/nhc%nvt(inhc + 1, n)%mass
353 END DO
354 END DO
355 ! update velocity on last thermostat ! O1
356 nhc%nvt(nhc%nhc_len, :)%v = nhc%nvt(nhc%nhc_len, :)%v + &
357 nhc%nvt(nhc%nhc_len, :)%f*0.25_dp*nhc%dt_yosh(iyosh)*nhc%dt_fact
358 END DO yosh
359 END DO ncloop
360 END SUBROUTINE multiple_step_yoshida
361
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
subroutine, public lnhc_barostat(nhc, npt, group)
...
subroutine, public shell_scale_comv(atomic_kind_set, local_particles, particle_set, com_vel, shell_vel, core_vel)
...
subroutine, public lnhc_shells(nhc, atomic_kind_set, particle_set, local_particles, group, shell_particle_set, core_particle_set, vel, shell_vel, core_vel)
...
subroutine, public lnhc_particles(nhc, molecule_kind_set, molecule_set, particle_set, local_molecules, group, shell_adiabatic, shell_particle_set, core_particle_set, vel, shell_vel, core_vel)
...
Lumps all possible extended system variables into one type for easy access and passing.
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 molecule kind structure types and the corresponding functionality.
Define the data structure for the molecule information.
Define the data structure for the particle information.
Utilities for thermostats.
subroutine, public vel_rescale_shells(map_info, atomic_kind_set, particle_set, local_particles, shell_particle_set, core_particle_set, shell_vel, core_vel, vel)
...
subroutine, public vel_rescale_particles(map_info, molecule_kind_set, molecule_set, particle_set, local_molecules, shell_adiabatic, shell_particle_set, core_particle_set, vel, shell_vel, core_vel)
...
subroutine, public ke_region_shells(map_info, particle_set, atomic_kind_set, local_particles, group, core_particle_set, shell_particle_set, core_vel, shell_vel)
...
subroutine, public ke_region_baro(map_info, npt, group)
...
subroutine, public vel_rescale_baro(map_info, npt)
...
subroutine, public ke_region_particles(map_info, particle_set, molecule_kind_set, local_molecules, molecule_set, group, vel)
...
Provides all information about an atomic kind.
structure to store local (to a processor) ordered lists of integers.