LCOV - code coverage report
Current view: top level - src/swarm - glbopt_mincrawl.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 92.0 % 162 149
Test Date: 2025-07-25 12:55:17 Functions: 61.1 % 18 11

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Routines for the Minima Crawling global optimization scheme
      10              : !> \author Ole Schuett
      11              : ! **************************************************************************************************
      12              : MODULE glbopt_mincrawl
      13              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      14              :                                               cp_logger_type
      15              :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      16              :                                               cp_print_key_unit_nr
      17              :    USE cp_units,                        ONLY: cp_unit_from_cp2k
      18              :    USE glbopt_history,                  ONLY: history_add,&
      19              :                                               history_finalize,&
      20              :                                               history_fingerprint,&
      21              :                                               history_fingerprint_type,&
      22              :                                               history_init,&
      23              :                                               history_lookup,&
      24              :                                               history_type
      25              :    USE input_constants,                 ONLY: dump_xmol
      26              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      27              :                                               section_vals_type,&
      28              :                                               section_vals_val_get
      29              :    USE kinds,                           ONLY: default_string_length,&
      30              :                                               dp
      31              :    USE parallel_rng_types,              ONLY: rng_stream_type
      32              :    USE particle_methods,                ONLY: write_particle_coordinates
      33              :    USE particle_types,                  ONLY: particle_type
      34              :    USE physcon,                         ONLY: kelvin
      35              :    USE swarm_message,                   ONLY: swarm_message_add,&
      36              :                                               swarm_message_get,&
      37              :                                               swarm_message_type
      38              : #include "../base/base_uses.f90"
      39              : 
      40              :    IMPLICIT NONE
      41              :    PRIVATE
      42              : 
      43              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'glbopt_mincrawl'
      44              : 
      45              :    PUBLIC :: mincrawl_type
      46              :    PUBLIC :: mincrawl_init, mincrawl_finalize
      47              :    PUBLIC :: mincrawl_steer
      48              : 
      49              :    TYPE minima_type
      50              :       INTEGER                                             :: id = -1
      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
      59              :    END TYPE minima_type
      60              : 
      61              :    TYPE minima_p_type
      62              :       TYPE(minima_type), POINTER                          :: p => Null()
      63              :    END TYPE minima_p_type
      64              : 
      65              :    TYPE worker_state_type
      66              :       TYPE(minima_type), POINTER                          :: start_minima => Null()
      67              :       INTEGER                                             :: tempstep = 0
      68              :       INTEGER                                             :: iframe = 1
      69              :    END TYPE worker_state_type
      70              : 
      71              :    TYPE mincrawl_type
      72              :       PRIVATE
      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
      87              :       INTEGER                                             :: iw = 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
      93              : 
      94              : CONTAINS
      95              : 
      96              : ! **************************************************************************************************
      97              : !> \brief Initializes master for Minima Crawling
      98              : !> \param this ...
      99              : !> \param glbopt_section ...
     100              : !> \param n_workers ...
     101              : !> \param iw ...
     102              : !> \param particle_set ...
     103              : !> \author Ole Schuett
     104              : ! **************************************************************************************************
     105            1 :    SUBROUTINE mincrawl_init(this, glbopt_section, n_workers, iw, particle_set)
     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
     110              : 
     111              :       INTEGER                                            :: i
     112              :       REAL(kind=dp)                                      :: temp_in_kelvin
     113              :       TYPE(cp_logger_type), POINTER                      :: logger
     114              :       TYPE(section_vals_type), POINTER                   :: history_section
     115              : 
     116            1 :       NULLIFY (logger, history_section)
     117              : 
     118              :       ! read input
     119            1 :       this%mincrawl_section => section_vals_get_subs_vals(glbopt_section, "MINIMA_CRAWLING")
     120            1 :       CALL section_vals_val_get(this%mincrawl_section, "TEMPSTEP_BASE", r_val=this%tempstep_base)
     121            1 :       CALL section_vals_val_get(this%mincrawl_section, "TEMPSTEP_MAX", i_val=this%tempstep_max)
     122            1 :       CALL section_vals_val_get(this%mincrawl_section, "TEMPDIST_INIT_WIDTH", r_val=this%tempdist_init_width)
     123            1 :       CALL section_vals_val_get(this%mincrawl_section, "TEMPDIST_UPDATE_WIDTH", r_val=this%tempdist_update_width)
     124            1 :       CALL section_vals_val_get(this%mincrawl_section, "TEMPDIST_UPDATE_HEIGHT", r_val=this%tempdist_update_height)
     125            1 :       CALL section_vals_val_get(this%mincrawl_section, "TEMPERATURE_INIT", r_val=temp_in_kelvin)
     126            1 :       this%tempstep_init = temp2tempstep(this, temp_in_kelvin/kelvin)
     127            1 :       CALL section_vals_val_get(this%mincrawl_section, "WORKER_PER_MINIMA", i_val=this%worker_per_min)
     128            1 :       CALL section_vals_val_get(this%mincrawl_section, "ESCAPE_HISTORY_LENGTH", i_val=this%esc_hist_len)
     129              : 
     130              :       !init minima trajectory
     131            1 :       logger => cp_get_default_logger()
     132              :       this%minima_traj_unit = cp_print_key_unit_nr(logger, &
     133              :                                                    this%mincrawl_section, "MINIMA_TRAJECTORY", &
     134              :                                                    middle_name="minima", extension=".xyz", &
     135            1 :                                                    file_action="WRITE", file_position="REWIND")
     136              : 
     137              :       !init history
     138            1 :       history_section => section_vals_get_subs_vals(glbopt_section, "HISTORY")
     139            1 :       CALL history_init(this%history, history_section, iw=iw)
     140              : 
     141              :       !allocate data structures
     142         1001 :       ALLOCATE (this%minimas(1000)) !will be grown if needed
     143              : 
     144            4 :       ALLOCATE (this%workers(n_workers))
     145            1 :       this%n_workers = n_workers
     146            1 :       this%iw = iw
     147            1 :       this%particle_set => particle_set
     148              : 
     149              :       ! call fermi-like stepfunction for initial temp-dist
     150            3 :       ALLOCATE (this%tempdist_init(this%tempstep_max))
     151          101 :       this%tempdist_init = 0.0
     152          101 :       DO i = 1, this%tempstep_max
     153          101 :          this%tempdist_init(i) = 1.0/(1.0 + EXP((this%tempstep_init - i)/this%tempdist_init_width))
     154              :       END DO
     155              : 
     156            1 :       this%rng_stream = rng_stream_type(name="mincrawl")
     157            1 :    END SUBROUTINE mincrawl_init
     158              : 
     159              : ! **************************************************************************************************
     160              : !> \brief Central steering routine of Minima Crawling
     161              : !> \param this ...
     162              : !> \param report ...
     163              : !> \param cmd ...
     164              : !> \author Ole Schuett
     165              : ! **************************************************************************************************
     166           36 :    SUBROUTINE mincrawl_steer(this, report, cmd)
     167              :       TYPE(mincrawl_type)                                :: this
     168              :       TYPE(swarm_message_type)                           :: report, cmd
     169              : 
     170              :       CHARACTER(len=default_string_length)               :: status
     171              :       INTEGER                                            :: wid
     172              :       TYPE(minima_type), POINTER                         :: best_minima
     173              : 
     174           18 :       CALL swarm_message_get(report, "status", status)
     175           18 :       CALL swarm_message_get(report, "worker_id", wid)
     176              : 
     177           18 :       IF (TRIM(status) == "initial_hello") THEN
     178            1 :          this%workers(wid)%tempstep = this%tempstep_init
     179            1 :          CALL swarm_message_add(cmd, "command", "md_and_gopt")
     180            1 :          CALL swarm_message_add(cmd, "iframe", 1)
     181            1 :          CALL swarm_message_add(cmd, "temperature", tempstep2temp(this, this%workers(wid)%tempstep))
     182            1 :          RETURN
     183              :       END IF
     184              : 
     185           17 :       IF (TRIM(status) == "ok") &
     186           17 :          CALL mincrawl_register_minima(this, report)
     187              : 
     188              :       IF (.FALSE.) CALL print_tempdist(best_minima)
     189              : 
     190           17 :       best_minima => choose_promising_minima(this)
     191              : 
     192           17 :       IF (.NOT. ASSOCIATED(best_minima)) THEN ! no suitable minima found
     193            0 :          CALL swarm_message_add(cmd, "command", "wait")
     194              :          !WRITE(this%iw,*) " MINCRAWL| Waiting until new minima become available"
     195            0 :          RETURN
     196              :       END IF
     197              : 
     198           17 :       best_minima%n_active = best_minima%n_active + 1
     199           17 :       best_minima%n_sampled = best_minima%n_sampled + 1
     200           17 :       this%workers(wid)%start_minima => best_minima
     201           17 :       this%workers(wid)%tempstep = choose_tempstep(this, best_minima)
     202              : 
     203           17 :       CALL swarm_message_add(cmd, "command", "md_and_gopt")
     204           17 :       CALL swarm_message_add(cmd, "iframe", this%workers(wid)%iframe)
     205           17 :       CALL swarm_message_add(cmd, "temperature", tempstep2temp(this, this%workers(wid)%tempstep))
     206           17 :       CALL swarm_message_add(cmd, "positions", best_minima%pos)
     207              : 
     208           17 :       IF (this%iw > 0) THEN
     209              :          WRITE (this%iw, '(1X,A,T71,I10)') &
     210           17 :             "MINCRAWL| Total number of found minima", this%n_minima
     211              :          WRITE (this%iw, '(1X,A,T71,I10)') &
     212           17 :             "MINCRAWL| Sampling minima with id", best_minima%id
     213              :          WRITE (this%iw, '(1X,A,I10,A,A,T71,F10.3)') &
     214           17 :             "MINCRAWL| Temperature  (step ", this%workers(wid)%tempstep, " ) ", &
     215           34 :             "[Kelvin]", kelvin*tempstep2temp(this, this%workers(wid)%tempstep)
     216              :       END IF
     217              : 
     218              :    END SUBROUTINE mincrawl_steer
     219              : 
     220              : ! **************************************************************************************************
     221              : !> \brief Helper routine for mincrawl_steer, choses minimum based on its score.
     222              : !> \param this ...
     223              : !> \return ...
     224              : !> \author Ole Schuett
     225              : ! **************************************************************************************************
     226           17 :    FUNCTION choose_promising_minima(this) RESULT(minima)
     227              :       TYPE(mincrawl_type)                                :: this
     228              :       TYPE(minima_type), POINTER                         :: minima
     229              : 
     230              :       INTEGER                                            :: i
     231              :       REAL(KIND=dp)                                      :: score, score_best
     232              : 
     233           17 :       score_best = HUGE(1.0)
     234           17 :       NULLIFY (minima)
     235              : 
     236          111 :       DO i = 1, this%n_minima
     237           94 :          IF (this%minimas(i)%p%disabled) CYCLE
     238           44 :          IF (this%minimas(i)%p%n_active > this%worker_per_min) CYCLE
     239           44 :          score = minima_score(this%minimas(i)%p)
     240              : !       WRITE (*,*) "Minima: ", i, " active: ",this%minimas(i)%active, " E_expect: ", E_expect
     241           61 :          IF (score < score_best) THEN
     242           29 :             score_best = score
     243           29 :             minima => this%minimas(i)%p
     244              :          END IF
     245              :       END DO
     246           17 :    END FUNCTION choose_promising_minima
     247              : 
     248              : ! **************************************************************************************************
     249              : !> \brief Helper routine for choose_promising_minima, calculates a minimum's score
     250              : !> \param minima ...
     251              : !> \return ...
     252              : !> \author Ole Schuett
     253              : ! **************************************************************************************************
     254           44 :    FUNCTION minima_score(minima) RESULT(res)
     255              :       TYPE(minima_type), POINTER                         :: minima
     256              :       REAL(KIND=dp)                                      :: res
     257              : 
     258          484 :       res = SUM(minima%escape_hist)/SIZE(minima%escape_hist)
     259           44 :    END FUNCTION minima_score
     260              : 
     261              : ! **************************************************************************************************
     262              : !> \brief Helper routine for mincrawl_steer, samples from a temp-dist.
     263              : !> \param this ...
     264              : !> \param minima ...
     265              : !> \return ...
     266              : !> \author Ole Schuett
     267              : ! **************************************************************************************************
     268           17 :    FUNCTION choose_tempstep(this, minima) RESULT(step)
     269              :       TYPE(mincrawl_type)                                :: this
     270              :       TYPE(minima_type), POINTER                         :: minima
     271              :       INTEGER                                            :: step
     272              : 
     273              :       REAL(KIND=dp)                                      :: a, r
     274              : 
     275              :       DO
     276          129 :          r = this%rng_stream%next()
     277          129 :          step = INT(r*SIZE(minima%tempdist)) + 1
     278          129 :          a = 1.0 - 2.0*ABS(minima%tempdist(step) - 0.5)
     279          129 :          r = this%rng_stream%next()
     280          129 :          IF (r < a) EXIT
     281              :       END DO
     282              : 
     283           17 :    END FUNCTION choose_tempstep
     284              : 
     285              : ! **************************************************************************************************
     286              : !> \brief Debugging routine, prints a minimum's temp-distribution.
     287              : !> \param minima ...
     288              : !> \author Ole Schuett
     289              : ! **************************************************************************************************
     290            0 :    SUBROUTINE print_tempdist(minima)
     291              :       TYPE(minima_type), POINTER                         :: minima
     292              : 
     293              :       INTEGER                                            :: i
     294              : 
     295              : !WRITE (*,*) "tempdist: ", SUM(minima%tempdist, DIM=1)
     296              : 
     297            0 :       DO i = 1, SIZE(minima%tempdist)
     298            0 :          WRITE (*, *) "tempstep: ", i, minima%tempdist(i)
     299              :       END DO
     300            0 :    END SUBROUTINE print_tempdist
     301              : 
     302              : ! **************************************************************************************************
     303              : !> \brief Helper routine, convertes a  discrete temp-step to a temperature.
     304              : !> \param this ...
     305              : !> \param step ...
     306              : !> \return ...
     307              : !> \author Ole Schuett
     308              : ! **************************************************************************************************
     309           35 :    FUNCTION tempstep2temp(this, step) RESULT(temp_in_au)
     310              :       TYPE(mincrawl_type)                                :: this
     311              :       INTEGER                                            :: step
     312              :       REAL(KIND=dp)                                      :: temp_in_au
     313              : 
     314           35 :       temp_in_au = (this%tempstep_base**step)/kelvin
     315           35 :    END FUNCTION tempstep2temp
     316              : 
     317              : ! **************************************************************************************************
     318              : !> \brief Helper routine, convertes a temperature to a discrete temp-step.
     319              : !> \param this ...
     320              : !> \param temp_in_au ...
     321              : !> \return ...
     322              : !> \author Ole Schuett
     323              : ! **************************************************************************************************
     324            1 :    FUNCTION temp2tempstep(this, temp_in_au) RESULT(step)
     325              :       TYPE(mincrawl_type)                                :: this
     326              :       REAL(KIND=dp)                                      :: temp_in_au
     327              :       INTEGER                                            :: step
     328              : 
     329            1 :       step = INT(LOG(temp_in_au*kelvin)/LOG(this%tempstep_base))
     330              :       !WRITE(*,*) "temp: ", temp_in_au*kelvin, this%tempstep_base
     331              :       !WRITE(*,*) "step: ", step
     332            1 :       IF (step > this%tempstep_max) CPABORT("temp2tempstep: step > tempstep_max")
     333            1 :    END FUNCTION temp2tempstep
     334              : 
     335              : ! **************************************************************************************************
     336              : !> \brief Helper routine for mincrawl_steer
     337              : !>        Incorporates information of new report into history.
     338              : !> \param this ...
     339              : !> \param report ...
     340              : !> \author Ole Schuett
     341              : ! **************************************************************************************************
     342           17 :    SUBROUTINE mincrawl_register_minima(this, report)
     343              :       TYPE(mincrawl_type)                                :: this
     344              :       TYPE(swarm_message_type)                           :: report
     345              : 
     346              :       INTEGER                                            :: new_mid, tempstep, wid
     347              :       LOGICAL                                            :: minima_known
     348              :       REAL(KIND=dp)                                      :: report_Epot
     349           17 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: report_positions
     350              :       TYPE(history_fingerprint_type)                     :: report_fp
     351           17 :       TYPE(minima_p_type), ALLOCATABLE, DIMENSION(:)     :: minimas_tmp
     352              :       TYPE(minima_type), POINTER                         :: new_minima, start_minima
     353              : 
     354           17 :       NULLIFY (start_minima, new_minima, report_positions)
     355              : 
     356           17 :       CALL swarm_message_get(report, "worker_id", wid)
     357           17 :       CALL swarm_message_get(report, "Epot", report_Epot)
     358           17 :       CALL swarm_message_get(report, "positions", report_positions)
     359           17 :       CALL swarm_message_get(report, "iframe", this%workers(wid)%iframe)
     360              : 
     361           17 :       start_minima => this%workers(wid)%start_minima
     362           17 :       tempstep = this%workers(wid)%tempstep
     363              : 
     364           17 :       report_fp = history_fingerprint(report_Epot, report_positions)
     365           17 :       CALL history_lookup(this%history, report_fp, minima_known)
     366              : 
     367           17 :       IF (ASSOCIATED(start_minima)) THEN
     368           16 :          start_minima%n_active = start_minima%n_active - 1
     369           16 :          IF (start_minima%n_active < 0) CPABORT("negative n_active")
     370              : 
     371              :          ! update tempdist and escape_hist
     372           16 :          IF (minima_known) THEN
     373            7 :             CALL update_tempdist(this, start_minima%tempdist, tempstep, -1)
     374              :          ELSE
     375            9 :             CALL update_tempdist(this, start_minima%tempdist, tempstep, +1)
     376           99 :             start_minima%escape_hist(:) = EOSHIFT(start_minima%escape_hist, 1)
     377            9 :             start_minima%escape_hist(1) = report_Epot
     378              :          END IF
     379              : 
     380              :       END IF
     381              : 
     382           17 :       IF (.NOT. minima_known) THEN
     383           10 :          this%n_minima = this%n_minima + 1
     384           10 :          IF (this%n_minima > SIZE(this%minimas)) THEN
     385            0 :             ALLOCATE (minimas_tmp(SIZE(this%minimas)))
     386            0 :             minimas_tmp(:) = this%minimas
     387            0 :             DEALLOCATE (this%minimas)
     388            0 :             ALLOCATE (this%minimas(SIZE(minimas_tmp) + 1000))
     389            0 :             this%minimas(:SIZE(minimas_tmp)) = minimas_tmp
     390            0 :             DEALLOCATE (minimas_tmp)
     391              :          END IF
     392              : 
     393           10 :          new_mid = this%n_minima
     394           10 :          ALLOCATE (this%minimas(new_mid)%p)
     395           10 :          new_minima => this%minimas(new_mid)%p
     396           10 :          new_minima%id = new_mid
     397           30 :          ALLOCATE (new_minima%escape_hist(this%esc_hist_len))
     398           30 :          ALLOCATE (new_minima%tempdist(this%tempstep_max))
     399              : 
     400          110 :          new_minima%escape_hist(:) = report_Epot !init with Epot
     401              : 
     402           10 :          IF (ASSOCIATED(start_minima)) THEN
     403         1818 :             new_minima%tempdist(:) = start_minima%tempdist ! inherit tempdist
     404              :          ELSE
     405          101 :             new_minima%tempdist(:) = this%tempdist_init
     406              :          END IF
     407              : 
     408           10 :          new_minima%Epot = report_Epot
     409           10 :          new_minima%fp = report_fp
     410           30 :          ALLOCATE (new_minima%pos(SIZE(report_positions)))
     411          620 :          new_minima%pos(:) = report_positions
     412              : 
     413           10 :          IF (ASSOCIATED(start_minima)) THEN
     414            9 :             IF (report_Epot < start_minima%Epot) THEN
     415            6 :                start_minima%disabled = .TRUE.
     416            6 :                IF (this%iw > 0) WRITE (this%iw, '(1X,A,T71,I10)') &
     417            6 :                   "MINCRAWL| Disabling minimum with id", start_minima%id
     418              :             END IF
     419              :          END IF
     420              : 
     421           10 :          IF (this%iw > 0) WRITE (this%iw, '(1X,A,T71,I10)') &
     422           10 :             "MINCRAWL| Adding new minima with id", new_mid
     423              : 
     424           10 :          CALL history_add(this%history, report_fp, id=new_mid)
     425           10 :          CALL write_minima_traj(this, wid, new_mid, report_Epot, report_positions)
     426              :       END IF
     427           17 :       DEALLOCATE (report_positions)
     428           34 :    END SUBROUTINE mincrawl_register_minima
     429              : 
     430              : ! **************************************************************************************************
     431              : !> \brief Helper routine for mincrawl_register_minima.
     432              : !>        Adds or subtracts small Gaussian from a minimum's temp-distribution.
     433              : !> \param this ...
     434              : !> \param tempdist ...
     435              : !> \param center ...
     436              : !> \param direction ...
     437              : !> \author Ole Schuett
     438              : ! **************************************************************************************************
     439           16 :    SUBROUTINE update_tempdist(this, tempdist, center, direction)
     440              :       TYPE(mincrawl_type)                                :: this
     441              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: tempdist
     442              :       INTEGER                                            :: center, direction
     443              : 
     444              :       INTEGER                                            :: i
     445              : 
     446         1616 :       DO i = 1, SIZE(tempdist)
     447              :          tempdist(i) = tempdist(i) + this%tempdist_update_height &
     448         1600 :                        *REAL(direction, KIND=dp)*EXP(-((center - i)/this%tempdist_update_width)**2)
     449         1616 :          tempdist(i) = MAX(0.0_dp, MIN(1.0_dp, tempdist(i)))
     450              :       END DO
     451           16 :    END SUBROUTINE update_tempdist
     452              : 
     453              : ! **************************************************************************************************
     454              : !> \brief Helper routine for mincrawl_register_minima, write trajectory.
     455              : !> \param this ...
     456              : !> \param worker_id ...
     457              : !> \param minimum_id ...
     458              : !> \param Epot ...
     459              : !> \param positions ...
     460              : !> \author Ole Schuett
     461              : ! **************************************************************************************************
     462           10 :    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
     467              : 
     468              :       CHARACTER(len=default_string_length)               :: title, unit_str
     469              :       REAL(KIND=dp)                                      :: unit_conv
     470              : 
     471           10 :       IF (this%minima_traj_unit <= 0) RETURN
     472              : 
     473           10 :       WRITE (title, '(A,I8,A,I5,A,F20.10)') 'minimum_id = ', minimum_id, &
     474           20 :          ' worker_id = ', worker_id, ' Epot = ', Epot
     475              : 
     476              :       !get the conversion factor for the length unit
     477              :       CALL section_vals_val_get(this%mincrawl_section, "MINIMA_TRAJECTORY%UNIT", &
     478           10 :                                 c_val=unit_str)
     479           10 :       unit_conv = cp_unit_from_cp2k(1.0_dp, TRIM(unit_str))
     480              : 
     481              :       CALL write_particle_coordinates(this%particle_set, &
     482              :                                       iunit=this%minima_traj_unit, &
     483              :                                       output_format=dump_xmol, &
     484              :                                       content="POS", &
     485              :                                       title=TRIM(title), &
     486              :                                       array=positions, &
     487           10 :                                       unit_conv=unit_conv)
     488              :    END SUBROUTINE write_minima_traj
     489              : 
     490              : ! **************************************************************************************************
     491              : !> \brief Finalizes master for Minima Crawling
     492              : !> \param this ...
     493              : !> \author Ole Schuett
     494              : ! **************************************************************************************************
     495            1 :    SUBROUTINE mincrawl_finalize(this)
     496              :       TYPE(mincrawl_type)                                :: this
     497              : 
     498              :       INTEGER                                            :: i
     499              :       TYPE(cp_logger_type), POINTER                      :: logger
     500              : 
     501            1 :       NULLIFY (logger)
     502              : 
     503           11 :       DO i = 1, this%n_minima
     504              :          !WRITE (*,*) "Minima: ", i, " n_sampled: ",this%minimas(i)%n_sampled
     505           11 :          DEALLOCATE (this%minimas(i)%p)
     506              :       END DO
     507              : 
     508            1 :       logger => cp_get_default_logger()
     509              :       CALL cp_print_key_finished_output(this%minima_traj_unit, logger, &
     510            1 :                                         this%mincrawl_section, "MINIMA_TRAJECTORY")
     511              : 
     512            1 :       CALL history_finalize(this%history)
     513            1 :    END SUBROUTINE mincrawl_finalize
     514              : 
     515            0 : END MODULE glbopt_mincrawl
     516              : 
        

Generated by: LCOV version 2.0-1