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 2607 : 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 869 : 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 869 : CALL timeset(routineN, handle)
75 869 : logger => cp_get_default_logger()
76 :
77 869 : CPASSERT(ASSOCIATED(force_env))
78 869 : CPASSERT(ASSOCIATED(globenv))
79 869 : 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 869 : CALL hfx_ace_set_dynamic_mode(.TRUE.)
86 :
87 869 : root_section => force_env%root_section
88 869 : geo_section => section_vals_get_subs_vals(root_section, "MOTION%GEO_OPT")
89 :
90 869 : ALLOCATE (gopt_param)
91 869 : CALL gopt_param_read(gopt_param, geo_section)
92 : CALL gopt_f_create(gopt_env, gopt_param, force_env=force_env, globenv=globenv, &
93 869 : geo_opt_section=geo_section, eval_opt_geo=eval_opt_geo)
94 869 : CALL gopt_f_create_x0(gopt_env, x0)
95 :
96 869 : CALL section_vals_val_get(geo_section, "STEP_START_VAL", i_val=step_start_val)
97 869 : CALL cp_add_iter_level(logger%iter_info, "GEO_OPT")
98 869 : 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 869 : geo_section, x0)
101 869 : CALL cp_rm_iter_level(logger%iter_info, "GEO_OPT")
102 :
103 : ! Reset counter for next iteration, unless rm_restart_info==.FALSE.
104 869 : my_rm_restart_info = .TRUE.
105 869 : IF (PRESENT(rm_restart_info)) my_rm_restart_info = rm_restart_info
106 25 : IF (my_rm_restart_info) &
107 844 : CALL section_vals_val_set(geo_section, "STEP_START_VAL", i_val=0)
108 :
109 869 : DEALLOCATE (x0)
110 869 : CALL gopt_f_release(gopt_env)
111 869 : DEALLOCATE (gopt_param)
112 869 : CALL timestop(handle)
113 :
114 869 : END SUBROUTINE cp_geo_opt
115 :
116 : ! **************************************************************************************************
117 : !> \brief Main driver to perform rotation optimization for Dimer
118 : !> \param gopt_env ...
119 : !> \param x0 ...
120 : !> \param gopt_param ...
121 : !> \param geo_section ...
122 : ! **************************************************************************************************
123 264 : SUBROUTINE cp_rot_opt(gopt_env, x0, gopt_param, geo_section)
124 : TYPE(gopt_f_type), POINTER :: gopt_env
125 : REAL(KIND=dp), DIMENSION(:), POINTER :: x0
126 : TYPE(gopt_param_type), POINTER :: gopt_param
127 : TYPE(section_vals_type), POINTER :: geo_section
128 :
129 : CHARACTER(len=*), PARAMETER :: routineN = 'cp_rot_opt'
130 :
131 : INTEGER :: handle, step_start_val
132 : TYPE(cp_logger_type), POINTER :: logger
133 :
134 132 : CALL timeset(routineN, handle)
135 132 : logger => cp_get_default_logger()
136 132 : CPASSERT(ASSOCIATED(gopt_env))
137 132 : CPASSERT(ASSOCIATED(gopt_env%force_env))
138 132 : CPASSERT(ASSOCIATED(gopt_env%globenv))
139 :
140 132 : CALL section_vals_val_get(geo_section, "STEP_START_VAL", i_val=step_start_val)
141 132 : CALL cp_add_iter_level(logger%iter_info, "ROT_OPT")
142 132 : CALL cp_iterate(logger%iter_info, iter_nr=step_start_val)
143 : CALL cp_geo_opt_low(gopt_env%force_env, gopt_env%globenv, gopt_param, gopt_env, &
144 132 : geo_section, x0)
145 132 : CALL cp_rm_iter_level(logger%iter_info, "ROT_OPT")
146 :
147 : ! Reset counter for next iteration
148 132 : CALL section_vals_val_set(geo_section, "STEP_START_VAL", i_val=0)
149 132 : CALL timestop(handle)
150 :
151 132 : END SUBROUTINE cp_rot_opt
152 :
153 : ! **************************************************************************************************
154 : !> \brief call to low level geometry optimizers
155 : !> \param force_env ...
156 : !> \param globenv ...
157 : !> \param gopt_param ...
158 : !> \param gopt_env ...
159 : !> \param geo_section ...
160 : !> \param x0 ...
161 : ! **************************************************************************************************
162 1001 : SUBROUTINE cp_geo_opt_low(force_env, globenv, gopt_param, gopt_env, &
163 : geo_section, x0)
164 : TYPE(force_env_type), POINTER :: force_env
165 : TYPE(global_environment_type), POINTER :: globenv
166 : TYPE(gopt_param_type), POINTER :: gopt_param
167 : TYPE(gopt_f_type), POINTER :: gopt_env
168 : TYPE(section_vals_type), POINTER :: geo_section
169 : REAL(KIND=dp), DIMENSION(:), POINTER :: x0
170 :
171 1001 : CPASSERT(ASSOCIATED(force_env))
172 1001 : CPASSERT(ASSOCIATED(globenv))
173 1001 : CPASSERT(ASSOCIATED(gopt_param))
174 1001 : CPASSERT(ASSOCIATED(gopt_env))
175 1001 : CPASSERT(ASSOCIATED(x0))
176 1001 : CPASSERT(ASSOCIATED(geo_section))
177 :
178 1758 : SELECT CASE (gopt_param%method_id)
179 : CASE (default_bfgs_method_id)
180 : CALL geoopt_bfgs(force_env, gopt_param, globenv, &
181 757 : geo_section, gopt_env, x0)
182 : CASE (default_lbfgs_method_id)
183 : CALL geoopt_lbfgs(force_env, gopt_param, globenv, &
184 46 : geo_section, gopt_env, x0)
185 : CASE (default_cg_method_id)
186 : CALL geoopt_cg(force_env, gopt_param, globenv, &
187 198 : geo_section, gopt_env, x0)
188 : CASE DEFAULT
189 1001 : CPABORT("Invalid or not yet implemented method for optimization")
190 : END SELECT
191 :
192 1001 : END SUBROUTINE cp_geo_opt_low
193 :
194 : END MODULE geo_opt
|