(git:34ef472)
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 !--------------------------------------------------------------------------------------------------!
8  USE cell_types, ONLY: parse_cell_line
13  cp_logger_type
15  cp_iterate,&
20  USE cp_parser_types, ONLY: cp_parser_type,&
24  USE f77_interface, ONLY: calc_force,&
27  set_cell
29  USE input_section_types, ONLY: section_type,&
32  section_vals_type,&
36  USE kinds, ONLY: default_path_length,&
38  dp
39  USE machine, ONLY: m_flush,&
41  USE memory_utilities, ONLY: reallocate
42  USE message_passing, ONLY: mp_comm_type,&
43  mp_para_env_type
44  USE parallel_rng_types, ONLY: uniform,&
45  rng_stream_type
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 
93 CONTAINS
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.
574 999 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 
678 END 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:333
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
Definition: environment.F:1166
interface to use cp2k as library
Definition: f77_interface.F:20
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