Line data Source code
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 performs geometry optimization
10 : !> \par History
11 : !> none
12 : ! **************************************************************************************************
13 : MODULE geo_opt
14 :
15 : USE bfgs_optimizer, ONLY: geoopt_bfgs
16 : USE cg_optimizer, ONLY: geoopt_cg
17 : USE cp_lbfgs_geo, ONLY: geoopt_lbfgs
18 : USE cp_log_handling, ONLY: cp_get_default_logger,&
19 : cp_logger_type
20 : USE cp_output_handling, ONLY: cp_add_iter_level,&
21 : cp_iterate,&
22 : cp_rm_iter_level
23 : USE force_env_types, ONLY: force_env_type
24 : USE global_types, ONLY: global_environment_type
25 : USE gopt_f_methods, ONLY: gopt_f_create_x0
26 : USE gopt_f_types, ONLY: gopt_f_create,&
27 : gopt_f_release,&
28 : gopt_f_type
29 : USE gopt_param_types, ONLY: gopt_param_read,&
30 : gopt_param_type
31 : USE hfx_ace_methods, ONLY: hfx_ace_set_dynamic_mode
32 : USE input_constants, ONLY: default_bfgs_method_id,&
33 : default_cg_method_id,&
34 : default_lbfgs_method_id
35 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
36 : section_vals_type,&
37 : section_vals_val_get,&
38 : section_vals_val_set
39 : USE kinds, ONLY: dp
40 : #include "../base/base_uses.f90"
41 :
42 : IMPLICIT NONE
43 : PRIVATE
44 :
45 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'geo_opt'
46 :
47 : PUBLIC :: cp_geo_opt, cp_rot_opt
48 :
49 : CONTAINS
50 :
51 : ! **************************************************************************************************
52 : !> \brief Main driver to perform geometry optimization
53 : !> \param force_env ...
54 : !> \param globenv ...
55 : !> \param eval_opt_geo ...
56 : !> \param rm_restart_info ...
57 : ! **************************************************************************************************
58 2628 : SUBROUTINE cp_geo_opt(force_env, globenv, eval_opt_geo, rm_restart_info)
59 :
60 : TYPE(force_env_type), POINTER :: force_env
61 : TYPE(global_environment_type), POINTER :: globenv
62 : LOGICAL, INTENT(IN), OPTIONAL :: eval_opt_geo, rm_restart_info
63 :
64 : CHARACTER(len=*), PARAMETER :: routineN = 'cp_geo_opt'
65 :
66 : INTEGER :: handle, step_start_val
67 : LOGICAL :: my_rm_restart_info
68 876 : REAL(KIND=dp), DIMENSION(:), POINTER :: x0
69 : TYPE(cp_logger_type), POINTER :: logger
70 : TYPE(gopt_f_type), POINTER :: gopt_env
71 : TYPE(gopt_param_type), POINTER :: gopt_param
72 : TYPE(section_vals_type), POINTER :: geo_section, root_section
73 :
74 876 : CALL timeset(routineN, handle)
75 876 : logger => cp_get_default_logger()
76 :
77 876 : CPASSERT(ASSOCIATED(force_env))
78 876 : CPASSERT(ASSOCIATED(globenv))
79 876 : NULLIFY (gopt_param, gopt_env, x0)
80 :
81 : ! Tell ACE that this is a dynamic run: full HFX is used for the
82 : ! entire first geometry step so that wavefunction extrapolation
83 : ! delivers a near-converged C_occ to step 1, making the ACE
84 : ! projector BUILD there accurate.
85 876 : CALL hfx_ace_set_dynamic_mode(.TRUE.)
86 :
87 876 : root_section => force_env%root_section
88 876 : geo_section => section_vals_get_subs_vals(root_section, "MOTION%GEO_OPT")
89 :
90 876 : ALLOCATE (gopt_param)
91 876 : CALL gopt_param_read(gopt_param, geo_section)
92 : CALL gopt_f_create(gopt_env, gopt_param, force_env=force_env, globenv=globenv, &
93 876 : geo_opt_section=geo_section, eval_opt_geo=eval_opt_geo)
94 876 : CALL gopt_f_create_x0(gopt_env, x0)
95 :
96 876 : CALL section_vals_val_get(geo_section, "STEP_START_VAL", i_val=step_start_val)
97 876 : CALL cp_add_iter_level(logger%iter_info, "GEO_OPT")
98 876 : CALL cp_iterate(logger%iter_info, iter_nr=step_start_val)
99 : CALL cp_geo_opt_low(force_env, globenv, gopt_param, gopt_env, &
100 876 : geo_section, x0)
101 876 : CALL cp_rm_iter_level(logger%iter_info, "GEO_OPT")
102 :
103 : ! Reset counter for next iteration, unless rm_restart_info==.FALSE.
104 876 : my_rm_restart_info = .TRUE.
105 876 : IF (PRESENT(rm_restart_info)) my_rm_restart_info = rm_restart_info
106 28 : IF (my_rm_restart_info) THEN
107 848 : CALL section_vals_val_set(geo_section, "STEP_START_VAL", i_val=0)
108 : END IF
109 :
110 876 : DEALLOCATE (x0)
111 876 : CALL gopt_f_release(gopt_env)
112 876 : DEALLOCATE (gopt_param)
113 876 : CALL timestop(handle)
114 :
115 876 : END SUBROUTINE cp_geo_opt
116 :
117 : ! **************************************************************************************************
118 : !> \brief Main driver to perform rotation optimization for Dimer
119 : !> \param gopt_env ...
120 : !> \param x0 ...
121 : !> \param gopt_param ...
122 : !> \param geo_section ...
123 : ! **************************************************************************************************
124 280 : SUBROUTINE cp_rot_opt(gopt_env, x0, gopt_param, geo_section)
125 : TYPE(gopt_f_type), POINTER :: gopt_env
126 : REAL(KIND=dp), DIMENSION(:), POINTER :: x0
127 : TYPE(gopt_param_type), POINTER :: gopt_param
128 : TYPE(section_vals_type), POINTER :: geo_section
129 :
130 : CHARACTER(len=*), PARAMETER :: routineN = 'cp_rot_opt'
131 :
132 : INTEGER :: handle, step_start_val
133 : TYPE(cp_logger_type), POINTER :: logger
134 :
135 140 : CALL timeset(routineN, handle)
136 140 : logger => cp_get_default_logger()
137 140 : CPASSERT(ASSOCIATED(gopt_env))
138 140 : CPASSERT(ASSOCIATED(gopt_env%force_env))
139 140 : CPASSERT(ASSOCIATED(gopt_env%globenv))
140 :
141 140 : CALL section_vals_val_get(geo_section, "STEP_START_VAL", i_val=step_start_val)
142 140 : CALL cp_add_iter_level(logger%iter_info, "ROT_OPT")
143 140 : CALL cp_iterate(logger%iter_info, iter_nr=step_start_val)
144 : CALL cp_geo_opt_low(gopt_env%force_env, gopt_env%globenv, gopt_param, gopt_env, &
145 140 : geo_section, x0)
146 140 : CALL cp_rm_iter_level(logger%iter_info, "ROT_OPT")
147 :
148 : ! Reset counter for next iteration
149 140 : CALL section_vals_val_set(geo_section, "STEP_START_VAL", i_val=0)
150 140 : CALL timestop(handle)
151 :
152 140 : END SUBROUTINE cp_rot_opt
153 :
154 : ! **************************************************************************************************
155 : !> \brief call to low level geometry optimizers
156 : !> \param force_env ...
157 : !> \param globenv ...
158 : !> \param gopt_param ...
159 : !> \param gopt_env ...
160 : !> \param geo_section ...
161 : !> \param x0 ...
162 : ! **************************************************************************************************
163 1016 : SUBROUTINE cp_geo_opt_low(force_env, globenv, gopt_param, gopt_env, &
164 : geo_section, x0)
165 : TYPE(force_env_type), POINTER :: force_env
166 : TYPE(global_environment_type), POINTER :: globenv
167 : TYPE(gopt_param_type), POINTER :: gopt_param
168 : TYPE(gopt_f_type), POINTER :: gopt_env
169 : TYPE(section_vals_type), POINTER :: geo_section
170 : REAL(KIND=dp), DIMENSION(:), POINTER :: x0
171 :
172 1016 : CPASSERT(ASSOCIATED(force_env))
173 1016 : CPASSERT(ASSOCIATED(globenv))
174 1016 : CPASSERT(ASSOCIATED(gopt_param))
175 1016 : CPASSERT(ASSOCIATED(gopt_env))
176 1016 : CPASSERT(ASSOCIATED(x0))
177 1016 : CPASSERT(ASSOCIATED(geo_section))
178 :
179 1778 : SELECT CASE (gopt_param%method_id)
180 : CASE (default_bfgs_method_id)
181 : CALL geoopt_bfgs(force_env, gopt_param, globenv, &
182 762 : geo_section, gopt_env, x0)
183 : CASE (default_lbfgs_method_id)
184 : CALL geoopt_lbfgs(force_env, gopt_param, globenv, &
185 46 : geo_section, gopt_env, x0)
186 : CASE (default_cg_method_id)
187 : CALL geoopt_cg(force_env, gopt_param, globenv, &
188 208 : geo_section, gopt_env, x0)
189 : CASE DEFAULT
190 1016 : CPABORT("Invalid or not yet implemented method for optimization")
191 : END SELECT
192 :
193 1016 : END SUBROUTINE cp_geo_opt_low
194 :
195 : END MODULE geo_opt
|