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 Perform a molecular dynamics (MD) run using QUICKSTEP
10 : !> \par History
11 : !> - Added support for Langevin regions (2014/02/05, LT)
12 : !> \author Matthias Krack (07.11.2002)
13 : ! **************************************************************************************************
14 : MODULE md_run
15 : USE atomic_kind_list_types, ONLY: atomic_kind_list_type
16 : USE averages_types, ONLY: average_quantities_type
17 : USE barostat_types, ONLY: barostat_type,&
18 : create_barostat_type
19 : USE cell_types, ONLY: cell_type
20 : USE cp_external_control, ONLY: external_control
21 : USE cp_log_handling, ONLY: cp_get_default_logger,&
22 : cp_logger_get_default_io_unit,&
23 : cp_logger_type
24 : USE cp_output_handling, ONLY: cp_add_iter_level,&
25 : cp_iterate,&
26 : cp_p_file,&
27 : cp_print_key_finished_output,&
28 : cp_print_key_should_output,&
29 : cp_print_key_unit_nr,&
30 : cp_rm_iter_level
31 : USE cp_subsys_types, ONLY: cp_subsys_get,&
32 : cp_subsys_type
33 : USE distribution_1d_types, ONLY: distribution_1d_type
34 : USE force_env_methods, ONLY: force_env_calc_energy_force
35 : USE force_env_types, ONLY: force_env_get,&
36 : force_env_type
37 : USE free_energy_methods, ONLY: free_energy_evaluate
38 : USE free_energy_types, ONLY: fe_env_create,&
39 : free_energy_type
40 : USE global_types, ONLY: global_environment_type
41 : USE hfx_ace_methods, ONLY: hfx_ace_set_dynamic_mode
42 : USE input_constants, ONLY: &
43 : ehrenfest, langevin_ensemble, npe_f_ensemble, npe_i_ensemble, &
44 : nph_uniaxial_damped_ensemble, nph_uniaxial_ensemble, npt_f_ensemble, npt_i_ensemble, &
45 : npt_ia_ensemble, reftraj_ensemble
46 : USE input_cp2k_check, ONLY: remove_restart_info
47 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
48 : section_vals_remove_values,&
49 : section_vals_type,&
50 : section_vals_val_get
51 : USE kinds, ONLY: default_string_length,&
52 : dp
53 : USE machine, ONLY: m_flush,&
54 : m_walltime
55 : USE md_ener_types, ONLY: create_md_ener,&
56 : md_ener_type
57 : USE md_energies, ONLY: initialize_md_ener,&
58 : md_ener_reftraj,&
59 : md_energy,&
60 : md_write_output
61 : USE md_environment_types, ONLY: get_md_env,&
62 : md_env_create,&
63 : md_env_release,&
64 : md_environment_type,&
65 : need_per_atom_wiener_process,&
66 : set_md_env
67 : USE md_util, ONLY: md_output,&
68 : update_expected_temperature
69 : USE md_vel_utils, ONLY: angvel_control,&
70 : comvel_control,&
71 : setup_velocities,&
72 : temperature_control
73 : USE mdctrl_methods, ONLY: mdctrl_callback
74 : USE mdctrl_types, ONLY: mdctrl_type
75 : USE message_passing, ONLY: mp_para_env_type
76 : USE metadynamics, ONLY: metadyn_finalise_plumed,&
77 : metadyn_forces,&
78 : metadyn_initialise_plumed,&
79 : metadyn_write_colvar
80 : USE metadynamics_types, ONLY: set_meta_env
81 : USE particle_list_types, ONLY: particle_list_type
82 : USE qs_environment_methods, ONLY: qs_env_time_update
83 : USE reftraj_types, ONLY: create_reftraj,&
84 : reftraj_type
85 : USE reftraj_util, ONLY: initialize_reftraj,&
86 : write_output_reftraj
87 : USE rt_propagation, ONLY: rt_prop_setup
88 : USE simpar_methods, ONLY: read_md_section
89 : USE simpar_types, ONLY: create_simpar_type,&
90 : release_simpar_type,&
91 : simpar_type
92 : USE thermal_region_types, ONLY: thermal_regions_type
93 : USE thermal_region_utils, ONLY: create_thermal_regions,&
94 : print_thermal_regions_langevin
95 : USE thermostat_methods, ONLY: create_thermostats
96 : USE thermostat_types, ONLY: thermostats_type
97 : USE velocity_verlet_control, ONLY: velocity_verlet
98 : USE virial_methods, ONLY: virial_evaluate
99 : USE virial_types, ONLY: virial_type
100 : USE wiener_process, ONLY: create_wiener_process,&
101 : create_wiener_process_cv
102 : #include "../base/base_uses.f90"
103 :
104 : IMPLICIT NONE
105 :
106 : PRIVATE
107 :
108 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'md_run'
109 :
110 : PUBLIC :: qs_mol_dyn
111 :
112 : CONTAINS
113 :
114 : ! **************************************************************************************************
115 : !> \brief Main driver module for Molecular Dynamics
116 : !> \param force_env ...
117 : !> \param globenv ...
118 : !> \param averages ...
119 : !> \param rm_restart_info ...
120 : !> \param hmc_e_initial ...
121 : !> \param hmc_e_final ...
122 : !> \param mdctrl ...
123 : ! **************************************************************************************************
124 3540 : SUBROUTINE qs_mol_dyn(force_env, globenv, averages, rm_restart_info, hmc_e_initial, hmc_e_final, mdctrl)
125 :
126 : TYPE(force_env_type), POINTER :: force_env
127 : TYPE(global_environment_type), POINTER :: globenv
128 : TYPE(average_quantities_type), OPTIONAL, POINTER :: averages
129 : LOGICAL, INTENT(IN), OPTIONAL :: rm_restart_info
130 : REAL(KIND=dp), OPTIONAL :: hmc_e_initial, hmc_e_final
131 : TYPE(mdctrl_type), OPTIONAL, POINTER :: mdctrl
132 :
133 : LOGICAL :: my_rm_restart_info
134 : TYPE(md_environment_type), POINTER :: md_env
135 : TYPE(mp_para_env_type), POINTER :: para_env
136 : TYPE(section_vals_type), POINTER :: md_section, motion_section
137 :
138 1770 : my_rm_restart_info = .TRUE.
139 1770 : IF (PRESENT(rm_restart_info)) my_rm_restart_info = rm_restart_info
140 1770 : NULLIFY (md_env, para_env)
141 :
142 : ! Tell ACE that this is a dynamic run: Bypass C will use full HFX
143 : ! for the entire first MD step so wavefunction propagation delivers
144 : ! a near-converged C_occ to step 1, making the ACE BUILD accurate.
145 1770 : CALL hfx_ace_set_dynamic_mode(.TRUE.)
146 :
147 1770 : para_env => force_env%para_env
148 1770 : motion_section => section_vals_get_subs_vals(force_env%root_section, "MOTION")
149 1770 : md_section => section_vals_get_subs_vals(motion_section, "MD")
150 :
151 : ! Real call to MD driver - Low Level
152 1770 : ALLOCATE (md_env)
153 1770 : CALL md_env_create(md_env, md_section, para_env, force_env=force_env)
154 1770 : CALL set_md_env(md_env, averages=averages)
155 1770 : IF (PRESENT(hmc_e_initial) .AND. PRESENT(hmc_e_final)) THEN
156 : CALL qs_mol_dyn_low(md_env, md_section, motion_section, force_env, globenv, &
157 28 : hmc_e_initial=hmc_e_initial, hmc_e_final=hmc_e_final)
158 : ELSE
159 1742 : CALL qs_mol_dyn_low(md_env, md_section, motion_section, force_env, globenv, mdctrl=mdctrl)
160 : END IF
161 1770 : CALL md_env_release(md_env)
162 1770 : DEALLOCATE (md_env)
163 :
164 : ! Clean restartable sections..
165 1770 : IF (my_rm_restart_info) CALL remove_restart_info(force_env%root_section)
166 1770 : END SUBROUTINE qs_mol_dyn
167 :
168 : ! **************************************************************************************************
169 : !> \brief Purpose: Driver routine for MD run using QUICKSTEP.
170 : !> \param md_env ...
171 : !> \param md_section ...
172 : !> \param motion_section ...
173 : !> \param force_env ...
174 : !> \param globenv ...
175 : !> \param hmc_e_initial ...
176 : !> \param hmc_e_final ...
177 : !> \param mdctrl ...
178 : !> \par History
179 : !> - Cleaning (09.2007) Teodoro Laino [tlaino] - University of Zurich
180 : !> - Added lines to print out langevin regions (2014/02/04, LT)
181 : !> \author Creation (07.11.2002,MK)
182 : ! **************************************************************************************************
183 8850 : SUBROUTINE qs_mol_dyn_low(md_env, md_section, motion_section, force_env, globenv, hmc_e_initial, hmc_e_final, mdctrl)
184 :
185 : TYPE(md_environment_type), POINTER :: md_env
186 : TYPE(section_vals_type), POINTER :: md_section, motion_section
187 : TYPE(force_env_type), POINTER :: force_env
188 : TYPE(global_environment_type), POINTER :: globenv
189 : REAL(KIND=dp), OPTIONAL :: hmc_e_initial, hmc_e_final
190 : TYPE(mdctrl_type), OPTIONAL, POINTER :: mdctrl
191 :
192 : CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_mol_dyn_low'
193 :
194 : CHARACTER(LEN=80) :: md_step_line
195 : CHARACTER(LEN=default_string_length) :: my_act, my_pos
196 : INTEGER :: handle, i, istep, md_stride, &
197 : output_unit, run_type_id
198 : INTEGER, POINTER :: itimes
199 : LOGICAL :: check, ehrenfest_md, save_mem, &
200 : should_stop, write_binary_restart_file
201 : REAL(KIND=dp) :: dummy, time_iter_start, time_iter_stop
202 : REAL(KIND=dp), POINTER :: constant, time, used_time
203 : TYPE(atomic_kind_list_type), POINTER :: atomic_kinds
204 : TYPE(barostat_type), POINTER :: barostat
205 : TYPE(cell_type), POINTER :: cell
206 : TYPE(cp_logger_type), POINTER :: logger
207 : TYPE(cp_subsys_type), POINTER :: subsys, subsys_i
208 : TYPE(distribution_1d_type), POINTER :: local_particles
209 : TYPE(free_energy_type), POINTER :: fe_env
210 : TYPE(md_ener_type), POINTER :: md_ener
211 : TYPE(mp_para_env_type), POINTER :: para_env
212 : TYPE(particle_list_type), POINTER :: particles
213 : TYPE(reftraj_type), POINTER :: reftraj
214 : TYPE(section_vals_type), POINTER :: constraint_section, force_env_section, &
215 : free_energy_section, global_section, reftraj_section, subsys_section, work_section
216 : TYPE(simpar_type), POINTER :: simpar
217 : TYPE(thermal_regions_type), POINTER :: thermal_regions
218 : TYPE(thermostats_type), POINTER :: thermostats
219 : TYPE(virial_type), POINTER :: virial
220 :
221 1770 : CALL timeset(routineN, handle)
222 1770 : CPASSERT(ASSOCIATED(globenv))
223 1770 : CPASSERT(ASSOCIATED(force_env))
224 :
225 1770 : NULLIFY (particles, cell, simpar, itimes, used_time, subsys, &
226 1770 : md_ener, thermostats, barostat, reftraj, force_env_section, &
227 1770 : reftraj_section, work_section, atomic_kinds, &
228 1770 : local_particles, time, fe_env, free_energy_section, &
229 1770 : constraint_section, thermal_regions, virial, subsys_i)
230 1770 : logger => cp_get_default_logger()
231 1770 : para_env => force_env%para_env
232 1770 : output_unit = cp_logger_get_default_io_unit(logger)
233 :
234 1770 : global_section => section_vals_get_subs_vals(force_env%root_section, "GLOBAL")
235 1770 : free_energy_section => section_vals_get_subs_vals(motion_section, "FREE_ENERGY")
236 1770 : constraint_section => section_vals_get_subs_vals(motion_section, "CONSTRAINT")
237 1770 : CALL section_vals_val_get(global_section, "SAVE_MEM", l_val=save_mem)
238 :
239 1770 : CALL section_vals_val_get(global_section, "RUN_TYPE", i_val=run_type_id)
240 1770 : IF (run_type_id == ehrenfest) CALL set_md_env(md_env, ehrenfest_md=.TRUE.)
241 :
242 1770 : CALL create_simpar_type(simpar)
243 1770 : force_env_section => force_env%force_env_section
244 1770 : subsys_section => section_vals_get_subs_vals(force_env_section, "SUBSYS")
245 1770 : CALL cp_add_iter_level(logger%iter_info, "MD")
246 1770 : CALL cp_iterate(logger%iter_info, iter_nr=0)
247 : ! Read MD section
248 1770 : CALL read_md_section(simpar, motion_section, md_section)
249 : ! Setup print_keys
250 : simpar%info_constraint = cp_print_key_unit_nr(logger, constraint_section, &
251 1770 : "CONSTRAINT_INFO", extension=".shakeLog", log_filename=.FALSE.)
252 : simpar%lagrange_multipliers = cp_print_key_unit_nr(logger, constraint_section, &
253 1770 : "LAGRANGE_MULTIPLIERS", extension=".LagrangeMultLog", log_filename=.FALSE.)
254 : simpar%dump_lm = BTEST(cp_print_key_should_output(logger%iter_info, constraint_section, &
255 1770 : "LAGRANGE_MULTIPLIERS"), cp_p_file)
256 :
257 : ! Create the structure for the md energies
258 7080 : ALLOCATE (md_ener)
259 1770 : CALL create_md_ener(md_ener)
260 1770 : CALL set_md_env(md_env, md_ener=md_ener)
261 1770 : NULLIFY (md_ener)
262 :
263 : ! If requested setup Thermostats
264 : CALL create_thermostats(thermostats, md_section, force_env, simpar, para_env, &
265 1770 : globenv, global_section)
266 :
267 : ! If requested setup Barostat
268 1770 : CALL create_barostat_type(barostat, md_section, force_env, simpar, globenv)
269 :
270 : ! If requested setup different thermal regions
271 1770 : CALL create_thermal_regions(thermal_regions, md_section, simpar, force_env)
272 :
273 : ! If doing langevin_ensemble, then print out langevin_regions information upon request
274 1770 : IF (simpar%ensemble == langevin_ensemble) THEN
275 42 : my_pos = "REWIND"
276 42 : my_act = "WRITE"
277 : CALL print_thermal_regions_langevin(thermal_regions, simpar, &
278 42 : pos=my_pos, act=my_act)
279 : END IF
280 :
281 1770 : CALL set_md_env(md_env, thermostats=thermostats, barostat=barostat, thermal_regions=thermal_regions)
282 :
283 1770 : CALL get_md_env(md_env, ehrenfest_md=ehrenfest_md)
284 :
285 : !If requested set up the REFTRAJ run
286 1770 : IF (simpar%ensemble == reftraj_ensemble .AND. ehrenfest_md) THEN
287 0 : CPABORT("Ehrenfest MD does not support reftraj ensemble ")
288 : END IF
289 1770 : IF (simpar%ensemble == reftraj_ensemble) THEN
290 36 : reftraj_section => section_vals_get_subs_vals(md_section, "REFTRAJ")
291 36 : ALLOCATE (reftraj)
292 36 : CALL create_reftraj(reftraj, reftraj_section, para_env)
293 36 : CALL set_md_env(md_env, reftraj=reftraj)
294 : END IF
295 :
296 : CALL force_env_get(force_env, subsys=subsys, cell=cell, &
297 1770 : force_env_section=force_env_section)
298 1770 : CALL cp_subsys_get(subsys, virial=virial)
299 :
300 : ! Set V0 if needed
301 1770 : IF (simpar%ensemble == nph_uniaxial_ensemble .OR. simpar%ensemble == nph_uniaxial_damped_ensemble) THEN
302 6 : IF (simpar%v0 == 0._dp) simpar%v0 = cell%deth
303 : END IF
304 :
305 : ! Initialize velocities possibly applying constraints at the zeroth MD step
306 : CALL section_vals_val_get(motion_section, "PRINT%RESTART%SPLIT_RESTART_FILE", &
307 1770 : l_val=write_binary_restart_file)
308 : CALL setup_velocities(force_env, simpar, globenv, md_env, md_section, constraint_section, &
309 1770 : write_binary_restart_file)
310 :
311 : ! Setup Free Energy Calculation (if required)
312 1770 : CALL fe_env_create(fe_env, free_energy_section)
313 :
314 : CALL set_md_env(md_env=md_env, simpar=simpar, fe_env=fe_env, cell=cell, &
315 1770 : force_env=force_env)
316 :
317 : ! Possibly initialize Wiener processes
318 : ![NB] Tested again within create_wiener_process. Why??
319 1770 : IF (need_per_atom_wiener_process(md_env)) CALL create_wiener_process(md_env)
320 :
321 1770 : time_iter_start = m_walltime()
322 :
323 : CALL get_md_env(md_env, force_env=force_env, itimes=itimes, constant=constant, &
324 1770 : md_ener=md_ener, t=time, used_time=used_time)
325 :
326 : ! Attach the time counter of the meta_env to the one of the MD
327 1770 : CALL set_meta_env(force_env%meta_env, time=time)
328 :
329 : ! Initialize the md_ener structure
330 1770 : CALL initialize_md_ener(md_ener, force_env, simpar)
331 :
332 : ! Check for ensembles requiring the stress tensor - takes into account the possibility for
333 : ! multiple force_evals
334 : IF ((simpar%ensemble == npt_i_ensemble) .OR. &
335 : (simpar%ensemble == npt_ia_ensemble) .OR. &
336 : (simpar%ensemble == npt_f_ensemble) .OR. &
337 : (simpar%ensemble == npe_f_ensemble) .OR. &
338 : (simpar%ensemble == npe_i_ensemble) .OR. &
339 1770 : (simpar%ensemble == nph_uniaxial_ensemble) .OR. &
340 : (simpar%ensemble == nph_uniaxial_damped_ensemble)) THEN
341 174 : check = virial%pv_availability
342 174 : IF (.NOT. check) THEN
343 : CALL cp_abort(__LOCATION__, &
344 : "Virial evaluation not requested for this run in the input file!"// &
345 : " You may consider to switch on the virial evaluation with the keyword: STRESS_TENSOR."// &
346 0 : " Be sure the method you are using can compute the virial!")
347 : END IF
348 174 : IF (ASSOCIATED(force_env%sub_force_env)) THEN
349 26 : DO i = 1, SIZE(force_env%sub_force_env)
350 26 : IF (ASSOCIATED(force_env%sub_force_env(i)%force_env)) THEN
351 10 : CALL force_env_get(force_env%sub_force_env(i)%force_env, subsys=subsys_i)
352 10 : CALL cp_subsys_get(subsys_i, virial=virial)
353 10 : check = check .AND. virial%pv_availability
354 : END IF
355 : END DO
356 : END IF
357 174 : IF (.NOT. check) THEN
358 : CALL cp_abort(__LOCATION__, &
359 : "Virial evaluation not requested for all the force_eval sections present in"// &
360 : " the input file! You have to switch on the virial evaluation with the keyword: STRESS_TENSOR"// &
361 0 : " in each force_eval section. Be sure the method you are using can compute the virial!")
362 : END IF
363 : END IF
364 :
365 : ! Computing Forces at zero MD step
366 1770 : IF (simpar%ensemble /= reftraj_ensemble) THEN
367 1734 : CALL section_vals_val_get(md_section, "STEP_START_VAL", i_val=itimes)
368 1734 : CALL section_vals_val_get(md_section, "TIME_START_VAL", r_val=time)
369 1734 : CALL section_vals_val_get(md_section, "ECONS_START_VAL", r_val=constant)
370 1734 : CALL cp_iterate(logger%iter_info, iter_nr=itimes)
371 1734 : IF (save_mem) THEN
372 2 : work_section => section_vals_get_subs_vals(subsys_section, "VELOCITY")
373 2 : CALL section_vals_remove_values(work_section)
374 2 : work_section => section_vals_get_subs_vals(subsys_section, "SHELL_VELOCITY")
375 2 : CALL section_vals_remove_values(work_section)
376 2 : work_section => section_vals_get_subs_vals(subsys_section, "CORE_VELOCITY")
377 2 : CALL section_vals_remove_values(work_section)
378 : END IF
379 :
380 1734 : IF (ehrenfest_md) THEN
381 74 : CALL rt_prop_setup(force_env)
382 74 : force_env%qs_env%rtp%dt = simpar%dt
383 : ELSE
384 : ![NB] Lets let all methods, even ones without consistent energies, succeed here.
385 : ! They'll fail in actual integrator if needed
386 : ! consistent_energies=.FALSE. by default
387 1660 : CALL force_env_calc_energy_force(force_env, calc_force=.TRUE.)
388 : END IF
389 :
390 1734 : IF (ASSOCIATED(force_env%qs_env)) THEN
391 612 : CALL qs_env_time_update(force_env%qs_env, time, itimes)
392 : END IF
393 : ! Warm-up engines for metadynamics
394 1734 : IF (ASSOCIATED(force_env%meta_env)) THEN
395 : ! Setup stuff for plumed if needed
396 148 : IF (force_env%meta_env%use_plumed .EQV. .TRUE.) THEN
397 2 : CALL metadyn_initialise_plumed(force_env, simpar, itimes)
398 : ELSE
399 146 : IF (force_env%meta_env%langevin) THEN
400 4 : CALL create_wiener_process_cv(force_env%meta_env)
401 : END IF
402 146 : IF (force_env%meta_env%well_tempered) THEN
403 2 : force_env%meta_env%wttemperature = simpar%temp_ext
404 2 : IF (force_env%meta_env%wtgamma > EPSILON(1._dp)) THEN
405 0 : dummy = force_env%meta_env%wttemperature*(force_env%meta_env%wtgamma - 1._dp)
406 0 : IF (force_env%meta_env%delta_t > EPSILON(1._dp)) THEN
407 0 : check = ABS(force_env%meta_env%delta_t - dummy) < 1.E+3_dp*EPSILON(1._dp)
408 0 : IF (.NOT. check) THEN
409 : CALL cp_abort(__LOCATION__, &
410 : "Inconsistency between DELTA_T and WTGAMMA (both specified):"// &
411 0 : " please, verify that DELTA_T=(WTGAMMA-1)*TEMPERATURE")
412 : END IF
413 : ELSE
414 0 : force_env%meta_env%delta_t = dummy
415 : END IF
416 : ELSE
417 : force_env%meta_env%wtgamma = 1._dp &
418 2 : + force_env%meta_env%delta_t/force_env%meta_env%wttemperature
419 : END IF
420 2 : force_env%meta_env%invdt = 1._dp/force_env%meta_env%delta_t
421 : END IF
422 146 : CALL metadyn_forces(force_env)
423 146 : CALL metadyn_write_colvar(force_env)
424 : END IF
425 : END IF
426 :
427 1734 : IF (simpar%do_respa) THEN
428 : CALL force_env_calc_energy_force(force_env%sub_force_env(1)%force_env, &
429 6 : calc_force=.TRUE.)
430 : END IF
431 :
432 1734 : CALL force_env_get(force_env, subsys=subsys)
433 :
434 : CALL cp_subsys_get(subsys, atomic_kinds=atomic_kinds, local_particles=local_particles, &
435 1734 : particles=particles, virial=virial)
436 :
437 : CALL virial_evaluate(atomic_kinds%els, particles%els, local_particles, &
438 1734 : virial, force_env%para_env)
439 :
440 1734 : CALL md_energy(md_env, md_ener)
441 1734 : CALL md_write_output(md_env) !inits the print env at itimes == 0 also writes trajectories
442 1734 : md_stride = 1
443 : ELSE
444 36 : CALL get_md_env(md_env, reftraj=reftraj)
445 36 : CALL initialize_reftraj(reftraj, reftraj_section, md_env)
446 36 : itimes = reftraj%info%first_snapshot - 1
447 36 : md_stride = reftraj%info%stride
448 36 : IF (ASSOCIATED(force_env%meta_env)) THEN
449 4 : IF (force_env%meta_env%use_plumed .EQV. .TRUE.) THEN
450 0 : CALL metadyn_initialise_plumed(force_env, simpar, itimes)
451 : END IF
452 : END IF
453 : END IF
454 :
455 : CALL cp_print_key_finished_output(simpar%info_constraint, logger, &
456 1770 : constraint_section, "CONSTRAINT_INFO")
457 : CALL cp_print_key_finished_output(simpar%lagrange_multipliers, logger, &
458 1770 : constraint_section, "LAGRANGE_MULTIPLIERS")
459 :
460 : ! if we need the initial kinetic energy for Hybrid Monte Carlo
461 1770 : IF (PRESENT(hmc_e_initial)) hmc_e_initial = md_ener%ekin
462 :
463 1770 : IF (itimes >= simpar%max_steps) CALL cp_abort(__LOCATION__, &
464 0 : "maximum step number smaller than initial step value")
465 :
466 : ! Real MD Loop
467 42695 : DO istep = 1, simpar%nsteps, md_stride
468 40959 : IF (output_unit > 0) THEN
469 22289 : WRITE (md_step_line, FMT="(A,I12,A,I0)") "MD STEP: ", istep, " / ", simpar%nsteps
470 :
471 622567 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") REPEAT("-", LEN_TRIM(md_step_line))
472 22289 : WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(md_step_line)
473 622567 : WRITE (UNIT=output_unit, FMT="(T2,A)") REPEAT("-", LEN_TRIM(md_step_line))
474 22289 : CALL m_flush(output_unit)
475 : END IF
476 : ! Increase counters
477 40959 : itimes = itimes + 1
478 40959 : time = time + simpar%dt
479 : !needed when electric field fields are applied
480 40959 : IF (ASSOCIATED(force_env%qs_env)) THEN
481 3282 : CALL qs_env_time_update(force_env%qs_env, time, itimes)
482 : END IF
483 40959 : IF (ehrenfest_md) force_env%qs_env%rtp%istep = istep
484 :
485 40959 : IF (.NOT. logger%iter_info%last_iter(logger%iter_info%n_rlevel)) THEN
486 40959 : CALL cp_iterate(logger%iter_info, last=(istep == simpar%nsteps), iter_nr=itimes)
487 : ELSE
488 0 : CALL cp_iterate(logger%iter_info, last=.TRUE., iter_nr=itimes)
489 : END IF
490 :
491 : ! Open possible Shake output units
492 : simpar%info_constraint = cp_print_key_unit_nr(logger, constraint_section, "CONSTRAINT_INFO", &
493 40959 : extension=".shakeLog", log_filename=.FALSE.)
494 : simpar%lagrange_multipliers = cp_print_key_unit_nr( &
495 : logger, constraint_section, &
496 40959 : "LAGRANGE_MULTIPLIERS", extension=".LagrangeMultLog", log_filename=.FALSE.)
497 : simpar%dump_lm = BTEST(cp_print_key_should_output(logger%iter_info, constraint_section, &
498 40959 : "LAGRANGE_MULTIPLIERS"), cp_p_file)
499 :
500 : ! Update temperature for thermal regions and thermostat regions
501 40959 : CALL update_expected_temperature(md_env)
502 :
503 : ! Velocity Verlet Integrator
504 40959 : CALL velocity_verlet(md_env, globenv)
505 :
506 : ! Close Shake output if requested...
507 : CALL cp_print_key_finished_output(simpar%info_constraint, logger, &
508 40959 : constraint_section, "CONSTRAINT_INFO")
509 : CALL cp_print_key_finished_output(simpar%lagrange_multipliers, logger, &
510 40959 : constraint_section, "LAGRANGE_MULTIPLIERS")
511 :
512 : ! Free Energy calculation
513 40959 : CALL free_energy_evaluate(md_env, should_stop, free_energy_section)
514 :
515 40959 : IF (should_stop) EXIT
516 :
517 : ! Test for <PROJECT_NAME>.EXIT_MD or for WALL_TIME to exit
518 : ! Default:
519 : ! IF so we don't overwrite the restart or append to the trajectory
520 : ! because the execution could in principle stop inside the SCF where energy
521 : ! and forces are not converged.
522 : ! But:
523 : ! You can force to print the last step (for example if the method used
524 : ! to compute energy and forces is not SCF based) activating the print_key
525 : ! MOTION%MD%PRINT%FORCE_LAST.
526 40959 : CALL external_control(should_stop, "MD", globenv=globenv)
527 :
528 : !check if upper bound of total steps has been reached
529 40959 : IF (.NOT. (istep == simpar%nsteps) .AND. logger%iter_info%last_iter(logger%iter_info%n_rlevel)) should_stop = .TRUE.
530 40959 : IF (itimes >= simpar%max_steps) should_stop = .TRUE.
531 :
532 : ! call external hook e.g. from global optimization
533 40959 : IF (PRESENT(mdctrl)) THEN
534 3059 : CALL mdctrl_callback(mdctrl, md_env, should_stop)
535 : END IF
536 :
537 40959 : IF (should_stop) THEN
538 34 : CALL cp_iterate(logger%iter_info, last=.TRUE., iter_nr=itimes)
539 : !In Ehrenfest molecular dynamics the external control is only checked after a converged propagation
540 : !The restart needs to be written in order to be consistent with the mos/density matrix for the restart
541 34 : IF (run_type_id == ehrenfest) THEN
542 2 : CALL md_output(md_env, md_section, force_env%root_section, .FALSE.)
543 : ELSE
544 32 : CALL md_output(md_env, md_section, force_env%root_section, should_stop)
545 : END IF
546 : EXIT
547 : END IF
548 :
549 40925 : IF (simpar%ensemble /= reftraj_ensemble) THEN
550 40643 : CALL md_energy(md_env, md_ener)
551 40643 : CALL temperature_control(simpar, md_env, md_ener, force_env, logger)
552 40643 : CALL comvel_control(md_ener, force_env, md_section, logger)
553 40643 : CALL angvel_control(md_ener, force_env, md_section, logger)
554 : ELSE
555 282 : CALL md_ener_reftraj(md_env, md_ener)
556 : END IF
557 :
558 40925 : time_iter_stop = m_walltime()
559 40925 : used_time = time_iter_stop - time_iter_start
560 40925 : time_iter_start = time_iter_stop
561 :
562 40925 : CALL md_output(md_env, md_section, force_env%root_section, should_stop)
563 124579 : IF (simpar%ensemble == reftraj_ensemble) THEN
564 282 : CALL write_output_reftraj(md_env)
565 : END IF
566 : END DO
567 :
568 : ! if we need the final kinetic energy for Hybrid Monte Carlo
569 1770 : IF (PRESENT(hmc_e_final)) hmc_e_final = md_ener%ekin
570 :
571 : ! Remove the iteration level
572 1770 : CALL cp_rm_iter_level(logger%iter_info, "MD")
573 :
574 : ! Clean up PLUMED
575 1770 : IF (ASSOCIATED(force_env%meta_env)) THEN
576 152 : IF (force_env%meta_env%use_plumed .EQV. .TRUE.) THEN
577 2 : CALL metadyn_finalise_plumed()
578 : END IF
579 : END IF
580 :
581 : ! Deallocate Thermostats and Barostats
582 1770 : CALL release_simpar_type(simpar)
583 1770 : CALL timestop(handle)
584 :
585 1770 : END SUBROUTINE qs_mol_dyn_low
586 :
587 : END MODULE md_run
|