(git:98357aa)
Loading...
Searching...
No Matches
qs_cdft_opt_types.F
Go to the documentation of this file.
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 Control parameters for optimizers that work with CDFT constraints
10!> \par History
11!> separated from scf_control_types [03.2018]
12!> \author Nico Holmberg [03.2018]
13! **************************************************************************************************
15
16 USE input_constants, ONLY: &
23 USE kinds, ONLY: dp
24#include "./base/base_uses.f90"
25
26 IMPLICIT NONE
27
28 PRIVATE
29
30 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_cdft_opt_types'
31
32 ! Public data types
33
34 PUBLIC :: cdft_opt_type
35
36 ! Public subroutines
37
38 PUBLIC :: cdft_opt_type_create, &
43
44! **************************************************************************************************
45!> \brief contains the parameters needed by CDFT specific optimizers
46!> \param build_jacobian logical which determines if the inverse Jacobian should be computed
47!> \param jacobian_step the step size for calculating the finite difference Jacobian
48!> \param newton_step the step size used by the Newton optimizer with values between 0 and 1
49!> \param newton_step_save permanent copy of the above
50!> \param jacobian_type the finite difference scheme to compute the Jacobian
51!> \param broyden_type the variant of Broyden's method to use
52!> \param jacobian_freq control parameters defining how often the Jacobian is built
53!> \param ijacobian counter to track how many SCF iterations/energy evaluations have passed since
54!> the last Jacobian rebuild
55!> \param broyden_update logical which determines if a Broyden update is needed
56!> \param max_ls the maximum number of backtracking line search steps to perform
57!> \param continue_ls continue line search until max steps are reached or until the gradient
58!> no longer decreases
59!> \param factor_ls line search parameter used in generating a new step size
60!> \par History
61!> created [03.2018]
62!> \author Nico Holmberg [03.2018]
63! **************************************************************************************************
64
66 LOGICAL :: build_jacobian = .false.
67 LOGICAL :: broyden_update = .false.
68 LOGICAL :: continue_ls = .false.
69 LOGICAL :: jacobian_restart = .false.
70 REAL(kind=dp) :: newton_step = 0.0_dp
71 REAL(kind=dp) :: newton_step_save = 0.0_dp
72 REAL(kind=dp) :: factor_ls = 0.0_dp
73 REAL(kind=dp), DIMENSION(:), &
74 ALLOCATABLE :: jacobian_step
75 REAL(kind=dp), DIMENSION(:), &
76 POINTER :: jacobian_vector => null()
77 INTEGER :: jacobian_type = -1
78 INTEGER :: broyden_type = -1
79 INTEGER :: jacobian_freq(2) = -1
80 INTEGER :: ijacobian(2) = -1
81 INTEGER :: max_ls = -1
82 END TYPE cdft_opt_type
83
84CONTAINS
85
86! **************************************************************************************************
87!> \brief allocates and initializes the CDFT optimizer control object with default values
88!> \param cdft_opt_control the object to initialize
89!> \par History
90!> 03.2018 created [Nico Holmberg]
91!> \author Nico Holmberg
92! **************************************************************************************************
93 SUBROUTINE cdft_opt_type_create(cdft_opt_control)
94
95 TYPE(cdft_opt_type), POINTER :: cdft_opt_control
96
97 CHARACTER(LEN=*), PARAMETER :: routinen = 'cdft_opt_type_create'
98
99 INTEGER :: handle
100
101 CALL timeset(routinen, handle)
102
103 cpassert(.NOT. ASSOCIATED(cdft_opt_control))
104 ALLOCATE (cdft_opt_control)
105
106 ! Load the default values
107
108 cdft_opt_control%jacobian_type = -1
109 cdft_opt_control%broyden_type = -1
110 cdft_opt_control%jacobian_freq(:) = 1
111 cdft_opt_control%newton_step = 1.0_dp
112 cdft_opt_control%newton_step_save = 1.0_dp
113 cdft_opt_control%factor_ls = 0.5_dp
114 cdft_opt_control%ijacobian(:) = 0
115 cdft_opt_control%max_ls = 0
116 cdft_opt_control%build_jacobian = .false.
117 cdft_opt_control%broyden_update = .false.
118 cdft_opt_control%continue_ls = .false.
119 cdft_opt_control%jacobian_restart = .false.
120 NULLIFY (cdft_opt_control%jacobian_vector)
121
122 CALL timestop(handle)
123
124 END SUBROUTINE cdft_opt_type_create
125
126! **************************************************************************************************
127!> \brief releases the CDFT optimizer control object
128!> \param cdft_opt_control the object to release
129!> \par History
130!> 03.2018 created [Nico Holmberg]
131!> \author Nico Holmberg
132! **************************************************************************************************
133 SUBROUTINE cdft_opt_type_release(cdft_opt_control)
134
135 TYPE(cdft_opt_type), POINTER :: cdft_opt_control
136
137 IF (ASSOCIATED(cdft_opt_control)) THEN
138 IF (ASSOCIATED(cdft_opt_control%jacobian_vector)) THEN
139 DEALLOCATE (cdft_opt_control%jacobian_vector)
140 END IF
141 IF (ALLOCATED(cdft_opt_control%jacobian_step)) THEN
142 DEALLOCATE (cdft_opt_control%jacobian_step)
143 END IF
144
145 DEALLOCATE (cdft_opt_control)
146 END IF
147
148 NULLIFY (cdft_opt_control)
149
150 END SUBROUTINE cdft_opt_type_release
151
152! **************************************************************************************************
153!> \brief reads the parameters of the CDFT optimizer type
154!> \param cdft_opt_control the object that will contain the values read
155!> \param inp_section the input section that contains the values that are read
156!> \par History
157!> 03.2018 created [Nico Holmberg]
158!> \author Nico Holmberg
159! **************************************************************************************************
160 SUBROUTINE cdft_opt_type_read(cdft_opt_control, inp_section)
161
162 TYPE(cdft_opt_type), POINTER :: cdft_opt_control
163 TYPE(section_vals_type), POINTER :: inp_section
164
165 CHARACTER(LEN=*), PARAMETER :: routinen = 'cdft_opt_type_read'
166
167 INTEGER :: handle
168 INTEGER, DIMENSION(:), POINTER :: tmplist
169 LOGICAL :: exists
170 REAL(kind=dp), DIMENSION(:), POINTER :: rtmplist
171 TYPE(section_vals_type), POINTER :: cdft_opt_section
172
173 CALL timeset(routinen, handle)
174
175 cpassert(ASSOCIATED(cdft_opt_control))
176 cdft_opt_section => section_vals_get_subs_vals(inp_section, "CDFT_OPT")
177
178 CALL section_vals_val_get(cdft_opt_section, "MAX_LS", &
179 i_val=cdft_opt_control%max_ls)
180 CALL section_vals_val_get(cdft_opt_section, "JACOBIAN_TYPE", &
181 i_val=cdft_opt_control%jacobian_type)
182 CALL section_vals_val_get(cdft_opt_section, "JACOBIAN_STEP", &
183 r_vals=rtmplist)
184 ALLOCATE (cdft_opt_control%jacobian_step(SIZE(rtmplist)))
185 cdft_opt_control%jacobian_step(:) = rtmplist
186 CALL section_vals_val_get(cdft_opt_section, "BROYDEN_TYPE", &
187 i_val=cdft_opt_control%broyden_type)
188 CALL section_vals_val_get(cdft_opt_section, "CONTINUE_LS", &
189 l_val=cdft_opt_control%continue_ls)
190 CALL section_vals_val_get(cdft_opt_section, "FACTOR_LS", &
191 r_val=cdft_opt_control%factor_ls)
192 IF (cdft_opt_control%factor_ls <= 0.0_dp .OR. &
193 cdft_opt_control%factor_ls >= 1.0_dp) THEN
194 CALL cp_abort(__location__, &
195 "Keyword FACTOR_LS must be between 0.0 and 1.0.")
196 END IF
197 CALL section_vals_val_get(cdft_opt_section, "JACOBIAN_FREQ", explicit=exists)
198 IF (exists) THEN
199 CALL section_vals_val_get(cdft_opt_section, "JACOBIAN_FREQ", &
200 i_vals=tmplist)
201 IF (SIZE(tmplist) /= 2) THEN
202 CALL cp_abort(__location__, &
203 "Keyword JACOBIAN_FREQ takes exactly two input values.")
204 END IF
205 IF (any(tmplist < 0)) THEN
206 CALL cp_abort(__location__, &
207 "Keyword JACOBIAN_FREQ takes only positive values.")
208 END IF
209 IF (all(tmplist == 0)) THEN
210 CALL cp_abort(__location__, &
211 "Both values to keyword JACOBIAN_FREQ cannot be zero.")
212 END IF
213 cdft_opt_control%jacobian_freq(:) = tmplist(1:2)
214 END IF
215 CALL section_vals_val_get(cdft_opt_section, "JACOBIAN_RESTART", &
216 l_val=cdft_opt_control%jacobian_restart)
217 IF (cdft_opt_control%jacobian_restart) THEN
218 CALL section_vals_val_get(cdft_opt_section, "JACOBIAN_VECTOR", &
219 r_vals=rtmplist)
220 ALLOCATE (cdft_opt_control%jacobian_vector(SIZE(rtmplist)))
221 cdft_opt_control%jacobian_vector = rtmplist
222 END IF
223
224 CALL timestop(handle)
225
226 END SUBROUTINE cdft_opt_type_read
227
228! **************************************************************************************************
229!> \brief writes information about the CDFT optimizer object
230!> \param cdft_opt_control the CDFT optimizer object
231!> \param optimizer the type of optimizer to use
232!> \param output_unit the output unit handle
233!> \par History
234!> 03.2018 created [Nico Holmberg]
235!> \author Nico Holmberg
236! **************************************************************************************************
237 SUBROUTINE cdft_opt_type_write(cdft_opt_control, optimizer, output_unit)
238 TYPE(cdft_opt_type), POINTER :: cdft_opt_control
239 INTEGER :: optimizer, output_unit
240
241 cpassert(ASSOCIATED(cdft_opt_control))
242
243 SELECT CASE (optimizer)
244 CASE DEFAULT
245 ! Do nothing
247 WRITE (output_unit, '(T3,A)') "Optimization with Broyden's method"
248 SELECT CASE (cdft_opt_control%broyden_type)
249 CASE (broyden_type_1)
250 WRITE (output_unit, '(A)') " variant : 1st method"
252 WRITE (output_unit, '(A)') " variant : 1st method with explicit initial Jacobian"
253 CASE (broyden_type_1_ls)
254 WRITE (output_unit, '(A)') " variant : 1st method with backtracking line search"
256 WRITE (output_unit, '(A)') &
257 " variant : 1st method with explicit initial Jacobian"
258 WRITE (output_unit, '(A)') &
259 " and backtracking line search"
260 CASE (broyden_type_2)
261 WRITE (output_unit, '(A)') " variant : 2nd method"
263 WRITE (output_unit, '(A)') " variant : 2nd method with explicit initial Jacobian"
264 CASE (broyden_type_2_ls)
265 WRITE (output_unit, '(A)') " variant : 2nd method with backtracking line search"
267 WRITE (output_unit, '(A)') &
268 " variant : 2nd method with explicit initial Jacobian"
269 WRITE (output_unit, '(A)') &
270 " and backtracking line search"
271 END SELECT
273 WRITE (output_unit, '(T3,A)') "Optimization with Newton's method"
275 WRITE (output_unit, '(T3,A)') "Optimization with Newton's method using backtracking line search"
276 END SELECT
277 SELECT CASE (optimizer)
278 CASE DEFAULT
279 ! Do nothing
281 IF (cdft_opt_control%jacobian_freq(2) > 0) THEN
282 WRITE (output_unit, '(T6,A,I4,A)') &
283 "The Jacobian is restarted every ", cdft_opt_control%jacobian_freq(2), " energy evaluation"
284 IF (cdft_opt_control%jacobian_freq(1) > 0) THEN
285 WRITE (output_unit, '(T29,A,I4,A)') &
286 "or every ", cdft_opt_control%jacobian_freq(1), " CDFT SCF iteration"
287 END IF
288 ELSE
289 WRITE (output_unit, '(T6,A,I4,A)') &
290 "The Jacobian is restarted every ", cdft_opt_control%jacobian_freq(1), " CDFT SCF iteration"
291 END IF
292 WRITE (output_unit, '(T3,A,F8.4)') &
293 "Optimizer step size: ", cdft_opt_control%newton_step_save
294 END SELECT
295
296 END SUBROUTINE cdft_opt_type_write
297
298! **************************************************************************************************
299!> \brief copies settings between two CDFT optimizer control objects retaining both
300!> \param new the object where to copy the settings
301!> \param old the object from where to copy the settings
302!> \par History
303!> 03.2018 created [Nico Holmberg]
304!> \author Nico Holmberg
305! **************************************************************************************************
306 SUBROUTINE cdft_opt_type_copy(new, old)
307
308 TYPE(cdft_opt_type), POINTER :: new, old
309
310 CHARACTER(LEN=*), PARAMETER :: routinen = 'cdft_opt_type_copy'
311
312 INTEGER :: handle
313
314 ! Do nothing if cdft_opt_type is not allocated
315 ! this happens if CDFT is performed with an optimizer other than Broyden/Newton
316 IF (.NOT. ASSOCIATED(old)) RETURN
317
318 CALL timeset(routinen, handle)
319
320 IF (.NOT. ASSOCIATED(new)) CALL cdft_opt_type_create(new)
321 new%max_ls = old%max_ls
322 new%continue_ls = old%continue_ls
323 new%factor_ls = old%factor_ls
324 new%jacobian_type = old%jacobian_type
325 new%jacobian_freq(:) = old%jacobian_freq(:)
326 new%newton_step = old%newton_step
327 new%newton_step_save = old%newton_step_save
328 new%ijacobian(:) = old%ijacobian(:)
329 new%build_jacobian = old%build_jacobian
330 new%broyden_type = old%broyden_type
331 new%broyden_update = old%broyden_update
332 IF (ALLOCATED(new%jacobian_step)) DEALLOCATE (new%jacobian_step)
333 ALLOCATE (new%jacobian_step(SIZE(old%jacobian_step)))
334 new%jacobian_step(:) = old%jacobian_step
335 IF (old%jacobian_restart) THEN
336 ! Transfer restart vector for inverse Jacobian matrix
337 ! (qs_calculate_inverse_jacobian handles deallocation of transferred vector)
338 new%jacobian_restart = .true.
339 ALLOCATE (new%jacobian_vector(SIZE(old%jacobian_vector)))
340 new%jacobian_vector = old%jacobian_vector
341 DEALLOCATE (old%jacobian_vector)
342 old%jacobian_restart = .false.
343 END IF
344
345 CALL timestop(handle)
346
347 END SUBROUTINE cdft_opt_type_copy
348
349END MODULE qs_cdft_opt_types
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public broyden_type_2_explicit_ls
integer, parameter, public broyden_type_1_explicit
integer, parameter, public broyden_type_2_ls
integer, parameter, public broyden_type_1
integer, parameter, public outer_scf_optimizer_broyden
integer, parameter, public broyden_type_1_explicit_ls
integer, parameter, public broyden_type_2_explicit
integer, parameter, public broyden_type_2
integer, parameter, public outer_scf_optimizer_newton_ls
integer, parameter, public outer_scf_optimizer_newton
integer, parameter, public broyden_type_1_ls
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
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Control parameters for optimizers that work with CDFT constraints.
subroutine, public cdft_opt_type_create(cdft_opt_control)
allocates and initializes the CDFT optimizer control object with default values
subroutine, public cdft_opt_type_release(cdft_opt_control)
releases the CDFT optimizer control object
subroutine, public cdft_opt_type_copy(new, old)
copies settings between two CDFT optimizer control objects retaining both
subroutine, public cdft_opt_type_read(cdft_opt_control, inp_section)
reads the parameters of the CDFT optimizer type
subroutine, public cdft_opt_type_write(cdft_opt_control, optimizer, output_unit)
writes information about the CDFT optimizer object
contains the parameters needed by CDFT specific optimizers