21 history_fingerprint_type,&
38 #include "../base/base_uses.f90"
43 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'glbopt_mincrawl'
45 PUBLIC :: mincrawl_type
51 REAL(KIND=
dp),
DIMENSION(:),
ALLOCATABLE :: pos
52 REAL(KIND=
dp),
DIMENSION(:),
ALLOCATABLE :: escape_hist
53 REAL(KIND=
dp),
DIMENSION(:),
ALLOCATABLE :: tempdist
54 REAL(KIND=
dp) :: epot = -1.0
55 TYPE(history_fingerprint_type) :: fp
56 LOGICAL :: disabled = .false.
57 INTEGER :: n_active = 0
58 INTEGER :: n_sampled = 0
62 TYPE(minima_type),
POINTER :: p => null()
63 END TYPE minima_p_type
65 TYPE worker_state_type
66 TYPE(minima_type),
POINTER :: start_minima => null()
67 INTEGER :: tempstep = 0
69 END TYPE worker_state_type
73 TYPE(history_type) :: history
74 TYPE(worker_state_type),
DIMENSION(:),
ALLOCATABLE :: workers
75 TYPE(minima_p_type),
DIMENSION(:),
ALLOCATABLE :: minimas
76 REAL(KIND=
dp) :: tempstep_base = 0
77 INTEGER :: tempstep_max = 0
78 REAL(KIND=
dp) :: tempdist_init_width = 0
79 REAL(KIND=
dp) :: tempdist_update_width = 0
80 REAL(KIND=
dp) :: tempdist_update_height = 0
81 INTEGER :: esc_hist_len = 0
82 INTEGER :: tempstep_init = 0
83 REAL(KIND=
dp),
DIMENSION(:),
ALLOCATABLE :: tempdist_init
84 INTEGER :: n_minima = 0
85 INTEGER :: n_workers = 0
86 INTEGER :: worker_per_min = 0
88 INTEGER :: minima_traj_unit = 0
89 TYPE(section_vals_type),
POINTER :: mincrawl_section => null()
90 TYPE(rng_stream_type) :: rng_stream
91 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set => null()
92 END TYPE mincrawl_type
106 TYPE(mincrawl_type) :: this
107 TYPE(section_vals_type),
POINTER :: glbopt_section
108 INTEGER,
INTENT(IN) :: n_workers, iw
109 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
112 REAL(kind=
dp) :: temp_in_kelvin
113 TYPE(cp_logger_type),
POINTER :: logger
114 TYPE(section_vals_type),
POINTER :: history_section
116 NULLIFY (logger, history_section)
122 CALL section_vals_val_get(this%mincrawl_section,
"TEMPDIST_INIT_WIDTH", r_val=this%tempdist_init_width)
123 CALL section_vals_val_get(this%mincrawl_section,
"TEMPDIST_UPDATE_WIDTH", r_val=this%tempdist_update_width)
124 CALL section_vals_val_get(this%mincrawl_section,
"TEMPDIST_UPDATE_HEIGHT", r_val=this%tempdist_update_height)
126 this%tempstep_init = temp2tempstep(this, temp_in_kelvin/
kelvin)
127 CALL section_vals_val_get(this%mincrawl_section,
"WORKER_PER_MINIMA", i_val=this%worker_per_min)
128 CALL section_vals_val_get(this%mincrawl_section,
"ESCAPE_HISTORY_LENGTH", i_val=this%esc_hist_len)
133 this%mincrawl_section,
"MINIMA_TRAJECTORY", &
134 middle_name=
"minima", extension=
".xyz", &
135 file_action=
"WRITE", file_position=
"REWIND")
142 ALLOCATE (this%minimas(1000))
144 ALLOCATE (this%workers(n_workers))
145 this%n_workers = n_workers
147 this%particle_set => particle_set
150 ALLOCATE (this%tempdist_init(this%tempstep_max))
151 this%tempdist_init = 0.0
152 DO i = 1, this%tempstep_max
153 this%tempdist_init(i) = 1.0/(1.0 + exp((this%tempstep_init - i)/this%tempdist_init_width))
156 this%rng_stream = rng_stream_type(name=
"mincrawl")
167 TYPE(mincrawl_type) :: this
168 TYPE(swarm_message_type) :: report, cmd
170 CHARACTER(len=default_string_length) :: status
172 TYPE(minima_type),
POINTER :: best_minima
174 CALL swarm_message_get(report,
"status", status)
175 CALL swarm_message_get(report,
"worker_id", wid)
177 IF (trim(status) ==
"initial_hello")
THEN
178 this%workers(wid)%tempstep = this%tempstep_init
179 CALL swarm_message_add(cmd,
"command",
"md_and_gopt")
180 CALL swarm_message_add(cmd,
"iframe", 1)
181 CALL swarm_message_add(cmd,
"temperature", tempstep2temp(this, this%workers(wid)%tempstep))
185 IF (trim(status) ==
"ok") &
186 CALL mincrawl_register_minima(this, report)
188 IF (.false.)
CALL print_tempdist(best_minima)
190 best_minima => choose_promising_minima(this)
192 IF (.NOT.
ASSOCIATED(best_minima))
THEN
193 CALL swarm_message_add(cmd,
"command",
"wait")
198 best_minima%n_active = best_minima%n_active + 1
199 best_minima%n_sampled = best_minima%n_sampled + 1
200 this%workers(wid)%start_minima => best_minima
201 this%workers(wid)%tempstep = choose_tempstep(this, best_minima)
203 CALL swarm_message_add(cmd,
"command",
"md_and_gopt")
204 CALL swarm_message_add(cmd,
"iframe", this%workers(wid)%iframe)
205 CALL swarm_message_add(cmd,
"temperature", tempstep2temp(this, this%workers(wid)%tempstep))
206 CALL swarm_message_add(cmd,
"positions", best_minima%pos)
208 IF (this%iw > 0)
THEN
209 WRITE (this%iw,
'(1X,A,T71,I10)') &
210 "MINCRAWL| Total number of found minima", this%n_minima
211 WRITE (this%iw,
'(1X,A,T71,I10)') &
212 "MINCRAWL| Sampling minima with id", best_minima%id
213 WRITE (this%iw,
'(1X,A,I10,A,A,T71,F10.3)') &
214 "MINCRAWL| Temperature (step ", this%workers(wid)%tempstep,
" ) ", &
215 "[Kelvin]",
kelvin*tempstep2temp(this, this%workers(wid)%tempstep)
226 FUNCTION choose_promising_minima(this)
RESULT(minima)
227 TYPE(mincrawl_type) :: this
228 TYPE(minima_type),
POINTER :: minima
231 REAL(kind=
dp) :: score, score_best
233 score_best = huge(1.0)
236 DO i = 1, this%n_minima
237 IF (this%minimas(i)%p%disabled) cycle
238 IF (this%minimas(i)%p%n_active > this%worker_per_min) cycle
239 score = minima_score(this%minimas(i)%p)
241 IF (score < score_best)
THEN
243 minima => this%minimas(i)%p
246 END FUNCTION choose_promising_minima
254 FUNCTION minima_score(minima)
RESULT(res)
255 TYPE(minima_type),
POINTER :: minima
258 res = sum(minima%escape_hist)/
SIZE(minima%escape_hist)
259 END FUNCTION minima_score
268 FUNCTION choose_tempstep(this, minima)
RESULT(step)
269 TYPE(mincrawl_type) :: this
270 TYPE(minima_type),
POINTER :: minima
273 REAL(kind=
dp) :: a, r
276 r = this%rng_stream%next()
277 step = int(r*
SIZE(minima%tempdist)) + 1
278 a = 1.0 - 2.0*abs(minima%tempdist(step) - 0.5)
279 r = this%rng_stream%next()
283 END FUNCTION choose_tempstep
290 SUBROUTINE print_tempdist(minima)
291 TYPE(minima_type),
POINTER :: minima
297 DO i = 1,
SIZE(minima%tempdist)
298 WRITE (*, *)
"tempstep: ", i, minima%tempdist(i)
300 END SUBROUTINE print_tempdist
309 FUNCTION tempstep2temp(this, step)
RESULT(temp_in_au)
310 TYPE(mincrawl_type) :: this
312 REAL(kind=
dp) :: temp_in_au
314 temp_in_au = (this%tempstep_base**step)/
kelvin
315 END FUNCTION tempstep2temp
324 FUNCTION temp2tempstep(this, temp_in_au)
RESULT(step)
325 TYPE(mincrawl_type) :: this
326 REAL(kind=
dp) :: temp_in_au
329 step = int(log(temp_in_au*
kelvin)/log(this%tempstep_base))
332 IF (step > this%tempstep_max) cpabort(
"temp2tempstep: step > tempstep_max")
333 END FUNCTION temp2tempstep
342 SUBROUTINE mincrawl_register_minima(this, report)
343 TYPE(mincrawl_type) :: this
344 TYPE(swarm_message_type) :: report
346 INTEGER :: new_mid, tempstep, wid
347 LOGICAL :: minima_known
348 REAL(kind=
dp) :: report_epot
349 REAL(kind=
dp),
DIMENSION(:),
POINTER :: report_positions
350 TYPE(history_fingerprint_type) :: report_fp
351 TYPE(minima_p_type),
ALLOCATABLE,
DIMENSION(:) :: minimas_tmp
352 TYPE(minima_type),
POINTER :: new_minima, start_minima
354 NULLIFY (start_minima, new_minima, report_positions)
356 CALL swarm_message_get(report,
"worker_id", wid)
357 CALL swarm_message_get(report,
"Epot", report_epot)
358 CALL swarm_message_get(report,
"positions", report_positions)
359 CALL swarm_message_get(report,
"iframe", this%workers(wid)%iframe)
361 start_minima => this%workers(wid)%start_minima
362 tempstep = this%workers(wid)%tempstep
367 IF (
ASSOCIATED(start_minima))
THEN
368 start_minima%n_active = start_minima%n_active - 1
369 IF (start_minima%n_active < 0) cpabort(
"negative n_active")
372 IF (minima_known)
THEN
373 CALL update_tempdist(this, start_minima%tempdist, tempstep, -1)
375 CALL update_tempdist(this, start_minima%tempdist, tempstep, +1)
376 start_minima%escape_hist(:) = eoshift(start_minima%escape_hist, 1)
377 start_minima%escape_hist(1) = report_epot
382 IF (.NOT. minima_known)
THEN
383 this%n_minima = this%n_minima + 1
384 IF (this%n_minima >
SIZE(this%minimas))
THEN
385 ALLOCATE (minimas_tmp(
SIZE(this%minimas)))
386 minimas_tmp(:) = this%minimas
387 DEALLOCATE (this%minimas)
388 ALLOCATE (this%minimas(
SIZE(minimas_tmp) + 1000))
389 this%minimas(:
SIZE(minimas_tmp)) = minimas_tmp
390 DEALLOCATE (minimas_tmp)
393 new_mid = this%n_minima
394 ALLOCATE (this%minimas(new_mid)%p)
395 new_minima => this%minimas(new_mid)%p
396 new_minima%id = new_mid
397 ALLOCATE (new_minima%escape_hist(this%esc_hist_len))
398 ALLOCATE (new_minima%tempdist(this%tempstep_max))
400 new_minima%escape_hist(:) = report_epot
402 IF (
ASSOCIATED(start_minima))
THEN
403 new_minima%tempdist(:) = start_minima%tempdist
405 new_minima%tempdist(:) = this%tempdist_init
408 new_minima%Epot = report_epot
409 new_minima%fp = report_fp
410 ALLOCATE (new_minima%pos(
SIZE(report_positions)))
411 new_minima%pos(:) = report_positions
413 IF (
ASSOCIATED(start_minima))
THEN
414 IF (report_epot < start_minima%Epot)
THEN
415 start_minima%disabled = .true.
416 IF (this%iw > 0)
WRITE (this%iw,
'(1X,A,T71,I10)') &
417 "MINCRAWL| Disabling minimum with id", start_minima%id
421 IF (this%iw > 0)
WRITE (this%iw,
'(1X,A,T71,I10)') &
422 "MINCRAWL| Adding new minima with id", new_mid
424 CALL history_add(this%history, report_fp, id=new_mid)
425 CALL write_minima_traj(this, wid, new_mid, report_epot, report_positions)
427 DEALLOCATE (report_positions)
428 END SUBROUTINE mincrawl_register_minima
439 SUBROUTINE update_tempdist(this, tempdist, center, direction)
440 TYPE(mincrawl_type) :: this
441 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: tempdist
442 INTEGER :: center, direction
446 DO i = 1,
SIZE(tempdist)
447 tempdist(i) = tempdist(i) + this%tempdist_update_height &
448 *real(direction, kind=
dp)*exp(-((center - i)/this%tempdist_update_width)**2)
449 tempdist(i) = max(0.0_dp, min(1.0_dp, tempdist(i)))
451 END SUBROUTINE update_tempdist
462 SUBROUTINE write_minima_traj(this, worker_id, minimum_id, Epot, positions)
463 TYPE(mincrawl_type),
INTENT(INOUT) :: this
464 INTEGER,
INTENT(IN) :: worker_id, minimum_id
465 REAL(kind=
dp),
INTENT(IN) :: epot
466 REAL(kind=
dp),
DIMENSION(:),
POINTER :: positions
468 CHARACTER(len=default_string_length) :: title, unit_str
469 REAL(kind=
dp) :: unit_conv
471 IF (this%minima_traj_unit <= 0)
RETURN
473 WRITE (title,
'(A,I8,A,I5,A,F20.10)')
'minimum_id = ', minimum_id, &
474 ' worker_id = ', worker_id,
' Epot = ', epot
482 iunit=this%minima_traj_unit, &
488 END SUBROUTINE write_minima_traj
496 TYPE(mincrawl_type) :: this
499 TYPE(cp_logger_type),
POINTER :: logger
503 DO i = 1, this%n_minima
505 DEALLOCATE (this%minimas(i)%p)
510 this%mincrawl_section,
"MINIMA_TRAJECTORY")
various routines to log and control the output. The idea is that decisions about where to log should ...
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,...
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
History of minima, calculates, stores and compares fingerprints of minima. Used by Minima Hopping and...
subroutine, public history_init(history, history_section, iw)
Initializes a history.
subroutine, public history_lookup(history, fingerprint, found, id)
Checks if a given fingerprints is contained in the history.
subroutine, public history_finalize(history)
Finalizes a history.
subroutine, public history_add(history, fingerprint, id)
Addes a new fingerprints to the history. Optionally, an abitrary id can be stored alongside the finge...
type(history_fingerprint_type) function, public history_fingerprint(Epot, pos)
Calculates a fingerprint for a given configuration.
Routines for the Minima Crawling global optimization scheme.
subroutine, public mincrawl_init(this, glbopt_section, n_workers, iw, particle_set)
Initializes master for Minima Crawling.
subroutine, public mincrawl_finalize(this)
Finalizes master for Minima Crawling.
subroutine, public mincrawl_steer(this, report, cmd)
Central steering routine of Minima Crawling.
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Parallel (pseudo)random number generator (RNG) for multiple streams and substreams of random numbers.
Define methods related to particle_type.
subroutine, public write_particle_coordinates(particle_set, iunit, output_format, content, title, cell, array, unit_conv, charge_occup, charge_beta, charge_extended, print_kind)
Should be able to write a few formats e.g. xmol, and some binary format (dcd) some format can be used...
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public kelvin
Swarm-message, a convenient data-container for with build-in serialization.