(git:374b731)
Loading...
Searching...
No Matches
optimize_input.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
24 USE f77_interface, ONLY: calc_force,&
36 USE kinds, ONLY: default_path_length,&
38 dp
39 USE machine, ONLY: m_flush,&
42 USE message_passing, ONLY: mp_comm_type,&
44 USE parallel_rng_types, ONLY: uniform,&
46 USE physcon, ONLY: bohr
47 USE powell, ONLY: opt_state_type,&
49#include "./base/base_uses.f90"
50
51 IMPLICIT NONE
52 PRIVATE
53
54 PUBLIC :: run_optimize_input
55
56 TYPE fm_env_type
57 CHARACTER(LEN=default_path_length) :: optimize_file_name
58
59 CHARACTER(LEN=default_path_length) :: ref_traj_file_name
60 CHARACTER(LEN=default_path_length) :: ref_force_file_name
61 CHARACTER(LEN=default_path_length) :: ref_cell_file_name
62
63 INTEGER :: group_size
64
65 REAL(KIND=dp) :: energy_weight
66 REAL(KIND=dp) :: shift_mm
67 REAL(KIND=dp) :: shift_qm
68 LOGICAL :: shift_average
69 INTEGER :: frame_start, frame_stop, frame_stride, frame_count
70 END TYPE
71
72 TYPE variable_type
73 CHARACTER(LEN=default_string_length) :: label
74 REAL(KIND=dp) :: value
75 LOGICAL :: fixed
76 END TYPE
77
78 TYPE oi_env_type
79 INTEGER :: method
80 INTEGER :: seed
81 CHARACTER(LEN=default_path_length) :: project_name
82 TYPE(fm_env_type) :: fm_env
83 TYPE(variable_type), DIMENSION(:), ALLOCATABLE :: variables
84 REAL(KIND=dp) :: rhobeg, rhoend
85 INTEGER :: maxfun
86 INTEGER :: iter_start_val
87 REAL(KIND=dp) :: randomize_variables
88 REAL(KIND=dp) :: start_time, target_time
89 END TYPE
90
91 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'optimize_input'
92
93CONTAINS
94
95! **************************************************************************************************
96!> \brief main entry point for methods aimed at optimizing parameters in a CP2K input file
97!> \param input_declaration ...
98!> \param root_section ...
99!> \param para_env ...
100!> \author Joost VandeVondele
101! **************************************************************************************************
102 SUBROUTINE run_optimize_input(input_declaration, root_section, para_env)
103 TYPE(section_type), POINTER :: input_declaration
104 TYPE(section_vals_type), POINTER :: root_section
105 TYPE(mp_para_env_type), POINTER :: para_env
106
107 CHARACTER(len=*), PARAMETER :: routinen = 'run_optimize_input'
108
109 INTEGER :: handle, i_var
110 REAL(kind=dp) :: random_number, seed(3, 2)
111 TYPE(oi_env_type) :: oi_env
112 TYPE(rng_stream_type), ALLOCATABLE :: rng_stream
113
114 CALL timeset(routinen, handle)
115
116 oi_env%start_time = m_walltime()
117
118 CALL parse_input(oi_env, root_section)
119
120 ! if we have been asked to randomize the variables, we do this.
121 IF (oi_env%randomize_variables .NE. 0.0_dp) THEN
122 seed = real(oi_env%seed, kind=dp)
123 rng_stream = rng_stream_type("run_optimize_input", distribution_type=uniform, seed=seed)
124 DO i_var = 1, SIZE(oi_env%variables, 1)
125 IF (.NOT. oi_env%variables(i_var)%fixed) THEN
126 ! change with a random percentage the variable
127 random_number = rng_stream%next()
128 oi_env%variables(i_var)%value = oi_env%variables(i_var)%value* &
129 (1.0_dp + (2*random_number - 1.0_dp)*oi_env%randomize_variables/100.0_dp)
130 END IF
131 END DO
132 END IF
133
134 ! proceed to actual methods
135 SELECT CASE (oi_env%method)
136 CASE (opt_force_matching)
137 CALL force_matching(oi_env, input_declaration, root_section, para_env)
138 CASE DEFAULT
139 cpabort("")
140 END SELECT
141
142 CALL timestop(handle)
143
144 END SUBROUTINE run_optimize_input
145
146! **************************************************************************************************
147!> \brief optimizes parameters by force/energy matching results against reference values
148!> \param oi_env ...
149!> \param input_declaration ...
150!> \param root_section ...
151!> \param para_env ...
152!> \author Joost VandeVondele
153! **************************************************************************************************
154 SUBROUTINE force_matching(oi_env, input_declaration, root_section, para_env)
155 TYPE(oi_env_type) :: oi_env
156 TYPE(section_type), POINTER :: input_declaration
157 TYPE(section_vals_type), POINTER :: root_section
158 TYPE(mp_para_env_type), POINTER :: para_env
159
160 CHARACTER(len=*), PARAMETER :: routinen = 'force_matching'
161
162 CHARACTER(len=default_path_length) :: input_path, output_path
163 CHARACTER(len=default_string_length), &
164 ALLOCATABLE, DIMENSION(:, :) :: initial_variables
165 INTEGER :: color, energies_unit, handle, history_unit, i_atom, i_el, i_frame, i_free_var, &
166 i_var, ierr, mepos_master, mepos_minion, n_atom, n_el, n_frames, n_free_var, n_groups, &
167 n_var, new_env_id, num_pe_master, output_unit, restart_unit, state
168 INTEGER, ALLOCATABLE, DIMENSION(:) :: free_var_index
169 INTEGER, DIMENSION(:), POINTER :: group_distribution
170 LOGICAL :: should_stop
171 REAL(kind=dp) :: e1, e2, e3, e4, e_pot, energy_weight, &
172 re, rf, shift_mm, shift_qm, t1, t2, &
173 t3, t4, t5
174 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: force, free_vars, pos
175 REAL(kind=dp), DIMENSION(:), POINTER :: energy_traj, energy_traj_read, energy_var
176 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: cell_traj, cell_traj_read, force_traj, &
177 force_traj_read, force_var, pos_traj, &
178 pos_traj_read
179 TYPE(cp_logger_type), POINTER :: logger
180 TYPE(mp_comm_type) :: mpi_comm_master, mpi_comm_minion, &
181 mpi_comm_minion_primus
182 TYPE(opt_state_type) :: ostate
183 TYPE(section_vals_type), POINTER :: oi_section, variable_section
184
185 CALL timeset(routinen, handle)
186
187 logger => cp_get_default_logger()
188 CALL cp_add_iter_level(logger%iter_info, "POWELL_OPT")
189 output_unit = cp_logger_get_default_io_unit(logger)
190
191 IF (output_unit > 0) THEN
192 WRITE (output_unit, '(T2,A)') 'FORCE_MATCHING| good morning....'
193 END IF
194
195 ! do IO of ref traj / frc / cell
196 NULLIFY (cell_traj)
197 NULLIFY (cell_traj_read, force_traj_read, pos_traj_read, energy_traj_read)
198 CALL read_reference_data(oi_env, para_env, force_traj_read, pos_traj_read, energy_traj_read, cell_traj_read)
199 n_atom = SIZE(pos_traj_read, 2)
200
201 ! adjust read data with respect to start/stop/stride
202 IF (oi_env%fm_env%frame_stop < 0) oi_env%fm_env%frame_stop = SIZE(pos_traj_read, 3)
203
204 IF (oi_env%fm_env%frame_count > 0) THEN
205 oi_env%fm_env%frame_stride = (oi_env%fm_env%frame_stop - oi_env%fm_env%frame_start + 1 + &
206 oi_env%fm_env%frame_count - 1)/(oi_env%fm_env%frame_count)
207 END IF
208 n_frames = (oi_env%fm_env%frame_stop - oi_env%fm_env%frame_start + oi_env%fm_env%frame_stride)/oi_env%fm_env%frame_stride
209
210 ALLOCATE (force_traj(3, n_atom, n_frames), pos_traj(3, n_atom, n_frames), energy_traj(n_frames))
211 IF (ASSOCIATED(cell_traj_read)) ALLOCATE (cell_traj(3, 3, n_frames))
212
213 n_frames = 0
214 DO i_frame = oi_env%fm_env%frame_start, oi_env%fm_env%frame_stop, oi_env%fm_env%frame_stride
215 n_frames = n_frames + 1
216 force_traj(:, :, n_frames) = force_traj_read(:, :, i_frame)
217 pos_traj(:, :, n_frames) = pos_traj_read(:, :, i_frame)
218 energy_traj(n_frames) = energy_traj_read(i_frame)
219 IF (ASSOCIATED(cell_traj)) cell_traj(:, :, n_frames) = cell_traj_read(:, :, i_frame)
220 END DO
221 DEALLOCATE (force_traj_read, pos_traj_read, energy_traj_read)
222 IF (ASSOCIATED(cell_traj_read)) DEALLOCATE (cell_traj_read)
223
224 n_el = 3*n_atom
225 ALLOCATE (pos(n_el), force(n_el))
226 ALLOCATE (energy_var(n_frames), force_var(3, n_atom, n_frames))
227
228 ! split the para_env in a set of sub_para_envs that will do the force_env communications
229 mpi_comm_master = para_env
230 num_pe_master = para_env%num_pe
231 mepos_master = para_env%mepos
232 ALLOCATE (group_distribution(0:num_pe_master - 1))
233 IF (oi_env%fm_env%group_size > para_env%num_pe) oi_env%fm_env%group_size = para_env%num_pe
234
235 CALL mpi_comm_minion%from_split(mpi_comm_master, n_groups, group_distribution, subgroup_min_size=oi_env%fm_env%group_size)
236 mepos_minion = mpi_comm_minion%mepos
237 color = 0
238 IF (mepos_minion == 0) color = 1
239 CALL mpi_comm_minion_primus%from_split(mpi_comm_master, color)
240
241 ! assign initial variables
242 n_var = SIZE(oi_env%variables, 1)
243 ALLOCATE (initial_variables(2, n_var))
244 n_free_var = 0
245 DO i_var = 1, n_var
246 initial_variables(1, i_var) = oi_env%variables(i_var)%label
247 WRITE (initial_variables(2, i_var), *) oi_env%variables(i_var)%value
248 IF (.NOT. oi_env%variables(i_var)%fixed) n_free_var = n_free_var + 1
249 END DO
250 ALLOCATE (free_vars(n_free_var), free_var_index(n_free_var))
251 i_free_var = 0
252 DO i_var = 1, n_var
253 IF (.NOT. oi_env%variables(i_var)%fixed) THEN
254 i_free_var = i_free_var + 1
255 free_var_index(i_free_var) = i_var
256 free_vars(i_free_var) = oi_env%variables(free_var_index(i_free_var))%value
257 END IF
258 END DO
259
260 ! create input and output file names.
261 input_path = oi_env%fm_env%optimize_file_name
262 WRITE (output_path, '(A,I0,A)') trim(oi_env%project_name)//"-worker-", group_distribution(mepos_master), ".out"
263
264 ! initialize the powell optimizer
265 energy_weight = oi_env%fm_env%energy_weight
266 shift_mm = oi_env%fm_env%shift_mm
267 shift_qm = oi_env%fm_env%shift_qm
268
269 IF (para_env%is_source()) THEN
270 ostate%nf = 0
271 ostate%nvar = n_free_var
272 ostate%rhoend = oi_env%rhoend
273 ostate%rhobeg = oi_env%rhobeg
274 ostate%maxfun = oi_env%maxfun
275 ostate%iprint = 1
276 ostate%unit = output_unit
277 ostate%state = 0
278 END IF
279
280 IF (output_unit > 0) THEN
281 WRITE (output_unit, '(T2,A,T60,I20)') 'FORCE_MATCHING| number of atoms per frame ', n_atom
282 WRITE (output_unit, '(T2,A,T60,I20)') 'FORCE_MATCHING| number of frames ', n_frames
283 WRITE (output_unit, '(T2,A,T60,I20)') 'FORCE_MATCHING| number of parallel groups ', n_groups
284 WRITE (output_unit, '(T2,A,T60,I20)') 'FORCE_MATCHING| number of variables ', n_var
285 WRITE (output_unit, '(T2,A,T60,I20)') 'FORCE_MATCHING| number of free variables ', n_free_var
286 WRITE (output_unit, '(T2,A,A)') 'FORCE_MATCHING| optimize file name ', trim(input_path)
287 WRITE (output_unit, '(T2,A,T60,F20.12)') 'FORCE_MATCHING| accuracy', ostate%rhoend
288 WRITE (output_unit, '(T2,A,T60,F20.12)') 'FORCE_MATCHING| step size', ostate%rhobeg
289 WRITE (output_unit, '(T2,A,T60,I20)') 'FORCE_MATCHING| max function evaluation', ostate%maxfun
290 WRITE (output_unit, '(T2,A,T60,L20)') 'FORCE_MATCHING| shift average', oi_env%fm_env%shift_average
291 WRITE (output_unit, '(T2,A)') 'FORCE_MATCHING| initial values:'
292 DO i_var = 1, n_var
293 WRITE (output_unit, '(T2,A,1X,E28.16)') trim(oi_env%variables(i_var)%label), oi_env%variables(i_var)%value
294 END DO
295 WRITE (output_unit, '(T2,A)') 'FORCE_MATCHING| switching to POWELL optimization of the free parameters'
296 WRITE (output_unit, '()')
297 WRITE (output_unit, '(T2,A20,A20,A11,A11)') 'iteration number', 'function value', 'time', 'time Force'
298 CALL m_flush(output_unit)
299 END IF
300
301 t1 = m_walltime()
302
303 DO
304
305 ! globalize the state
306 IF (para_env%is_source()) state = ostate%state
307 CALL para_env%bcast(state)
308
309 ! if required get the energy of this set of params
310 IF (state == 2) THEN
311
312 CALL cp_iterate(logger%iter_info, last=.false.)
313
314 ! create a new force env, updating the free vars as needed
315 DO i_free_var = 1, n_free_var
316 WRITE (initial_variables(2, free_var_index(i_free_var)), *) free_vars(i_free_var)
317 oi_env%variables(free_var_index(i_free_var))%value = free_vars(i_free_var)
318 END DO
319
320 ierr = 0
321 CALL create_force_env(new_env_id=new_env_id, input_declaration=input_declaration, &
322 input_path=input_path, output_path=output_path, &
323 mpi_comm=mpi_comm_minion, initial_variables=initial_variables, ierr=ierr)
324
325 ! set to zero initialy, for easier mp_summing
326 energy_var = 0.0_dp
327 force_var = 0.0_dp
328
329 ! compute energies and forces for all frames, doing the work on a minion sub group based on round robin
330 t5 = 0.0_dp
331 DO i_frame = group_distribution(mepos_master) + 1, n_frames, n_groups
332
333 ! set new cell if needed
334 IF (ASSOCIATED(cell_traj)) THEN
335 CALL set_cell(env_id=new_env_id, new_cell=cell_traj(:, :, i_frame), ierr=ierr)
336 END IF
337
338 ! copy pos from ref
339 i_el = 0
340 DO i_atom = 1, n_atom
341 pos(i_el + 1) = pos_traj(1, i_atom, i_frame)
342 pos(i_el + 2) = pos_traj(2, i_atom, i_frame)
343 pos(i_el + 3) = pos_traj(3, i_atom, i_frame)
344 i_el = i_el + 3
345 END DO
346
347 ! evaluate energy/force with new pos
348 t3 = m_walltime()
349 CALL calc_force(env_id=new_env_id, pos=pos, n_el_pos=n_el, e_pot=e_pot, force=force, n_el_force=n_el, ierr=ierr)
350 t4 = m_walltime()
351 t5 = t5 + t4 - t3
352
353 ! copy force and energy in place
354 energy_var(i_frame) = e_pot
355 i_el = 0
356 DO i_atom = 1, n_atom
357 force_var(1, i_atom, i_frame) = force(i_el + 1)
358 force_var(2, i_atom, i_frame) = force(i_el + 2)
359 force_var(3, i_atom, i_frame) = force(i_el + 3)
360 i_el = i_el + 3
361 END DO
362
363 END DO
364
365 ! clean up force env, get ready for the next round
366 CALL destroy_force_env(env_id=new_env_id, ierr=ierr)
367
368 ! get data everywhere on the master group, we could reduce the amount of data by reducing to partial RMSD first
369 ! furthermore, we should only do this operation among the masters of the minion group
370 IF (mepos_minion == 0) THEN
371 CALL mpi_comm_minion_primus%sum(energy_var)
372 CALL mpi_comm_minion_primus%sum(force_var)
373 END IF
374
375 ! now evaluate the target function to be minimized (only valid on mepos_minion==0)
376 IF (para_env%is_source()) THEN
377 rf = sqrt(sum((force_var - force_traj)**2)/(real(n_frames, kind=dp)*real(n_atom, kind=dp)))
378 IF (oi_env%fm_env%shift_average) THEN
379 shift_mm = sum(energy_var)/n_frames
380 shift_qm = sum(energy_traj)/n_frames
381 END IF
382 re = sqrt(sum(((energy_var - shift_mm) - (energy_traj - shift_qm))**2)/n_frames)
383 ostate%f = energy_weight*re + rf
384 t2 = m_walltime()
385 WRITE (output_unit, '(T2,I20,F20.12,F11.3,F11.3)') oi_env%iter_start_val + ostate%nf, ostate%f, t2 - t1, t5
386 CALL m_flush(output_unit)
387 t1 = m_walltime()
388 END IF
389
390 ! the history file with the trajectory of the parameters
391 history_unit = cp_print_key_unit_nr(logger, root_section, "OPTIMIZE_INPUT%HISTORY", &
392 extension=".dat")
393 IF (history_unit > 0) THEN
394 WRITE (unit=history_unit, fmt="(I20,F20.12,1000F20.12)") oi_env%iter_start_val + ostate%nf, ostate%f, free_vars
395 END IF
396 CALL cp_print_key_finished_output(history_unit, logger, root_section, "OPTIMIZE_INPUT%HISTORY")
397
398 ! the energy profile for all frames
399 energies_unit = cp_print_key_unit_nr(logger, root_section, "OPTIMIZE_INPUT%FORCE_MATCHING%COMPARE_ENERGIES", &
400 file_position="REWIND", extension=".dat")
401 IF (energies_unit > 0) THEN
402 WRITE (unit=energies_unit, fmt="(A20,A20,A20,A20)") "#frame", "ref", "fit", "diff"
403 DO i_frame = 1, n_frames
404 e1 = energy_traj(i_frame) - shift_qm
405 e2 = energy_var(i_frame) - shift_mm
406 WRITE (unit=energies_unit, fmt="(I20,F20.12,F20.12,F20.12)") i_frame, e1, e2, e1 - e2
407 END DO
408 END IF
409 CALL cp_print_key_finished_output(energies_unit, logger, root_section, "OPTIMIZE_INPUT%FORCE_MATCHING%COMPARE_ENERGIES")
410
411 ! the force profile for all frames
412 energies_unit = cp_print_key_unit_nr(logger, root_section, "OPTIMIZE_INPUT%FORCE_MATCHING%COMPARE_FORCES", &
413 file_position="REWIND", extension=".dat")
414 IF (energies_unit > 0) THEN
415 WRITE (unit=energies_unit, fmt="(A20,A20,A20,A20)") "#frame", "normalized diff", "diff", "ref", "ref sum"
416 DO i_frame = 1, n_frames
417 e1 = sqrt(sum((force_var(:, :, i_frame) - force_traj(:, :, i_frame))**2))
418 e2 = sqrt(sum((force_traj(:, :, i_frame))**2))
419 e3 = sqrt(sum(sum(force_traj(:, :, i_frame), dim=2)**2))
420 e4 = sqrt(sum(sum(force_var(:, :, i_frame), dim=2)**2))
421 WRITE (unit=energies_unit, fmt="(I20,F20.12,F20.12,F20.12,2F20.12)") i_frame, e1/e2, e1, e2, e3, e4
422 END DO
423 END IF
424 CALL cp_print_key_finished_output(energies_unit, logger, root_section, "OPTIMIZE_INPUT%FORCE_MATCHING%COMPARE_FORCES")
425
426 ! a restart file with the current values of the parameters
427 restart_unit = cp_print_key_unit_nr(logger, root_section, "OPTIMIZE_INPUT%RESTART", extension=".restart", &
428 file_position="REWIND", do_backup=.true.)
429 IF (restart_unit > 0) THEN
430 oi_section => section_vals_get_subs_vals(root_section, "OPTIMIZE_INPUT")
431 CALL section_vals_val_set(oi_section, "ITER_START_VAL", i_val=oi_env%iter_start_val + ostate%nf)
432 variable_section => section_vals_get_subs_vals(oi_section, "VARIABLE")
433 DO i_free_var = 1, n_free_var
434 CALL section_vals_val_set(variable_section, "VALUE", i_rep_section=free_var_index(i_free_var), &
435 r_val=free_vars(i_free_var))
436 END DO
437 CALL write_restart_header(restart_unit)
438 CALL section_vals_write(root_section, unit_nr=restart_unit, hide_root=.true.)
439 END IF
440 CALL cp_print_key_finished_output(restart_unit, logger, root_section, "OPTIMIZE_INPUT%RESTART")
441
442 END IF
443
444 IF (state == -1) EXIT
445
446 CALL external_control(should_stop, "OPTIMIZE_INPUT", target_time=oi_env%target_time, start_time=oi_env%start_time)
447
448 IF (should_stop) EXIT
449
450 ! do a powell step if needed
451 IF (para_env%is_source()) THEN
452 CALL powell_optimize(ostate%nvar, free_vars, ostate)
453 END IF
454 CALL para_env%bcast(free_vars)
455
456 END DO
457
458 ! finally, get the best set of variables
459 IF (para_env%is_source()) THEN
460 ostate%state = 8
461 CALL powell_optimize(ostate%nvar, free_vars, ostate)
462 END IF
463 CALL para_env%bcast(free_vars)
464 DO i_free_var = 1, n_free_var
465 WRITE (initial_variables(2, free_var_index(i_free_var)), *) free_vars(i_free_var)
466 oi_env%variables(free_var_index(i_free_var))%value = free_vars(i_free_var)
467 END DO
468 IF (para_env%is_source()) THEN
469 WRITE (output_unit, '(T2,A)') ''
470 WRITE (output_unit, '(T2,A,T60,F20.12)') 'FORCE_MATCHING| optimal function value found so far:', ostate%fopt
471 WRITE (output_unit, '(T2,A)') 'FORCE_MATCHING| optimal variables found so far:'
472 DO i_var = 1, n_var
473 WRITE (output_unit, '(T2,A,1X,E28.16)') trim(oi_env%variables(i_var)%label), oi_env%variables(i_var)%value
474 END DO
475 END IF
476
477 CALL cp_rm_iter_level(logger%iter_info, "POWELL_OPT")
478
479 ! deallocate for cleanup
480 IF (ASSOCIATED(cell_traj)) DEALLOCATE (cell_traj)
481 DEALLOCATE (pos, force, force_traj, pos_traj, force_var)
482 DEALLOCATE (group_distribution, energy_traj, energy_var)
483 CALL mpi_comm_minion%free()
484 CALL mpi_comm_minion_primus%free()
485
486 CALL timestop(handle)
487
488 END SUBROUTINE force_matching
489
490! **************************************************************************************************
491!> \brief reads the reference data for force matching results, the format of the files needs to be the CP2K xyz trajectory format
492!> \param oi_env ...
493!> \param para_env ...
494!> \param force_traj forces
495!> \param pos_traj position
496!> \param energy_traj energies, as extracted from the forces file
497!> \param cell_traj cell parameters, as extracted from a CP2K cell file
498!> \author Joost VandeVondele
499! **************************************************************************************************
500 SUBROUTINE read_reference_data(oi_env, para_env, force_traj, pos_traj, energy_traj, cell_traj)
501 TYPE(oi_env_type) :: oi_env
502 TYPE(mp_para_env_type), POINTER :: para_env
503 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: force_traj, pos_traj
504 REAL(kind=dp), DIMENSION(:), POINTER :: energy_traj
505 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: cell_traj
506
507 CHARACTER(len=*), PARAMETER :: routinen = 'read_reference_data'
508
509 CHARACTER(len=default_path_length) :: filename
510 CHARACTER(len=default_string_length) :: aa
511 INTEGER :: cell_itimes, handle, i, iframe, &
512 n_frames, n_frames_current, nread, &
513 trj_itimes
514 LOGICAL :: at_end, test_ok
515 REAL(kind=dp) :: cell_time, trj_epot, trj_time, vec(3), &
516 vol
517 TYPE(cp_parser_type) :: local_parser
518
519 CALL timeset(routinen, handle)
520
521 ! do IO of ref traj / frc / cell
522
523 ! trajectory
524 n_frames = 0
525 n_frames_current = 0
526 NULLIFY (pos_traj, energy_traj, force_traj)
527 filename = oi_env%fm_env%ref_traj_file_name
528 IF (filename .EQ. "") &
529 cpabort("The reference trajectory file name is empty")
530 CALL parser_create(local_parser, filename, para_env=para_env)
531 DO
532 CALL parser_read_line(local_parser, 1, at_end=at_end)
533 IF (at_end) EXIT
534 READ (local_parser%input_line, fmt="(I8)") nread
535 n_frames = n_frames + 1
536
537 IF (n_frames > n_frames_current) THEN
538 n_frames_current = 5*(n_frames_current + 10)/3
539 CALL reallocate(pos_traj, 1, 3, 1, nread, 1, n_frames_current)
540 END IF
541
542 ! title line
543 CALL parser_read_line(local_parser, 1)
544
545 ! actual coordinates
546 DO i = 1, nread
547 CALL parser_read_line(local_parser, 1)
548 READ (local_parser%input_line(1:len_trim(local_parser%input_line)), *) aa, vec
549 pos_traj(:, i, n_frames) = vec*bohr
550 END DO
551
552 END DO
553 CALL parser_release(local_parser)
554
555 n_frames_current = n_frames
556 CALL reallocate(energy_traj, 1, n_frames_current)
557 CALL reallocate(force_traj, 1, 3, 1, nread, 1, n_frames_current)
558 CALL reallocate(pos_traj, 1, 3, 1, nread, 1, n_frames_current)
559
560 ! now force reference trajectory
561 filename = oi_env%fm_env%ref_force_file_name
562 IF (filename .EQ. "") &
563 cpabort("The reference force file name is empty")
564 CALL parser_create(local_parser, filename, para_env=para_env)
565 DO iframe = 1, n_frames
566 CALL parser_read_line(local_parser, 1)
567 READ (local_parser%input_line, fmt="(I8)") nread
568
569 ! title line
570 test_ok = .false.
571 CALL parser_read_line(local_parser, 1)
572 READ (local_parser%input_line, fmt="(T6,I8,T23,F12.3,T41,F20.10)", err=999) trj_itimes, trj_time, trj_epot
573 test_ok = .true.
574999 CONTINUE
575 IF (.NOT. test_ok) THEN
576 cpabort("Could not parse the title line of the trajectory file")
577 END IF
578 energy_traj(iframe) = trj_epot
579
580 ! actual forces, in a.u.
581 DO i = 1, nread
582 CALL parser_read_line(local_parser, 1)
583 READ (local_parser%input_line(1:len_trim(local_parser%input_line)), *) aa, vec
584 force_traj(:, i, iframe) = vec
585 END DO
586 END DO
587 CALL parser_release(local_parser)
588
589 ! and cell, which is optional
590 NULLIFY (cell_traj)
591 filename = oi_env%fm_env%ref_cell_file_name
592 IF (filename .NE. "") THEN
593 CALL parser_create(local_parser, filename, para_env=para_env)
594 ALLOCATE (cell_traj(3, 3, n_frames))
595 DO iframe = 1, n_frames
596 CALL parser_read_line(local_parser, 1)
597 CALL parse_cell_line(local_parser%input_line, cell_itimes, cell_time, cell_traj(:, :, iframe), vol)
598 END DO
599 CALL parser_release(local_parser)
600 END IF
601
602 CALL timestop(handle)
603
604 END SUBROUTINE read_reference_data
605
606! **************************************************************************************************
607!> \brief parses the input section, and stores in the optimize input environment
608!> \param oi_env optimize input environment
609!> \param root_section ...
610!> \author Joost VandeVondele
611! **************************************************************************************************
612 SUBROUTINE parse_input(oi_env, root_section)
613 TYPE(oi_env_type) :: oi_env
614 TYPE(section_vals_type), POINTER :: root_section
615
616 CHARACTER(len=*), PARAMETER :: routinen = 'parse_input'
617
618 INTEGER :: handle, ivar, n_var
619 LOGICAL :: explicit
620 TYPE(section_vals_type), POINTER :: fm_section, oi_section, variable_section
621
622 CALL timeset(routinen, handle)
623
624 CALL section_vals_val_get(root_section, "GLOBAL%PROJECT", c_val=oi_env%project_name)
625 CALL section_vals_val_get(root_section, "GLOBAL%SEED", i_val=oi_env%seed)
626 CALL cp2k_get_walltime(section=root_section, keyword_name="GLOBAL%WALLTIME", &
627 walltime=oi_env%target_time)
628
629 oi_section => section_vals_get_subs_vals(root_section, "OPTIMIZE_INPUT")
630 variable_section => section_vals_get_subs_vals(oi_section, "VARIABLE")
631
632 CALL section_vals_val_get(oi_section, "ACCURACY", r_val=oi_env%rhoend)
633 CALL section_vals_val_get(oi_section, "STEP_SIZE", r_val=oi_env%rhobeg)
634 CALL section_vals_val_get(oi_section, "MAX_FUN", i_val=oi_env%maxfun)
635 CALL section_vals_val_get(oi_section, "ITER_START_VAL", i_val=oi_env%iter_start_val)
636 CALL section_vals_val_get(oi_section, "RANDOMIZE_VARIABLES", r_val=oi_env%randomize_variables)
637
638 CALL section_vals_get(variable_section, explicit=explicit, n_repetition=n_var)
639 IF (explicit) THEN
640 ALLOCATE (oi_env%variables(1:n_var))
641 DO ivar = 1, n_var
642 CALL section_vals_val_get(variable_section, "VALUE", i_rep_section=ivar, &
643 r_val=oi_env%variables(ivar)%value)
644 CALL section_vals_val_get(variable_section, "FIXED", i_rep_section=ivar, &
645 l_val=oi_env%variables(ivar)%fixed)
646 CALL section_vals_val_get(variable_section, "LABEL", i_rep_section=ivar, &
647 c_val=oi_env%variables(ivar)%label)
648 END DO
649 END IF
650
651 CALL section_vals_val_get(oi_section, "METHOD", i_val=oi_env%method)
652 SELECT CASE (oi_env%method)
653 CASE (opt_force_matching)
654 fm_section => section_vals_get_subs_vals(oi_section, "FORCE_MATCHING")
655 CALL section_vals_val_get(fm_section, "REF_TRAJ_FILE_NAME", c_val=oi_env%fm_env%ref_traj_file_name)
656 CALL section_vals_val_get(fm_section, "REF_FORCE_FILE_NAME", c_val=oi_env%fm_env%ref_force_file_name)
657 CALL section_vals_val_get(fm_section, "REF_CELL_FILE_NAME", c_val=oi_env%fm_env%ref_cell_file_name)
658 CALL section_vals_val_get(fm_section, "OPTIMIZE_FILE_NAME", c_val=oi_env%fm_env%optimize_file_name)
659 CALL section_vals_val_get(fm_section, "FRAME_START", i_val=oi_env%fm_env%frame_start)
660 CALL section_vals_val_get(fm_section, "FRAME_STOP", i_val=oi_env%fm_env%frame_stop)
661 CALL section_vals_val_get(fm_section, "FRAME_STRIDE", i_val=oi_env%fm_env%frame_stride)
662 CALL section_vals_val_get(fm_section, "FRAME_COUNT", i_val=oi_env%fm_env%frame_count)
663
664 CALL section_vals_val_get(fm_section, "GROUP_SIZE", i_val=oi_env%fm_env%group_size)
665
666 CALL section_vals_val_get(fm_section, "ENERGY_WEIGHT", r_val=oi_env%fm_env%energy_weight)
667 CALL section_vals_val_get(fm_section, "SHIFT_MM", r_val=oi_env%fm_env%shift_mm)
668 CALL section_vals_val_get(fm_section, "SHIFT_QM", r_val=oi_env%fm_env%shift_qm)
669 CALL section_vals_val_get(fm_section, "SHIFT_AVERAGE", l_val=oi_env%fm_env%shift_average)
670 CASE DEFAULT
671 cpabort("")
672 END SELECT
673
674 CALL timestop(handle)
675
676 END SUBROUTINE parse_input
677
678END MODULE optimize_input
Handles all functions related to the CELL.
Definition cell_types.F:15
subroutine, public parse_cell_line(input_line, cell_itimes, cell_time, h, vol)
Read cell info from a line (parsed from a file)
Definition cell_types.F:156
some minimal info about CP2K, including its version and license
Definition cp2k_info.F:16
subroutine, public write_restart_header(iunit)
Writes the header for the restart file.
Definition cp2k_info.F:334
Routines to handle the external control of CP2K.
subroutine, public external_control(should_stop, flag, globenv, target_time, start_time, force_check)
External manipulations during a run : when the <PROJECT_NAME>.EXIT_$runtype command is sent the progr...
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
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,...
subroutine, public cp_iterate(iteration_info, last, iter_nr, increment, iter_nr_out)
adds one to the actual iteration
subroutine, public cp_rm_iter_level(iteration_info, level_name, n_rlevel_att)
Removes an iteration level.
subroutine, public cp_add_iter_level(iteration_info, level_name, n_rlevel_new)
Adds an iteration level.
Utility routines to read data from files. Kept as close as possible to the old parser because.
subroutine, public parser_read_line(parser, nline, at_end)
Read the next line from a logical unit "unit" (I/O node only). Skip (nline-1) lines and skip also all...
Utility routines to read data from files. Kept as close as possible to the old parser because.
subroutine, public parser_release(parser)
releases the parser
subroutine, public parser_create(parser, file_name, unit_nr, para_env, end_section_label, separator_chars, comment_char, continuation_char, quote_char, section_char, parse_white_lines, initial_variables, apply_preprocessing)
Start a parser run. Initial variables allow to @SET stuff before opening the file.
Sets up and terminates the global environment variables.
Definition environment.F:17
subroutine, public cp2k_get_walltime(section, keyword_name, walltime)
reads the Walltime also in format HH:MM:SS
interface to use cp2k as library
recursive subroutine, public destroy_force_env(env_id, ierr, q_finalize)
deallocates the force_env with the given id
recursive subroutine, public create_force_env(new_env_id, input_declaration, input_path, output_path, mpi_comm, output_unit, owns_out_unit, input, ierr, work_dir, initial_variables)
creates a new force environment using the given input, and writing the output to the given output uni...
subroutine, public set_cell(env_id, new_cell, ierr)
sets a new cell
recursive subroutine, public calc_force(env_id, pos, n_el_pos, e_pot, force, n_el_force, ierr)
returns the energy of the configuration given by the positions passed as argument
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public opt_force_matching
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_val_set(section_vals, keyword_name, i_rep_section, i_rep_val, val, l_val, i_val, r_val, c_val, l_vals_ptr, i_vals_ptr, r_vals_ptr, c_vals_ptr)
sets the requested value
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
recursive subroutine, public section_vals_write(section_vals, unit_nr, hide_root, hide_defaults)
writes the values in the given section in a way that is suitable to the automatic parsing
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
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
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:106
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:123
Utility routines for the memory handling.
Interface to the message passing library MPI.
subroutine, public run_optimize_input(input_declaration, root_section, para_env)
main entry point for methods aimed at optimizing parameters in a CP2K input file
Parallel (pseudo)random number generator (RNG) for multiple streams and substreams of random numbers.
integer, parameter, public uniform
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public bohr
Definition physcon.F:147
Definition powell.F:9
subroutine, public powell_optimize(n, x, optstate)
...
Definition powell.F:55
type of a logger, at the moment it contains just a print level starting at which level it should be l...
represent a section of the input file
stores all the informations relevant to an mpi environment