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 Main driver for L-BFGS optimizer
10 : !> \par History
11 : !> 01.2020 Space Group Symmetry introduced by Pierre-André Cazade [pcazade]
12 : ! **************************************************************************************************
13 : MODULE cp_lbfgs_geo
14 : USE cell_types, ONLY: cell_type
15 : USE cp_external_control, ONLY: external_control
16 : USE cp_lbfgs_optimizer_gopt, ONLY: cp_lbfgs_opt_gopt_type,&
17 : cp_opt_gopt_create,&
18 : cp_opt_gopt_next,&
19 : cp_opt_gopt_release,&
20 : cp_opt_gopt_stop
21 : USE cp_log_handling, ONLY: cp_get_default_logger,&
22 : cp_logger_type
23 : USE cp_output_handling, ONLY: cp_iterate,&
24 : cp_print_key_finished_output,&
25 : cp_print_key_unit_nr
26 : USE cp_subsys_types, ONLY: cp_subsys_type
27 : USE force_env_types, ONLY: force_env_get,&
28 : force_env_type
29 : USE global_types, ONLY: global_environment_type
30 : USE gopt_f_methods, ONLY: gopt_f_ii,&
31 : gopt_f_io_finalize,&
32 : print_geo_opt_header,&
33 : print_geo_opt_nc
34 : USE gopt_f_types, ONLY: gopt_f_type
35 : USE gopt_param_types, ONLY: gopt_param_type
36 : USE input_constants, ONLY: default_ts_method_id
37 : USE input_section_types, ONLY: section_vals_type,&
38 : section_vals_val_set
39 : USE kinds, ONLY: dp
40 : USE message_passing, ONLY: mp_para_env_type
41 : USE space_groups, ONLY: identify_space_group,&
42 : print_spgr,&
43 : spgr_apply_rotations_coord
44 : USE space_groups_types, ONLY: spgr_type
45 : #include "../base/base_uses.f90"
46 :
47 : IMPLICIT NONE
48 : PRIVATE
49 :
50 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_lbfgs_geo'
51 :
52 : PUBLIC :: geoopt_lbfgs
53 :
54 : CONTAINS
55 :
56 : ! **************************************************************************************************
57 : !> \brief ...
58 : !> \param force_env ...
59 : !> \param gopt_param ...
60 : !> \param globenv ...
61 : !> \param geo_section ...
62 : !> \param gopt_env ...
63 : !> \param x0 ...
64 : !> \par History
65 : !> 08.2003 created [fawzi]
66 : !> 01.2020 modified [pcazade]
67 : !> \author Fawzi Mohamed
68 : ! **************************************************************************************************
69 208 : SUBROUTINE geoopt_lbfgs(force_env, gopt_param, globenv, geo_section, gopt_env, &
70 : x0)
71 : TYPE(force_env_type), POINTER :: force_env
72 : TYPE(gopt_param_type), POINTER :: gopt_param
73 : TYPE(global_environment_type), POINTER :: globenv
74 : TYPE(section_vals_type), POINTER :: geo_section
75 : TYPE(gopt_f_type), POINTER :: gopt_env
76 : REAL(KIND=dp), DIMENSION(:), POINTER :: x0
77 :
78 : CHARACTER(len=*), PARAMETER :: routineN = 'geoopt_lbfgs'
79 :
80 : INTEGER :: handle, iter_nr, its, output_unit
81 : LOGICAL :: converged, should_stop
82 : TYPE(cell_type), POINTER :: cell
83 : TYPE(cp_lbfgs_opt_gopt_type), POINTER :: optimizer
84 : TYPE(cp_logger_type), POINTER :: logger
85 : TYPE(cp_subsys_type), POINTER :: subsys
86 : TYPE(mp_para_env_type), POINTER :: para_env
87 : TYPE(section_vals_type), POINTER :: root_section
88 : TYPE(spgr_type), POINTER :: spgr
89 :
90 104 : CALL timeset(routineN, handle)
91 :
92 104 : NULLIFY (optimizer, para_env, spgr)
93 104 : logger => cp_get_default_logger()
94 104 : spgr => gopt_env%spgr
95 104 : root_section => force_env%root_section
96 104 : CPASSERT(ASSOCIATED(force_env))
97 104 : CPASSERT(ASSOCIATED(gopt_param))
98 :
99 : ! collecting subsys
100 104 : CALL force_env_get(force_env, para_env=para_env, cell=cell, subsys=subsys)
101 :
102 : ! Geometry optimization starts now
103 : output_unit = cp_print_key_unit_nr(logger, geo_section, "PRINT%PROGRAM_RUN_INFO", &
104 104 : extension=".geoLog")
105 104 : CALL print_geo_opt_header(gopt_env, output_unit, "L-BFGS")
106 :
107 : ! finds space group
108 104 : IF (spgr%keep_space_group) THEN
109 2 : CALL identify_space_group(subsys, geo_section, gopt_env, output_unit)
110 2 : CALL spgr_apply_rotations_coord(spgr, x0)
111 2 : CALL print_spgr(spgr)
112 : END IF
113 :
114 : ! Stop if not implemented
115 104 : IF (gopt_env%type_id == default_ts_method_id) THEN
116 0 : CPABORT("L-BFGS method not yet working with DIMER")
117 : END IF
118 :
119 520 : ALLOCATE (optimizer)
120 : CALL cp_opt_gopt_create(optimizer, para_env=para_env, obj_funct=gopt_env, &
121 : x0=x0, m=gopt_param%max_h_rank, &
122 : print_every=gopt_param%print_control, &
123 : wanted_relative_f_delta=gopt_param%wanted_rel_f_error, &
124 : wanted_projected_gradient=gopt_param%wanted_proj_gradient, &
125 : max_f_per_iter=gopt_param%max_f_per_iter, &
126 104 : trust_radius=gopt_param%trust_radius)
127 104 : CALL cp_iterate(logger%iter_info, increment=0, iter_nr_out=iter_nr)
128 104 : converged = .FALSE.
129 :
130 3046 : DO its = iter_nr + 1, gopt_param%max_iter
131 3044 : CALL cp_iterate(logger%iter_info, last=(its == gopt_param%max_iter))
132 3044 : CALL section_vals_val_set(geo_section, "STEP_START_VAL", i_val=its)
133 3044 : CALL gopt_f_ii(its, output_unit)
134 :
135 : ! Real optimization step..
136 3044 : IF (.NOT. cp_opt_gopt_next(optimizer, geo_section=geo_section, &
137 : force_env=force_env, gopt_param=gopt_param, &
138 : converged=converged, spgr=spgr)) EXIT
139 :
140 : ! Check for an external exit command
141 2974 : CALL external_control(should_stop, "GEO", globenv=globenv)
142 2974 : IF (should_stop) THEN
143 0 : CALL cp_opt_gopt_stop(optimizer)
144 0 : EXIT
145 : END IF
146 6020 : IF (its == gopt_param%max_iter) EXIT
147 : END DO
148 :
149 104 : IF (optimizer%status == 5) THEN
150 0 : IF (output_unit > 0) THEN
151 0 : WRITE (output_unit, FMT="(/,T2,A)") "*** L-BFGS ABNORMAL EXIT: OPTIMIZATION NOT CONVERGED ***"
152 0 : WRITE (output_unit, FMT="(T2,A)") "L-BFGS task: "//TRIM(optimizer%task)
153 : END IF
154 104 : ELSE IF ((its == gopt_param%max_iter) .AND. (.NOT. converged)) THEN
155 32 : CALL print_geo_opt_nc(gopt_env, output_unit)
156 : END IF
157 :
158 : ! show space_group
159 104 : IF (spgr%show_space_group) THEN
160 2 : CALL identify_space_group(subsys, geo_section, gopt_env, output_unit)
161 2 : CALL print_spgr(spgr)
162 : END IF
163 :
164 : ! Write final output information, if converged
165 104 : CALL cp_iterate(logger%iter_info, last=.TRUE., increment=0)
166 : CALL gopt_f_io_finalize(gopt_env, force_env, optimizer%x, converged, its, root_section, &
167 104 : optimizer%para_env, optimizer%master, output_unit)
168 :
169 104 : CALL cp_opt_gopt_release(optimizer)
170 104 : DEALLOCATE (optimizer)
171 : CALL cp_print_key_finished_output(output_unit, logger, geo_section, &
172 104 : "PRINT%PROGRAM_RUN_INFO")
173 :
174 104 : CALL timestop(handle)
175 :
176 104 : END SUBROUTINE geoopt_lbfgs
177 :
178 : END MODULE cp_lbfgs_geo
|