LCOV - code coverage report
Current view: top level - src/swarm - glbopt_mincrawl.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:e7e05ae) Lines: 149 162 92.0 %
Date: 2024-04-18 06:59:28 Functions: 11 18 61.1 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 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         106 :    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          53 :       CALL swarm_message_get(report, "status", status)
     175          53 :       CALL swarm_message_get(report, "worker_id", wid)
     176             : 
     177          53 :       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          52 :       IF (TRIM(status) == "ok") &
     186          52 :          CALL mincrawl_register_minima(this, report)
     187             : 
     188             :       IF (.FALSE.) CALL print_tempdist(best_minima)
     189             : 
     190          52 :       best_minima => choose_promising_minima(this)
     191             : 
     192          52 :       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          52 :       best_minima%n_active = best_minima%n_active + 1
     199          52 :       best_minima%n_sampled = best_minima%n_sampled + 1
     200          52 :       this%workers(wid)%start_minima => best_minima
     201          52 :       this%workers(wid)%tempstep = choose_tempstep(this, best_minima)
     202             : 
     203          52 :       CALL swarm_message_add(cmd, "command", "md_and_gopt")
     204          52 :       CALL swarm_message_add(cmd, "iframe", this%workers(wid)%iframe)
     205          52 :       CALL swarm_message_add(cmd, "temperature", tempstep2temp(this, this%workers(wid)%tempstep))
     206          52 :       CALL swarm_message_add(cmd, "positions", best_minima%pos)
     207             : 
     208          52 :       IF (this%iw > 0) THEN
     209             :          WRITE (this%iw, '(1X,A,T71,I10)') &
     210          52 :             "MINCRAWL| Total number of found minima", this%n_minima
     211             :          WRITE (this%iw, '(1X,A,T71,I10)') &
     212          52 :             "MINCRAWL| Sampling minima with id", best_minima%id
     213             :          WRITE (this%iw, '(1X,A,I10,A,A,T71,F10.3)') &
     214          52 :             "MINCRAWL| Temperature  (step ", this%workers(wid)%tempstep, " ) ", &
     215         104 :             "[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          52 :    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          52 :       score_best = HUGE(1.0)
     234          52 :       NULLIFY (minima)
     235             : 
     236         472 :       DO i = 1, this%n_minima
     237         420 :          IF (this%minimas(i)%p%disabled) CYCLE
     238         227 :          IF (this%minimas(i)%p%n_active > this%worker_per_min) CYCLE
     239         227 :          score = minima_score(this%minimas(i)%p)
     240             : !       WRITE (*,*) "Minima: ", i, " active: ",this%minimas(i)%active, " E_expect: ", E_expect
     241         279 :          IF (score < score_best) THEN
     242          94 :             score_best = score
     243          94 :             minima => this%minimas(i)%p
     244             :          END IF
     245             :       END DO
     246          52 :    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         227 :    FUNCTION minima_score(minima) RESULT(res)
     255             :       TYPE(minima_type), POINTER                         :: minima
     256             :       REAL(KIND=dp)                                      :: res
     257             : 
     258        2497 :       res = SUM(minima%escape_hist)/SIZE(minima%escape_hist)
     259         227 :    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          52 :    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         521 :          r = this%rng_stream%next()
     277         521 :          step = INT(r*SIZE(minima%tempdist)) + 1
     278         521 :          a = 1.0 - 2.0*ABS(minima%tempdist(step) - 0.5)
     279         521 :          r = this%rng_stream%next()
     280         521 :          IF (r < a) EXIT
     281             :       END DO
     282             : 
     283          52 :    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         105 :    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         105 :       temp_in_au = (this%tempstep_base**step)/kelvin
     315         105 :    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          52 :    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          52 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: report_positions
     350             :       TYPE(history_fingerprint_type)                     :: report_fp
     351          52 :       TYPE(minima_p_type), ALLOCATABLE, DIMENSION(:)     :: minimas_tmp
     352             :       TYPE(minima_type), POINTER                         :: new_minima, start_minima
     353             : 
     354          52 :       NULLIFY (start_minima, new_minima, report_positions)
     355             : 
     356          52 :       CALL swarm_message_get(report, "worker_id", wid)
     357          52 :       CALL swarm_message_get(report, "Epot", report_Epot)
     358          52 :       CALL swarm_message_get(report, "positions", report_positions)
     359          52 :       CALL swarm_message_get(report, "iframe", this%workers(wid)%iframe)
     360             : 
     361          52 :       start_minima => this%workers(wid)%start_minima
     362          52 :       tempstep = this%workers(wid)%tempstep
     363             : 
     364          52 :       report_fp = history_fingerprint(report_Epot, report_positions)
     365          52 :       CALL history_lookup(this%history, report_fp, minima_known)
     366             : 
     367          52 :       IF (ASSOCIATED(start_minima)) THEN
     368          51 :          start_minima%n_active = start_minima%n_active - 1
     369          51 :          IF (start_minima%n_active < 0) CPABORT("negative n_active")
     370             : 
     371             :          ! update tempdist and escape_hist
     372          51 :          IF (minima_known) THEN
     373          40 :             CALL update_tempdist(this, start_minima%tempdist, tempstep, -1)
     374             :          ELSE
     375          11 :             CALL update_tempdist(this, start_minima%tempdist, tempstep, +1)
     376         121 :             start_minima%escape_hist(:) = EOSHIFT(start_minima%escape_hist, 1)
     377          11 :             start_minima%escape_hist(1) = report_Epot
     378             :          END IF
     379             : 
     380             :       END IF
     381             : 
     382          52 :       IF (.NOT. minima_known) THEN
     383          12 :          this%n_minima = this%n_minima + 1
     384          12 :          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          12 :          new_mid = this%n_minima
     394          12 :          ALLOCATE (this%minimas(new_mid)%p)
     395          12 :          new_minima => this%minimas(new_mid)%p
     396          12 :          new_minima%id = new_mid
     397          36 :          ALLOCATE (new_minima%escape_hist(this%esc_hist_len))
     398          36 :          ALLOCATE (new_minima%tempdist(this%tempstep_max))
     399             : 
     400         132 :          new_minima%escape_hist(:) = report_Epot !init with Epot
     401             : 
     402          12 :          IF (ASSOCIATED(start_minima)) THEN
     403        2222 :             new_minima%tempdist(:) = start_minima%tempdist ! inherit tempdist
     404             :          ELSE
     405         101 :             new_minima%tempdist(:) = this%tempdist_init
     406             :          END IF
     407             : 
     408          12 :          new_minima%Epot = report_Epot
     409          12 :          new_minima%fp = report_fp
     410          36 :          ALLOCATE (new_minima%pos(SIZE(report_positions)))
     411         744 :          new_minima%pos(:) = report_positions
     412             : 
     413          12 :          IF (ASSOCIATED(start_minima)) THEN
     414          11 :             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          12 :          IF (this%iw > 0) WRITE (this%iw, '(1X,A,T71,I10)') &
     422          12 :             "MINCRAWL| Adding new minima with id", new_mid
     423             : 
     424          12 :          CALL history_add(this%history, report_fp, id=new_mid)
     425          12 :          CALL write_minima_traj(this, wid, new_mid, report_Epot, report_positions)
     426             :       END IF
     427          52 :       DEALLOCATE (report_positions)
     428         104 :    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          51 :    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        5151 :       DO i = 1, SIZE(tempdist)
     447             :          tempdist(i) = tempdist(i) + this%tempdist_update_height &
     448        5100 :                        *REAL(direction, KIND=dp)*EXP(-((center - i)/this%tempdist_update_width)**2)
     449        5151 :          tempdist(i) = MAX(0.0_dp, MIN(1.0_dp, tempdist(i)))
     450             :       END DO
     451          51 :    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          12 :    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          12 :       IF (this%minima_traj_unit <= 0) RETURN
     472             : 
     473          12 :       WRITE (title, '(A,I8,A,I5,A,F20.10)') 'minimum_id = ', minimum_id, &
     474          24 :          ' 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          12 :                                 c_val=unit_str)
     479          12 :       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          12 :                                       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          13 :       DO i = 1, this%n_minima
     504             :          !WRITE (*,*) "Minima: ", i, " n_sampled: ",this%minimas(i)%n_sampled
     505          13 :          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 1.15