(git:374b731)
Loading...
Searching...
No Matches
dimer_methods.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 Contains types used for a Dimer Method calculations
10!> \par History
11!> -Luca Bellucci 11.2017 - CNR-NANO, Pisa
12!> add K-DIMER from doi:10.1063/1.4898664
13!> \author Luca Bellucci and Teodoro Laino - created [tlaino] - 01.2008
14! **************************************************************************************************
16 USE bibliography, ONLY: henkelman2014,&
17 cite_reference
24 USE dimer_types, ONLY: dimer_env_type,&
26 USE dimer_utils, ONLY: get_theta
29 USE geo_opt, ONLY: cp_rot_opt
30 USE gopt_f_types, ONLY: gopt_f_type
36 USE kinds, ONLY: dp
37 USE motion_utils, ONLY: rot_ana,&
40#include "../base/base_uses.f90"
41
42 IMPLICIT NONE
43 PRIVATE
44
45 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .false.
46 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'dimer_methods'
47
48 PUBLIC :: cp_eval_at_ts
49
50CONTAINS
51
52! **************************************************************************************************
53!> \brief Computes the dimer energy/gradients (including the rotation of the dimer)
54!> \param gopt_env ...
55!> \param x ...
56!> \param f ...
57!> \param gradient ...
58!> \param calc_force ...
59!> \date 01.2008
60!> \par History
61!> none
62!> \author Luca Bellucci and Teodoro Laino - created [tlaino]
63! **************************************************************************************************
64 RECURSIVE SUBROUTINE cp_eval_at_ts(gopt_env, x, f, gradient, calc_force)
65 TYPE(gopt_f_type), POINTER :: gopt_env
66 REAL(kind=dp), DIMENSION(:), POINTER :: x
67 REAL(kind=dp), INTENT(OUT) :: f
68 REAL(kind=dp), DIMENSION(:), POINTER :: gradient
69 LOGICAL, INTENT(IN) :: calc_force
70
71 CHARACTER(len=*), PARAMETER :: routinen = 'cp_eval_at_ts'
72
73 INTEGER :: handle, iw
74 LOGICAL :: eval_analytical
75 REAL(kind=dp) :: angle1, angle2, f1, gm1, gm2, norm, swf
76 TYPE(cp_logger_type), POINTER :: logger
77 TYPE(dimer_env_type), POINTER :: dimer_env
78 TYPE(section_vals_type), POINTER :: print_section
79
80 NULLIFY (dimer_env, logger, print_section)
81 CALL timeset(routinen, handle)
82 logger => cp_get_default_logger()
83
84 cpassert(ASSOCIATED(gopt_env))
85 dimer_env => gopt_env%dimer_env
86 cpassert(ASSOCIATED(dimer_env))
87 iw = cp_print_key_unit_nr(logger, gopt_env%geo_section, "PRINT%PROGRAM_RUN_INFO", extension=".log")
88 ! Possibly rotate Dimer or just compute Gradients of point 0 for Translation
89 IF (gopt_env%dimer_rotation) THEN
90 IF (debug_this_module .AND. (iw > 0)) THEN
91 WRITE (iw, '(A)') "NVEC:"
92 WRITE (iw, '(3F15.9)') dimer_env%nvec
93 END IF
94 SELECT CASE (dimer_env%rot%rotation_step)
96 eval_analytical = .true.
97 IF ((dimer_env%rot%rotation_step == do_third_rotation_step) .AND. (dimer_env%rot%interpolate_gradient)) THEN
98 eval_analytical = .false.
99 END IF
100 IF (eval_analytical) THEN
101 ! Compute energy, gradients and rotation vector for R1
102 CALL cp_eval_at_ts_low(gopt_env, x, 1, dimer_env, calc_force, f1, dimer_env%rot%g1)
103 ELSE
104 angle1 = dimer_env%rot%angle1
105 angle2 = dimer_env%rot%angle2
106 dimer_env%rot%g1 = sin(angle1 - angle2)/sin(angle1)*dimer_env%rot%g1 + &
107 sin(angle2)/sin(angle1)*dimer_env%rot%g1p + &
108 (1.0_dp - cos(angle2) - sin(angle2)*tan(angle1/2.0_dp))*dimer_env%rot%g0
109 END IF
110
111 ! Determine the theta vector (i.e. the search direction for line minimization)
112 gradient = -2.0_dp*(dimer_env%rot%g1 - dimer_env%rot%g0)
113 IF (debug_this_module .AND. (iw > 0)) THEN
114 WRITE (iw, '(A)') "G1 vector:"
115 WRITE (iw, '(3F15.9)') dimer_env%rot%g1
116 WRITE (iw, '(A)') "-2*(G1-G0) vector:"
117 WRITE (iw, '(3F15.9)') gradient
118 END IF
119 CALL get_theta(gradient, dimer_env, norm)
120 f = norm
121 dimer_env%cg_rot%norm_theta_old = dimer_env%cg_rot%norm_theta
122 dimer_env%cg_rot%norm_theta = norm
123
124 IF (debug_this_module .AND. (iw > 0)) THEN
125 WRITE (iw, '(A,F20.10)') "Rotational Force step (1,3): module:", norm
126 WRITE (iw, '(3F15.9)') gradient
127 END IF
128
129 ! Compute curvature and derivative of the curvature w.r.t. the rotational angle
130 dimer_env%rot%curvature = dot_product(dimer_env%rot%g1 - dimer_env%rot%g0, dimer_env%nvec)/dimer_env%dr
131 dimer_env%rot%dCdp = 2.0_dp*dot_product(dimer_env%rot%g1 - dimer_env%rot%g0, gradient)/dimer_env%dr
132
133 dimer_env%rot%rotation_step = do_second_rotation_step
134 gradient = -gradient
136 ! Compute energy, gradients and rotation vector for R1
137 CALL cp_eval_at_ts_low(gopt_env, x, 1, dimer_env, calc_force, f1, dimer_env%rot%g1p)
138 dimer_env%rot%curvature = dot_product(dimer_env%rot%g1p - dimer_env%rot%g0, dimer_env%nvec)/dimer_env%dr
139 dimer_env%rot%rotation_step = do_third_rotation_step
140
141 ! Determine the theta vector (i.e. the search direction for line minimization)
142 ! This is never used for getting a new theta but is consistent in order to
143 ! give back the right value of f
144 gradient = -2.0_dp*(dimer_env%rot%g1p - dimer_env%rot%g0)
145 CALL get_theta(gradient, dimer_env, norm)
146 f = norm
147
148 IF (debug_this_module .AND. (iw > 0)) THEN
149 WRITE (iw, '(A)') "Rotational Force step (1,3):"
150 WRITE (iw, '(3F15.9)') gradient
151 END IF
152 END SELECT
153 ELSE
154 ! Compute energy, gradients and rotation vector for R0
155 CALL cp_eval_at_ts_low(gopt_env, x, 0, dimer_env, calc_force, f, dimer_env%rot%g0)
156
157 ! The dimer is rotated only when we are out of the translation line search
158 IF (.NOT. gopt_env%do_line_search) THEN
159 IF (debug_this_module .AND. (iw > 0)) THEN
160 WRITE (iw, '(A)') "Entering the rotation module"
161 WRITE (iw, '(A)') "G0 vector:"
162 WRITE (iw, '(3F15.9)') dimer_env%rot%g0
163 END IF
164 CALL cp_rot_opt(gopt_env%gopt_dimer_env, x, gopt_env%gopt_dimer_param, &
165 gopt_env%gopt_dimer_env%geo_section)
166 dimer_env%rot%rotation_step = do_first_rotation_step
167 END IF
168
169 print_section => section_vals_get_subs_vals(gopt_env%gopt_dimer_env%geo_section, "PRINT")
170
171 ! Correcting gradients for Translation K-DIMER or STANDARD
172 IF (dimer_env%kdimer) THEN
173 CALL cite_reference(henkelman2014)
174 ! K-DIMER
175 IF (iw > 0) THEN
176 WRITE (iw, '(T2,A)') "DIMER| Correcting gradients for Translation with K-DIMER method"
177 END IF
178 swf = 1.0_dp + exp(dimer_env%beta*dimer_env%rot%curvature)
179 gm2 = 1.0_dp - (1.0_dp/swf)
180 gm1 = (2.0_dp/swf) - 1.0_dp
181 gradient = gm2*(dimer_env%rot%g0 - 2.0_dp*dot_product(dimer_env%rot%g0, dimer_env%nvec)*dimer_env%nvec) &
182 - gm1*(dot_product(dimer_env%rot%g0, dimer_env%nvec)*dimer_env%nvec)
183 CALL remove_rot_transl_component(gopt_env, gradient, print_section)
184 IF (debug_this_module .AND. (iw > 0)) WRITE (iw, *) "K-DIMER", dimer_env%beta, dimer_env%rot%curvature, &
185 dimer_env%rot%dCdp, gm1, gm2, swf
186 ELSE
187 IF (iw > 0) THEN
188 WRITE (iw, '(T2,A)') "DIMER| Correcting gradients for Translation with standard method"
189 END IF
190 IF (dimer_env%rot%curvature > 0) THEN
191 gradient = -dot_product(dimer_env%rot%g0, dimer_env%nvec)*dimer_env%nvec
192 CALL remove_rot_transl_component(gopt_env, gradient, print_section)
193 ELSE
194 gradient = dimer_env%rot%g0 - 2.0_dp*dot_product(dimer_env%rot%g0, dimer_env%nvec)*dimer_env%nvec
195 CALL remove_rot_transl_component(gopt_env, gradient, print_section)
196 END IF
197 END IF
198 IF (debug_this_module .AND. (iw > 0)) THEN
199 WRITE (iw, *) "final gradient:", gradient
200 WRITE (iw, '(A,F20.10)') "norm gradient:", sqrt(dot_product(gradient, gradient))
201 END IF
202 IF (.NOT. gopt_env%do_line_search) THEN
203 f = sqrt(dot_product(gradient, gradient))
204 ELSE
205 f = -dot_product(gradient, dimer_env%tsl%tls_vec)
206 END IF
207 END IF
208 CALL cp_print_key_finished_output(iw, logger, gopt_env%geo_section, "PRINT%PROGRAM_RUN_INFO")
209 CALL timestop(handle)
210 END SUBROUTINE cp_eval_at_ts
211
212! **************************************************************************************************
213!> \brief This function removes translational forces after project of the gradient
214!> \param gopt_env ...
215!> \param gradient ...
216!> \param print_section ...
217!> \par History
218!> 2016/03/02 [LTong] added fixed atom constraint for gradient
219!> \author Luca Bellucci and Teodoro Laino - created [tlaino] - 01.2008
220! **************************************************************************************************
221 SUBROUTINE remove_rot_transl_component(gopt_env, gradient, print_section)
222 TYPE(gopt_f_type), POINTER :: gopt_env
223 REAL(kind=dp), DIMENSION(:) :: gradient
224 TYPE(section_vals_type), POINTER :: print_section
225
226 CHARACTER(len=*), PARAMETER :: routinen = 'remove_rot_transl_component'
227
228 INTEGER :: dof, handle, i, j, natoms
229 REAL(kind=dp) :: norm, norm_gradient_old
230 REAL(kind=dp), DIMENSION(:, :), POINTER :: d, mat
231 TYPE(cp_subsys_type), POINTER :: subsys
232 TYPE(particle_list_type), POINTER :: particles
233
234 CALL timeset(routinen, handle)
235 NULLIFY (mat)
236 CALL force_env_get(gopt_env%force_env, subsys=subsys)
237 CALL cp_subsys_get(subsys, particles=particles)
238
239 natoms = particles%n_els
240 norm_gradient_old = sqrt(dot_product(gradient, gradient))
241 IF (norm_gradient_old > 0.0_dp) THEN
242 IF (natoms > 1) THEN
243 CALL rot_ana(particles%els, mat, dof, print_section, keep_rotations=.false., &
244 mass_weighted=.false., natoms=natoms)
245
246 ! Orthogonalize gradient with respect to the full set of Roto-Trasl vectors
247 ALLOCATE (d(3*natoms, dof))
248 ! Check First orthogonality in the first element of the basis set
249 DO i = 1, dof
250 d(:, i) = mat(:, i)
251 DO j = i + 1, dof
252 norm = dot_product(mat(:, i), mat(:, j))
253 cpassert(abs(norm) < thrs_motion)
254 END DO
255 END DO
256 DO i = 1, dof
257 norm = dot_product(gradient, d(:, i))
258 gradient = gradient - norm*d(:, i)
259 END DO
260 DEALLOCATE (d)
261 DEALLOCATE (mat)
262 END IF
263 END IF
264 ! apply constraint
265 CALL dimer_fixed_atom_control(gradient, subsys)
266 CALL timestop(handle)
267 END SUBROUTINE remove_rot_transl_component
268
269! **************************************************************************************************
270!> \brief ...
271!> \param gopt_env ...
272!> \param x ...
273!> \param dimer_index ...
274!> \param dimer_env ...
275!> \param calc_force ...
276!> \param f ...
277!> \param gradient ...
278!> \par History
279!> none
280!> \author Luca Bellucci and Teodoro Laino - created [tlaino] - 01.2008
281! **************************************************************************************************
282 SUBROUTINE cp_eval_at_ts_low(gopt_env, x, dimer_index, dimer_env, calc_force, &
283 f, gradient)
284 TYPE(gopt_f_type), POINTER :: gopt_env
285 REAL(kind=dp), DIMENSION(:), POINTER :: x
286 INTEGER, INTENT(IN) :: dimer_index
287 TYPE(dimer_env_type), POINTER :: dimer_env
288 LOGICAL, INTENT(IN) :: calc_force
289 REAL(kind=dp), INTENT(OUT), OPTIONAL :: f
290 REAL(kind=dp), DIMENSION(:), OPTIONAL :: gradient
291
292 CHARACTER(len=*), PARAMETER :: routinen = 'cp_eval_at_ts_low'
293
294 INTEGER :: handle, idg, idir, ip
295 TYPE(cp_subsys_type), POINTER :: subsys
296 TYPE(particle_list_type), POINTER :: particles
297
298 CALL timeset(routinen, handle)
299 idg = 0
300 CALL force_env_get(gopt_env%force_env, subsys=subsys)
301 CALL cp_subsys_get(subsys, particles=particles)
302 DO ip = 1, particles%n_els
303 DO idir = 1, 3
304 idg = idg + 1
305 particles%els(ip)%r(idir) = x(idg) + real(dimer_index, kind=dp)*dimer_env%nvec(idg)*dimer_env%dr
306 END DO
307 END DO
308
309 ! Compute energy and forces
310 CALL force_env_calc_energy_force(gopt_env%force_env, calc_force=calc_force)
311
312 ! Possibly take the potential energy
313 IF (PRESENT(f)) THEN
314 CALL force_env_get(gopt_env%force_env, potential_energy=f)
315 END IF
316
317 ! Possibly take the gradients
318 IF (PRESENT(gradient)) THEN
319 idg = 0
320 CALL cp_subsys_get(subsys, particles=particles)
321 DO ip = 1, particles%n_els
322 DO idir = 1, 3
323 idg = idg + 1
324 cpassert(SIZE(gradient) >= idg)
325 gradient(idg) = -particles%els(ip)%f(idir)
326 END DO
327 END DO
328 END IF
329 CALL timestop(handle)
330 END SUBROUTINE cp_eval_at_ts_low
331
332END MODULE dimer_methods
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public henkelman2014
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_get(subsys, ref_count, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell)
returns information about various attributes of the given subsys
Contains types used for a Dimer Method calculations.
recursive subroutine, public cp_eval_at_ts(gopt_env, x, f, gradient, calc_force)
Computes the dimer energy/gradients (including the rotation of the dimer)
Contains types used for a Dimer Method calculations.
Definition dimer_types.F:14
subroutine, public dimer_fixed_atom_control(vec, subsys)
Set parts of a given array vec to zero according to fixed atom constraints. When atoms are (partially...
Contains utilities for a Dimer Method calculations.
Definition dimer_utils.F:14
subroutine, public get_theta(gradient, dimer_env, norm)
This function orthonormalize the vector for the rotational search.
Interface for the force calculations.
recursive subroutine, public force_env_calc_energy_force(force_env, calc_force, consistent_energies, skip_external_control, eval_energy_forces, require_consistent_energy_force, linres, calc_stress_tensor)
Interface routine for force and energy calculations.
Interface for the force calculations.
recursive subroutine, public force_env_get(force_env, in_use, fist_env, qs_env, meta_env, fp_env, subsys, para_env, potential_energy, additional_potential, kinetic_energy, harmonic_shell, kinetic_shell, cell, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, globenv, input, force_env_section, method_name_id, root_section, mixed_env, nnp_env, embed_env)
returns various attributes about the force environment
performs geometry optimization
Definition geo_opt.F:13
subroutine, public cp_rot_opt(gopt_env, x0, gopt_param, geo_section)
Main driver to perform rotation optimization for Dimer.
Definition geo_opt.F:115
contains a functional that calculates the energy and its derivatives for the geometry optimizer
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_second_rotation_step
integer, parameter, public do_first_rotation_step
integer, parameter, public do_third_rotation_step
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
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Output Utilities for MOTION_SECTION.
real(kind=dp), parameter, public thrs_motion
subroutine, public rot_ana(particles, mat, dof, print_section, keep_rotations, mass_weighted, natoms, rot_dof, inertia)
Performs an analysis of the principal inertia axis Getting back the generators of the translating and...
represent a simple array based list of the given type
type of a logger, at the moment it contains just a print level starting at which level it should be l...
represents a system: atoms, molecules, their pos,vel,...
Defines the environment for a Dimer Method calculation.
Definition dimer_types.F:94
calculates the potential energy of a system, and its derivatives