40#include "../base/base_uses.f90"
45 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .false.
46 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dimer_methods'
64 RECURSIVE SUBROUTINE cp_eval_at_ts(gopt_env, x, f, gradient, calc_force)
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
71 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_eval_at_ts'
74 LOGICAL :: eval_analytical
75 REAL(kind=
dp) :: angle1, angle2, f1, gm1, gm2, norm, swf
80 NULLIFY (dimer_env, logger, print_section)
81 CALL timeset(routinen, handle)
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")
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
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.
100 IF (eval_analytical)
THEN
102 CALL cp_eval_at_ts_low(gopt_env, x, 1, dimer_env, calc_force, f1, dimer_env%rot%g1)
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
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
119 CALL get_theta(gradient, dimer_env, norm)
121 dimer_env%cg_rot%norm_theta_old = dimer_env%cg_rot%norm_theta
122 dimer_env%cg_rot%norm_theta = norm
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
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
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
144 gradient = -2.0_dp*(dimer_env%rot%g1p - dimer_env%rot%g0)
145 CALL get_theta(gradient, dimer_env, norm)
148 IF (debug_this_module .AND. (iw > 0))
THEN
149 WRITE (iw,
'(A)')
"Rotational Force step (1,3):"
150 WRITE (iw,
'(3F15.9)') gradient
155 CALL cp_eval_at_ts_low(gopt_env, x, 0, dimer_env, calc_force, f, dimer_env%rot%g0)
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
164 CALL cp_rot_opt(gopt_env%gopt_dimer_env, x, gopt_env%gopt_dimer_param, &
165 gopt_env%gopt_dimer_env%geo_section)
172 IF (dimer_env%kdimer)
THEN
176 WRITE (iw,
'(T2,A)')
"DIMER| Correcting gradients for Translation with K-DIMER method"
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
188 WRITE (iw,
'(T2,A)')
"DIMER| Correcting gradients for Translation with standard method"
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)
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)
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))
202 IF (.NOT. gopt_env%do_line_search)
THEN
203 f = sqrt(dot_product(gradient, gradient))
205 f = -dot_product(gradient, dimer_env%tsl%tls_vec)
209 CALL timestop(handle)
221 SUBROUTINE remove_rot_transl_component(gopt_env, gradient, print_section)
223 REAL(kind=
dp),
DIMENSION(:) :: gradient
226 CHARACTER(len=*),
PARAMETER :: routinen =
'remove_rot_transl_component'
228 INTEGER :: dof, handle, i, j, natoms
229 REAL(kind=
dp) :: norm, norm_gradient_old
230 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: d, mat
234 CALL timeset(routinen, handle)
239 natoms = particles%n_els
240 norm_gradient_old = sqrt(dot_product(gradient, gradient))
241 IF (norm_gradient_old > 0.0_dp)
THEN
243 CALL rot_ana(particles%els, mat, dof, print_section, keep_rotations=.false., &
244 mass_weighted=.false., natoms=natoms)
247 ALLOCATE (d(3*natoms, dof))
252 norm = dot_product(mat(:, i), mat(:, j))
257 norm = dot_product(gradient, d(:, i))
258 gradient = gradient - norm*d(:, i)
266 CALL timestop(handle)
267 END SUBROUTINE remove_rot_transl_component
282 SUBROUTINE cp_eval_at_ts_low(gopt_env, x, dimer_index, dimer_env, calc_force, &
285 REAL(kind=
dp),
DIMENSION(:),
POINTER :: x
286 INTEGER,
INTENT(IN) :: dimer_index
288 LOGICAL,
INTENT(IN) :: calc_force
289 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: f
290 REAL(kind=
dp),
DIMENSION(:),
OPTIONAL :: gradient
292 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_eval_at_ts_low'
294 INTEGER :: handle, idg, idir, ip
298 CALL timeset(routinen, handle)
302 DO ip = 1, particles%n_els
305 particles%els(ip)%r(idir) = x(idg) + real(dimer_index, kind=
dp)*dimer_env%nvec(idg)*dimer_env%dr
318 IF (
PRESENT(gradient))
THEN
321 DO ip = 1, particles%n_els
324 cpassert(
SIZE(gradient) >= idg)
325 gradient(idg) = -particles%els(ip)%f(idir)
329 CALL timestop(handle)
330 END SUBROUTINE cp_eval_at_ts_low
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.
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.
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, ipi_env)
returns various attributes about the force environment
performs geometry optimization
subroutine, public cp_rot_opt(gopt_env, x0, gopt_param, geo_section)
Main driver to perform rotation optimization for Dimer.
contains a functional that calculates the energy and its derivatives for the geometry optimizer
Defines the basic variable types.
integer, parameter, public dp
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.
calculates the potential energy of a system, and its derivatives
represent a list of objects