(git:374b731)
Loading...
Searching...
No Matches
neb_md_utils.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!> \brief Module with utility to perform MD Nudged Elastic Band Calculation
10!> \note
11!> Numerical accuracy for parallel runs:
12!> Each replica starts the SCF run from the one optimized
13!> in a previous run. It may happen then energies and derivatives
14!> of a serial run and a parallel run could be slightly different
15!> 'cause of a different starting density matrix.
16!> Exact results are obtained using:
17!> EXTRAPOLATION USE_GUESS in QS section (Teo 09.2006)
18!> \author Teodoro Laino 10.2006
19! **************************************************************************************************
23 USE input_constants, ONLY: band_md_opt,&
29 USE kinds, ONLY: dp
30 USE neb_types, ONLY: neb_type,&
35 USE physcon, ONLY: kelvin,&
37#include "../base/base_uses.f90"
38
39 IMPLICIT NONE
40 PRIVATE
41 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'neb_md_utils'
42
43 PUBLIC :: neb_initialize_velocity, &
47
48CONTAINS
49
50! **************************************************************************************************
51!> \brief Initialize velocities of replica in an MD optimized algorithm within
52!> NEB
53!> \param vels ...
54!> \param neb_section ...
55!> \param particle_set ...
56!> \param i_rep ...
57!> \param iw ...
58!> \param globenv ...
59!> \param neb_env ...
60!> \par History
61!> 25.11.2010 Consider core-shell model (MK)
62!> \author Teodoro Laino 09.2006
63! **************************************************************************************************
64 SUBROUTINE neb_initialize_velocity(vels, neb_section, particle_set, i_rep, iw, &
65 globenv, neb_env)
66
67 REAL(kind=dp), DIMENSION(:, :), POINTER :: vels
68 TYPE(section_vals_type), POINTER :: neb_section
69 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
70 INTEGER, INTENT(IN) :: i_rep, iw
71 TYPE(global_environment_type), POINTER :: globenv
72 TYPE(neb_type), POINTER :: neb_env
73
74 INTEGER :: iatom, ivar, natom, nparticle, nvar
75 REAL(kind=dp) :: akin, mass, mass_tot, sc, temp, &
76 temp_ext, tmp_r1
77 REAL(kind=dp), DIMENSION(3) :: v, vcom
78 TYPE(section_vals_type), POINTER :: md_section
79
80 IF (neb_env%opt_type == band_md_opt) THEN
81 md_section => section_vals_get_subs_vals(neb_section, "OPTIMIZE_BAND%MD")
82 CALL section_vals_val_get(md_section, "TEMPERATURE", r_val=temp_ext)
83 ! Initialize velocity according to external temperature
84 nparticle = SIZE(vels, 1)
85 natom = SIZE(particle_set)
86 mass_tot = 0.0_dp
87 vcom(1:3) = 0.0_dp
88 CALL globenv%gaussian_rng_stream%fill(vels(:, i_rep))
89 ! Check always if BAND is working in Cartesian or in internal coordinates
90 ! If working in cartesian coordinates let's get rid of the COM
91 ! Compute also the total mass (both in Cartesian and internal)
92 IF (neb_env%use_colvar) THEN
93 nvar = nparticle
94 mass_tot = real(nvar, kind=dp)*massunit
95 ELSE
96 DO iatom = 1, natom
97 mass = particle_set(iatom)%atomic_kind%mass
98 mass_tot = mass_tot + mass
99 v(1:3) = get_particle_pos_or_vel(iatom, particle_set, vels(:, i_rep))
100 vcom(1:3) = vcom(1:3) + mass*v(1:3)
101 END DO
102 vcom(1:3) = vcom(1:3)/mass_tot
103 END IF
104 ! Compute kinetic energy and temperature
105 akin = 0.0_dp
106 IF (neb_env%use_colvar) THEN
107 DO ivar = 1, nvar
108 akin = akin + 0.5_dp*massunit*vels(ivar, i_rep)*vels(ivar, i_rep)
109 END DO
110 ELSE
111 DO iatom = 1, natom
112 mass = particle_set(iatom)%atomic_kind%mass
113 v(1:3) = -vcom(1:3)
114 CALL update_particle_pos_or_vel(iatom, particle_set, v(1:3), vels(:, i_rep))
115 akin = akin + 0.5_dp*mass*dot_product(v(1:3), v(1:3))
116 END DO
117 nvar = 3*natom
118 END IF
119 temp = 2.0_dp*akin/real(nvar, kind=dp)
120 ! Scale velocities to get the correct initial temperature and
121 sc = sqrt(temp_ext/temp)
122 vels(:, i_rep) = vels(:, i_rep)*sc
123 ! Re-compute kinetic energya and temperature and velocity of COM
124 akin = 0.0_dp
125 vcom = 0.0_dp
126 IF (neb_env%use_colvar) THEN
127 DO ivar = 1, nvar
128 akin = akin + 0.5_dp*massunit*vels(ivar, i_rep)*vels(ivar, i_rep)
129 END DO
130 ELSE
131 DO iatom = 1, natom
132 mass = particle_set(iatom)%atomic_kind%mass
133 v(1:3) = get_particle_pos_or_vel(iatom, particle_set, vels(:, i_rep))
134 vcom(1:3) = vcom(1:3) + mass*v(1:3)
135 akin = akin + 0.5_dp*mass*dot_product(v(1:3), v(1:3))
136 END DO
137 END IF
138 vcom(1:3) = vcom(1:3)/mass_tot
139 ! Dump information
140 IF (iw > 0) THEN
141 temp = 2.0_dp*akin/real(nvar, kind=dp)
142 tmp_r1 = cp_unit_from_cp2k(temp, "K")
143 WRITE (iw, '(A,T61,F18.2,A2)') &
144 ' NEB| Initial Temperature ', tmp_r1, " K"
145 WRITE (iw, '(A,T61,F20.12)') &
146 ' NEB| Centre of mass velocity in direction x:', vcom(1), &
147 ' NEB| Centre of mass velocity in direction y:', vcom(2), &
148 ' NEB| Centre of mass velocity in direction z:', vcom(3)
149 WRITE (iw, '(T2,"NEB|",75("*"))')
150 END IF
151 ELSE
152 vels(:, i_rep) = 0.0_dp
153 END IF
154
155 END SUBROUTINE neb_initialize_velocity
156
157! **************************************************************************************************
158!> \brief Control on velocities - I part
159!> \param vels ...
160!> \param particle_set ...
161!> \param tc_section ...
162!> \param vc_section ...
163!> \param output_unit ...
164!> \param istep ...
165!> \author Teodoro Laino 09.2006
166! **************************************************************************************************
167 SUBROUTINE control_vels_a(vels, particle_set, tc_section, vc_section, &
168 output_unit, istep)
169 TYPE(neb_var_type), POINTER :: vels
170 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
171 TYPE(section_vals_type), POINTER :: tc_section, vc_section
172 INTEGER, INTENT(IN) :: output_unit, istep
173
174 INTEGER :: i, temp_tol_steps
175 LOGICAL :: explicit
176 REAL(kind=dp) :: ext_temp, f_annealing, scale, temp_tol, &
177 temploc, tmp_r1, tmp_r2
178 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: temperatures
179
180! Temperature control
181
182 CALL section_vals_get(tc_section, explicit=explicit)
183 IF (explicit) THEN
184 CALL section_vals_val_get(tc_section, "TEMP_TOL_STEPS", i_val=temp_tol_steps)
185 CALL section_vals_val_get(tc_section, "TEMPERATURE", r_val=ext_temp)
186 CALL section_vals_val_get(tc_section, "TEMP_TOL", r_val=temp_tol)
187 ALLOCATE (temperatures(SIZE(vels%wrk, 2)))
188 ! Computes temperatures
189 CALL get_temperatures(vels, particle_set, temperatures, factor=1.0_dp)
190 ! Possibly rescale
191 IF (istep <= temp_tol_steps) THEN
192 DO i = 2, SIZE(vels%wrk, 2) - 1
193 temploc = temperatures(i)
194 IF (abs(temploc - ext_temp) > temp_tol) THEN
195 IF (output_unit > 0) THEN
196 tmp_r1 = cp_unit_from_cp2k(temploc, "K")
197 tmp_r2 = cp_unit_from_cp2k(ext_temp, "K")
198 WRITE (output_unit, '(T2,"NEB| Replica Nr.",I5,'// &
199 '" - Velocity rescaled from: ",F12.6," to: ",F12.6,".")') &
200 i, tmp_r1, tmp_r2
201
202 END IF
203 scale = sqrt(ext_temp/temploc)
204 vels%wrk(:, i) = scale*vels%wrk(:, i)
205 END IF
206 END DO
207 END IF
208 DEALLOCATE (temperatures)
209 END IF
210 ! Annealing
211 CALL section_vals_get(vc_section, explicit=explicit)
212 IF (explicit) THEN
213 CALL section_vals_val_get(vc_section, "ANNEALING", r_val=f_annealing)
214 DO i = 2, SIZE(vels%wrk, 2) - 1
215 vels%wrk(:, i) = f_annealing*vels%wrk(:, i)
216 END DO
217 END IF
218 END SUBROUTINE control_vels_a
219
220! **************************************************************************************************
221!> \brief Control on velocities - II part
222!> \param vels ...
223!> \param forces ...
224!> \param vc_section ...
225!> \author Teodoro Laino 09.2006
226! **************************************************************************************************
227 SUBROUTINE control_vels_b(vels, forces, vc_section)
228 TYPE(neb_var_type), POINTER :: vels, forces
229 TYPE(section_vals_type), POINTER :: vc_section
230
231 INTEGER :: i
232 LOGICAL :: explicit, lval
233 REAL(kind=dp) :: factor, norm
234
235! Check the sign of V.dot.F
236
237 CALL section_vals_get(vc_section, explicit=explicit)
238 IF (explicit) THEN
239 CALL section_vals_val_get(vc_section, "PROJ_VELOCITY_VERLET", l_val=lval)
240 IF (lval) THEN
241 DO i = 2, SIZE(vels%wrk, 2) - 1
242 norm = dot_product(forces%wrk(:, i), forces%wrk(:, i))
243 factor = dot_product(vels%wrk(:, i), forces%wrk(:, i))
244 IF (factor > 0 .AND. (norm >= epsilon(0.0_dp))) THEN
245 vels%wrk(:, i) = factor/norm*forces%wrk(:, i)
246 ELSE
247 vels%wrk(:, i) = 0.0_dp
248 END IF
249 END DO
250 END IF
251 CALL section_vals_val_get(vc_section, "SD_LIKE", l_val=lval)
252 IF (lval) THEN
253 DO i = 2, SIZE(vels%wrk, 2) - 1
254 vels%wrk(:, i) = 0.0_dp
255 END DO
256 END IF
257 END IF
258 END SUBROUTINE control_vels_b
259
260! **************************************************************************************************
261!> \brief Computes temperatures
262!> \param vels ...
263!> \param particle_set ...
264!> \param temperatures ...
265!> \param ekin ...
266!> \param factor ...
267!> \par History
268!> 24.11.2010 rewritten to include core-shell model (MK)
269!> \author Teodoro Laino 09.2006
270! **************************************************************************************************
271 SUBROUTINE get_temperatures(vels, particle_set, temperatures, ekin, factor)
272
273 TYPE(neb_var_type), POINTER :: vels
274 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
275 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: temperatures
276 REAL(kind=dp), DIMENSION(:), INTENT(OUT), OPTIONAL :: ekin
277 REAL(kind=dp), INTENT(IN), OPTIONAL :: factor
278
279 INTEGER :: i_rep, iatom, ivar, n_rep, natom, nvar
280 REAL(kind=dp) :: akin, mass, myfactor, temploc
281 REAL(kind=dp), DIMENSION(3) :: v
282
283 myfactor = kelvin
284 IF (PRESENT(factor)) myfactor = factor
285 IF (PRESENT(ekin)) ekin(:) = 0.0_dp
286 temperatures(:) = 0.0_dp
287 nvar = SIZE(vels%wrk, 1)
288 n_rep = SIZE(vels%wrk, 2)
289 natom = SIZE(particle_set)
290 DO i_rep = 2, n_rep - 1
291 akin = 0.0_dp
292 IF (vels%in_use == do_band_collective) THEN
293 DO ivar = 1, nvar
294 akin = akin + 0.5_dp*massunit*vels%wrk(ivar, i_rep)*vels%wrk(ivar, i_rep)
295 END DO
296 ELSE
297 DO iatom = 1, natom
298 mass = particle_set(iatom)%atomic_kind%mass
299 v(1:3) = get_particle_pos_or_vel(iatom, particle_set, vels%wrk(:, i_rep))
300 akin = akin + 0.5_dp*mass*dot_product(v(1:3), v(1:3))
301 END DO
302 nvar = 3*natom
303 END IF
304 IF (PRESENT(ekin)) ekin(i_rep) = akin
305 temploc = 2.0_dp*akin/real(nvar, kind=dp)
306 temperatures(i_rep) = temploc*myfactor
307 END DO
308
309 END SUBROUTINE get_temperatures
310
311END MODULE neb_md_utils
unit conversion facility
Definition cp_units.F:30
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Definition cp_units.F:1179
Define type storing the global information of a run. Keep the amount of stored data small....
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public band_md_opt
integer, parameter, public do_band_collective
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Module with utility to perform MD Nudged Elastic Band Calculation.
subroutine, public neb_initialize_velocity(vels, neb_section, particle_set, i_rep, iw, globenv, neb_env)
Initialize velocities of replica in an MD optimized algorithm within NEB.
subroutine, public get_temperatures(vels, particle_set, temperatures, ekin, factor)
Computes temperatures.
subroutine, public control_vels_a(vels, particle_set, tc_section, vc_section, output_unit, istep)
Control on velocities - I part.
subroutine, public control_vels_b(vels, forces, vc_section)
Control on velocities - II part.
Typo for Nudged Elastic Band Calculation.
Definition neb_types.F:20
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...
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...
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public kelvin
Definition physcon.F:165
real(kind=dp), parameter, public massunit
Definition physcon.F:141
contains the initially parsed file and the initial parallel environment