38#include "../base/base_uses.f90"
43 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'glbopt_mincrawl'
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
108 INTEGER,
INTENT(IN) :: n_workers, iw
112 REAL(kind=
dp) :: temp_in_kelvin
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))
170 CHARACTER(len=default_string_length) :: status
172 TYPE(minima_type),
POINTER :: best_minima
177 IF (trim(status) ==
"initial_hello")
THEN
178 this%workers(wid)%tempstep = this%tempstep_init
181 CALL swarm_message_add(cmd,
"temperature", tempstep2temp(this, this%workers(wid)%tempstep))
185 IF (trim(status) ==
"ok")
THEN
186 CALL mincrawl_register_minima(this, report)
189 IF (.false.)
CALL print_tempdist(best_minima)
191 best_minima => choose_promising_minima(this)
193 IF (.NOT.
ASSOCIATED(best_minima))
THEN
199 best_minima%n_active = best_minima%n_active + 1
200 best_minima%n_sampled = best_minima%n_sampled + 1
201 this%workers(wid)%start_minima => best_minima
202 this%workers(wid)%tempstep = choose_tempstep(this, best_minima)
206 CALL swarm_message_add(cmd,
"temperature", tempstep2temp(this, this%workers(wid)%tempstep))
209 IF (this%iw > 0)
THEN
210 WRITE (this%iw,
'(1X,A,T71,I10)') &
211 "MINCRAWL| Total number of found minima", this%n_minima
212 WRITE (this%iw,
'(1X,A,T71,I10)') &
213 "MINCRAWL| Sampling minima with id", best_minima%id
214 WRITE (this%iw,
'(1X,A,I10,A,A,T71,F10.3)') &
215 "MINCRAWL| Temperature (step ", this%workers(wid)%tempstep,
" ) ", &
216 "[Kelvin]",
kelvin*tempstep2temp(this, this%workers(wid)%tempstep)
227 FUNCTION choose_promising_minima(this)
RESULT(minima)
229 TYPE(minima_type),
POINTER :: minima
232 REAL(kind=
dp) :: score, score_best
234 score_best = huge(1.0)
237 DO i = 1, this%n_minima
238 IF (this%minimas(i)%p%disabled) cycle
239 IF (this%minimas(i)%p%n_active > this%worker_per_min) cycle
240 score = minima_score(this%minimas(i)%p)
242 IF (score < score_best)
THEN
244 minima => this%minimas(i)%p
247 END FUNCTION choose_promising_minima
255 FUNCTION minima_score(minima)
RESULT(res)
256 TYPE(minima_type),
POINTER :: minima
259 res = sum(minima%escape_hist)/
SIZE(minima%escape_hist)
260 END FUNCTION minima_score
269 FUNCTION choose_tempstep(this, minima)
RESULT(step)
271 TYPE(minima_type),
POINTER :: minima
274 REAL(kind=
dp) :: a, r
277 r = this%rng_stream%next()
278 step = int(r*
SIZE(minima%tempdist)) + 1
279 a = 1.0 - 2.0*abs(minima%tempdist(step) - 0.5)
280 r = this%rng_stream%next()
284 END FUNCTION choose_tempstep
291 SUBROUTINE print_tempdist(minima)
292 TYPE(minima_type),
POINTER :: minima
298 DO i = 1,
SIZE(minima%tempdist)
299 WRITE (*, *)
"tempstep: ", i, minima%tempdist(i)
301 END SUBROUTINE print_tempdist
310 FUNCTION tempstep2temp(this, step)
RESULT(temp_in_au)
313 REAL(kind=
dp) :: temp_in_au
315 temp_in_au = (this%tempstep_base**step)/
kelvin
316 END FUNCTION tempstep2temp
325 FUNCTION temp2tempstep(this, temp_in_au)
RESULT(step)
327 REAL(kind=
dp) :: temp_in_au
330 step = int(log(temp_in_au*
kelvin)/log(this%tempstep_base))
333 IF (step > this%tempstep_max) cpabort(
"temp2tempstep: step > tempstep_max")
334 END FUNCTION temp2tempstep
343 SUBROUTINE mincrawl_register_minima(this, report)
347 INTEGER :: new_mid, tempstep, wid
348 LOGICAL :: minima_known
349 REAL(kind=
dp) :: report_epot
350 REAL(kind=
dp),
DIMENSION(:),
POINTER :: report_positions
352 TYPE(minima_p_type),
ALLOCATABLE,
DIMENSION(:) :: minimas_tmp
353 TYPE(minima_type),
POINTER :: new_minima, start_minima
355 NULLIFY (start_minima, new_minima, report_positions)
362 start_minima => this%workers(wid)%start_minima
363 tempstep = this%workers(wid)%tempstep
368 IF (
ASSOCIATED(start_minima))
THEN
369 start_minima%n_active = start_minima%n_active - 1
370 IF (start_minima%n_active < 0) cpabort(
"negative n_active")
373 IF (minima_known)
THEN
374 CALL update_tempdist(this, start_minima%tempdist, tempstep, -1)
376 CALL update_tempdist(this, start_minima%tempdist, tempstep, +1)
377 start_minima%escape_hist(:) = eoshift(start_minima%escape_hist, 1)
378 start_minima%escape_hist(1) = report_epot
383 IF (.NOT. minima_known)
THEN
384 this%n_minima = this%n_minima + 1
385 IF (this%n_minima >
SIZE(this%minimas))
THEN
386 ALLOCATE (minimas_tmp(
SIZE(this%minimas)))
387 minimas_tmp(:) = this%minimas
388 DEALLOCATE (this%minimas)
389 ALLOCATE (this%minimas(
SIZE(minimas_tmp) + 1000))
390 this%minimas(:
SIZE(minimas_tmp)) = minimas_tmp
391 DEALLOCATE (minimas_tmp)
394 new_mid = this%n_minima
395 ALLOCATE (this%minimas(new_mid)%p)
396 new_minima => this%minimas(new_mid)%p
397 new_minima%id = new_mid
398 ALLOCATE (new_minima%escape_hist(this%esc_hist_len))
399 ALLOCATE (new_minima%tempdist(this%tempstep_max))
401 new_minima%escape_hist(:) = report_epot
403 IF (
ASSOCIATED(start_minima))
THEN
404 new_minima%tempdist(:) = start_minima%tempdist
406 new_minima%tempdist(:) = this%tempdist_init
409 new_minima%Epot = report_epot
410 new_minima%fp = report_fp
411 ALLOCATE (new_minima%pos(
SIZE(report_positions)))
412 new_minima%pos(:) = report_positions
414 IF (
ASSOCIATED(start_minima))
THEN
415 IF (report_epot < start_minima%Epot)
THEN
416 start_minima%disabled = .true.
417 IF (this%iw > 0)
WRITE (this%iw,
'(1X,A,T71,I10)') &
418 "MINCRAWL| Disabling minimum with id", start_minima%id
422 IF (this%iw > 0)
WRITE (this%iw,
'(1X,A,T71,I10)') &
423 "MINCRAWL| Adding new minima with id", new_mid
425 CALL history_add(this%history, report_fp, id=new_mid)
426 CALL write_minima_traj(this, wid, new_mid, report_epot, report_positions)
428 DEALLOCATE (report_positions)
429 END SUBROUTINE mincrawl_register_minima
440 SUBROUTINE update_tempdist(this, tempdist, center, direction)
442 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: tempdist
443 INTEGER :: center, direction
447 DO i = 1,
SIZE(tempdist)
448 tempdist(i) = tempdist(i) + this%tempdist_update_height &
449 *real(direction, kind=
dp)*exp(-((center - i)/this%tempdist_update_width)**2)
450 tempdist(i) = max(0.0_dp, min(1.0_dp, tempdist(i)))
452 END SUBROUTINE update_tempdist
463 SUBROUTINE write_minima_traj(this, worker_id, minimum_id, Epot, positions)
465 INTEGER,
INTENT(IN) :: worker_id, minimum_id
466 REAL(kind=
dp),
INTENT(IN) :: epot
467 REAL(kind=
dp),
DIMENSION(:),
POINTER :: positions
469 CHARACTER(len=default_string_length) :: title, unit_str
470 REAL(kind=
dp) :: unit_conv
472 IF (this%minima_traj_unit <= 0)
RETURN
474 WRITE (title,
'(A,I8,A,I5,A,F20.10)')
'minimum_id = ', minimum_id, &
475 ' worker_id = ', worker_id,
' Epot = ', epot
483 iunit=this%minima_traj_unit, &
489 END SUBROUTINE write_minima_traj
504 DO i = 1, this%n_minima
506 DEALLOCATE (this%minimas(i)%p)
511 this%mincrawl_section,
"MINIMA_TRAJECTORY")
Adds an entry from a swarm-message.
Returns an entry from a swarm-message.
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.
type(history_fingerprint_type) function, public history_fingerprint(epot, pos)
Calculates a fingerprint for a given configuration.
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...
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.
type of a logger, at the moment it contains just a print level starting at which level it should be l...