42 #include "../base/base_uses.f90"
47 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'glbopt_worker'
51 PUBLIC :: glbopt_worker_type
53 TYPE glbopt_worker_type
57 INTEGER :: f_env_id = -1
58 TYPE(f_env_type),
POINTER :: f_env => null()
59 TYPE(force_env_type),
POINTER :: force_env => null()
60 TYPE(cp_subsys_type),
POINTER :: subsys => null()
61 TYPE(section_vals_type),
POINTER :: root_section => null()
62 TYPE(global_environment_type),
POINTER :: globenv => null()
63 INTEGER :: gopt_max_iter = 0
64 INTEGER :: bump_steps_downwards = 0
65 INTEGER :: bump_steps_upwards = 0
66 INTEGER :: md_bumps_max = 0
67 REAL(KIND=
dp) :: fragmentation_threshold = 0.0_dp
68 INTEGER :: n_atoms = -1
70 END TYPE glbopt_worker_type
86 input_path, worker_id, iw)
87 TYPE(glbopt_worker_type),
INTENT(INOUT) :: worker
88 TYPE(section_type),
POINTER :: input_declaration
89 TYPE(mp_para_env_type),
POINTER :: para_env
90 TYPE(section_vals_type),
POINTER :: root_section
91 CHARACTER(LEN=*),
INTENT(IN) :: input_path
92 INTEGER,
INTENT(in) :: worker_id, iw
95 REAL(kind=
dp) :: dist_in_angstrom
96 TYPE(section_vals_type),
POINTER :: glbopt_section
98 worker%root_section => root_section
104 input_declaration=input_declaration, &
105 input_path=input_path, &
106 input=root_section, &
107 output_unit=worker%iw, &
112 worker%force_env => worker%f_env%force_env
113 CALL force_env_get(worker%force_env, globenv=worker%globenv, subsys=worker%subsys)
117 CALL worker%globenv%gaussian_rng_stream%reset_to_next_substream()
126 CALL section_vals_val_get(glbopt_section,
"BUMP_STEPS_UPWARDS", i_val=worker%bump_steps_upwards)
127 CALL section_vals_val_get(glbopt_section,
"BUMP_STEPS_DOWNWARDS", i_val=worker%bump_steps_downwards)
131 worker%fragmentation_threshold = dist_in_angstrom/
angstrom
142 TYPE(glbopt_worker_type),
INTENT(INOUT) :: worker
143 TYPE(swarm_message_type),
INTENT(IN) :: cmd
144 TYPE(swarm_message_type),
INTENT(INOUT) :: report
146 CHARACTER(len=default_string_length) :: command
148 CALL swarm_message_get(cmd,
"command", command)
149 IF (trim(command) ==
"md_and_gopt")
THEN
150 CALL run_mdgopt(worker, cmd, report)
152 cpabort(
"Worker: received unknown command")
164 SUBROUTINE run_mdgopt(worker, cmd, report)
165 TYPE(glbopt_worker_type),
INTENT(INOUT) :: worker
166 TYPE(swarm_message_type),
INTENT(IN) :: cmd
167 TYPE(swarm_message_type),
INTENT(INOUT) :: report
169 INTEGER :: gopt_steps, iframe, md_steps, &
170 n_fragments, prev_iframe
171 REAL(kind=
dp) :: epot, temperature
172 REAL(kind=
dp),
DIMENSION(:),
POINTER :: positions
173 TYPE(glbopt_mdctrl_data_type),
TARGET :: mdctrl_data
174 TYPE(mdctrl_type),
POINTER :: mdctrl_p
175 TYPE(mdctrl_type),
TARGET :: mdctrl
179 CALL swarm_message_get(cmd,
"temperature", temperature)
180 CALL swarm_message_get(cmd,
"iframe", iframe)
182 CALL swarm_message_get(cmd,
"positions", positions)
187 ALLOCATE (mdctrl_data%epot_history(worker%bump_steps_downwards + worker%bump_steps_upwards + 1))
188 mdctrl_data%epot_history = 0.0
189 mdctrl_data%md_bump_counter = 0
190 mdctrl_data%bump_steps_upwards = worker%bump_steps_upwards
191 mdctrl_data%bump_steps_downwards = worker%bump_steps_downwards
192 mdctrl_data%md_bumps_max = worker%md_bumps_max
193 mdctrl_data%output_unit = worker%iw
194 mdctrl%glbopt => mdctrl_data
209 IF (iframe == 0) iframe = 1
213 IF (worker%iw > 0)
THEN
214 WRITE (worker%iw,
'(A,33X,F20.3)')
' GLBOPT| MD temperature [K]', temperature*
kelvin
215 WRITE (worker%iw,
'(A,29X,I10)')
" GLBOPT| Starting MD at trajectory frame ", iframe
219 CALL qs_mol_dyn(worker%force_env, worker%globenv, mdctrl=mdctrl_p)
221 iframe = mdctrl_data%itimes + 1
222 md_steps = iframe - prev_iframe
223 IF (worker%iw > 0)
WRITE (worker%iw,
'(A,I4,A)')
" GLBOPT| md ended after ", md_steps,
" steps."
226 IF (.NOT.
ASSOCIATED(positions))
ALLOCATE (positions(3*worker%n_atoms))
230 n_fragments = n_fragments + 1
231 IF (fix_fragmentation(positions, worker%fragmentation_threshold))
EXIT
235 IF (n_fragments > 0 .AND. worker%iw > 0) &
236 WRITE (worker%iw,
'(A,13X,I10)')
" GLBOPT| Ran fix_fragmentation times:", n_fragments
239 IF (worker%iw > 0)
WRITE (worker%iw,
'(A,13X,I10)')
" GLBOPT| Starting local optimisation at trajectory frame ", iframe
240 CALL section_vals_val_set(worker%root_section,
"MOTION%GEO_OPT%STEP_START_VAL", i_val=iframe - 1)
242 i_val=iframe + worker%gopt_max_iter)
245 CALL cp_geo_opt(worker%force_env, worker%globenv, rm_restart_info=.false.)
250 gopt_steps = iframe - prev_iframe - 1
251 IF (worker%iw > 0)
WRITE (worker%iw,
'(A,I4,A)')
" GLBOPT| gopt ended after ", gopt_steps,
" steps."
253 IF (worker%iw > 0)
WRITE (worker%iw,
'(A,25X,E20.10)')
' GLBOPT| Potential Energy [Hartree]', epot
256 CALL swarm_message_add(report,
"Epot", epot)
257 CALL swarm_message_add(report,
"iframe", iframe)
258 CALL swarm_message_add(report,
"md_steps", md_steps)
259 CALL swarm_message_add(report,
"gopt_steps", gopt_steps)
261 CALL swarm_message_add(report,
"positions", positions)
263 DEALLOCATE (positions)
264 END SUBROUTINE run_mdgopt
273 FUNCTION fix_fragmentation(positions, bondlength)
RESULT(all_connected)
274 REAL(kind=
dp),
DIMENSION(:) :: positions
275 REAL(kind=
dp) :: bondlength
276 LOGICAL :: all_connected
278 INTEGER :: cluster_edge, fragment_edge, i, j, &
279 n_particles, stack_size
280 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: stack
281 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: marked
282 REAL(kind=
dp) :: d, dr(3), min_dist, s
284 n_particles =
SIZE(positions)/3
285 ALLOCATE (stack(n_particles), marked(n_particles))
287 marked = .false.; stack_size = 0
290 marked(1) = .true.; stack(1) = 1; stack_size = 1
292 DO WHILE (stack_size > 0)
293 i = stack(stack_size); stack_size = stack_size - 1
294 DO j = 1, n_particles
295 IF (norm(diff(positions, i, j)) < 1.25*bondlength)
THEN
296 IF (.NOT. marked(j))
THEN
298 stack(stack_size + 1) = j; stack_size = stack_size + 1;
304 all_connected = all(marked)
305 IF (all_connected)
RETURN
308 IF (count(marked) < n_particles/2) marked(:) = .NOT. (marked(:))
313 DO i = 1, n_particles
315 DO j = 1, n_particles
316 IF (.NOT. marked(j)) cycle
317 d = norm(diff(positions, i, j))
318 IF (d < min_dist)
THEN
326 dr = diff(positions, cluster_edge, fragment_edge)
327 s = 1.0 - bondlength/norm(dr)
328 DO i = 1, n_particles
330 positions(3*i - 2:3*i) = positions(3*i - 2:3*i) - s*dr
333 END FUNCTION fix_fragmentation
343 PURE FUNCTION diff(positions, i, j)
RESULT(dr)
344 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: positions
345 INTEGER,
INTENT(IN) :: i, j
346 REAL(kind=
dp),
DIMENSION(3) :: dr
348 dr = positions(3*i - 2:3*i) - positions(3*j - 2:3*j)
357 PURE FUNCTION norm(vec)
RESULT(res)
358 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: vec
361 res = sqrt(dot_product(vec, vec))
370 TYPE(glbopt_worker_type),
INTENT(INOUT) :: worker
376 IF (ierr /= 0) cpabort(
"destroy_force_env failed")
types that represent a subsys, i.e. a part of the system
subroutine, public unpack_subsys_particles(subsys, f, r, s, v, fscale, cell)
Unpack components of a subsystem particle sets into a single vector.
subroutine, public cp_subsys_get(subsys, ref_count, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell)
returns information about various attributes of the given subsys
subroutine, public pack_subsys_particles(subsys, f, r, s, v, fscale, cell)
Pack components of a subsystem particle sets into a single vector.
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
subroutine, public f_env_add_defaults(f_env_id, f_env, handle)
adds the default environments of the f_env to the stack of the defaults, and returns a new error and ...
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 f_env_rm_defaults(f_env, ierr, handle)
removes the default environments of the f_env to the stack of the defaults, and sets ierr accordingly...
Interface for the force calculations.
recursive subroutine, public force_env_get(force_env, in_use, fist_env, qs_env, meta_env, fp_env, subsys, para_env, potential_energy, additional_potential, kinetic_energy, harmonic_shell, kinetic_shell, cell, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, globenv, input, force_env_section, method_name_id, root_section, mixed_env, nnp_env, embed_env)
returns various attributes about the force environment
performs geometry optimization
subroutine, public cp_geo_opt(force_env, globenv, eval_opt_geo, rm_restart_info)
Main driver to perform geometry optimization.
Worker routines used by global optimization schemes.
subroutine, public glbopt_worker_init(worker, input_declaration, para_env, root_section, input_path, worker_id, iw)
Initializes worker for global optimization.
subroutine, public glbopt_worker_finalize(worker)
Finalizes worker for global optimization.
subroutine, public glbopt_worker_execute(worker, cmd, report)
Central execute routine of global optimization worker.
Define type storing the global information of a run. Keep the amount of stored data small....
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Perform a molecular dynamics (MD) run using QUICKSTEP.
subroutine, public qs_mol_dyn(force_env, globenv, averages, rm_restart_info, hmc_e_initial, hmc_e_final, mdctrl)
Main driver module for Molecular Dynamics.
A common interface for passing a callback into the md_run loop.
Interface to the message passing library MPI.
Definition of physical constants:
real(kind=dp), parameter, public kelvin
real(kind=dp), parameter, public angstrom
Swarm-message, a convenient data-container for with build-in serialization.