LCOV - code coverage report
Current view: top level - src/swarm - glbopt_master.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 98.0 % 98 96
Test Date: 2025-12-04 06:27:48 Functions: 85.7 % 7 6

            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 Master's routines for global optimization
      10              : !> \author Ole Schuett
      11              : ! **************************************************************************************************
      12              : MODULE glbopt_master
      13              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      14              :                                               deallocate_atomic_kind_set
      15              :    USE colvar_types,                    ONLY: colvar_p_release,&
      16              :                                               colvar_p_type
      17              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      18              :                                               cp_logger_type
      19              :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      20              :                                               cp_print_key_unit_nr
      21              :    USE cp_units,                        ONLY: cp_unit_from_cp2k
      22              :    USE exclusion_types,                 ONLY: exclusion_release,&
      23              :                                               exclusion_type
      24              :    USE glbopt_mincrawl,                 ONLY: mincrawl_finalize,&
      25              :                                               mincrawl_init,&
      26              :                                               mincrawl_steer,&
      27              :                                               mincrawl_type
      28              :    USE glbopt_minhop,                   ONLY: minhop_finalize,&
      29              :                                               minhop_init,&
      30              :                                               minhop_steer,&
      31              :                                               minhop_type
      32              :    USE input_constants,                 ONLY: dump_xmol,&
      33              :                                               glbopt_do_mincrawl,&
      34              :                                               glbopt_do_minhop
      35              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      36              :                                               section_vals_release,&
      37              :                                               section_vals_retain,&
      38              :                                               section_vals_type,&
      39              :                                               section_vals_val_get
      40              :    USE kinds,                           ONLY: default_string_length,&
      41              :                                               dp,&
      42              :                                               int_8
      43              :    USE message_passing,                 ONLY: mp_para_env_type
      44              :    USE molecule_kind_types,             ONLY: deallocate_molecule_kind_set,&
      45              :                                               molecule_kind_type
      46              :    USE molecule_types,                  ONLY: deallocate_global_constraint,&
      47              :                                               deallocate_molecule_set,&
      48              :                                               global_constraint_type,&
      49              :                                               molecule_type
      50              :    USE particle_methods,                ONLY: write_particle_coordinates
      51              :    USE particle_types,                  ONLY: deallocate_particle_set,&
      52              :                                               particle_type
      53              :    USE swarm_message,                   ONLY: swarm_message_get,&
      54              :                                               swarm_message_type
      55              :    USE topology,                        ONLY: topology_control
      56              : #include "../base/base_uses.f90"
      57              : 
      58              :    IMPLICIT NONE
      59              :    PRIVATE
      60              : 
      61              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'glbopt_master'
      62              : 
      63              :    PUBLIC :: glbopt_master_type
      64              :    PUBLIC :: glbopt_master_init, glbopt_master_finalize
      65              :    PUBLIC :: glbopt_master_steer
      66              : 
      67              :    TYPE glbopt_master_type
      68              :       PRIVATE
      69              :       REAL(KIND=dp)                                       :: E_lowest = HUGE(1.0_dp)
      70              :       REAL(KIND=dp)                                       :: E_target = TINY(1.0_dp)
      71              :       INTEGER                                             :: iw = 0
      72              :       INTEGER                                             :: progress_traj_unit = 0
      73              :       INTEGER(int_8)                                      :: total_md_steps = 0
      74              :       INTEGER(int_8)                                      :: total_gopt_steps = 0
      75              :       INTEGER(int_8)                                      :: count_reports = 0
      76              :       INTEGER                                             :: method = glbopt_do_minhop
      77              :       TYPE(minhop_type), POINTER                           :: minhop => NULL()
      78              :       TYPE(mincrawl_type), POINTER                        :: mincrawl => NULL()
      79              :       INTEGER                                             :: i_iteration = 0
      80              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER       :: atomic_kind_set => Null()
      81              :       TYPE(particle_type), DIMENSION(:), POINTER          :: particle_set => Null()
      82              :       TYPE(section_vals_type), POINTER                    :: glbopt_section => Null()
      83              :    END TYPE glbopt_master_type
      84              : 
      85              : CONTAINS
      86              : 
      87              : ! **************************************************************************************************
      88              : !> \brief Initializes the master of the global optimizer
      89              : !> \param this ...
      90              : !> \param para_env ...
      91              : !> \param root_section ...
      92              : !> \param n_walkers ...
      93              : !> \param iw ...
      94              : !> \author Ole Schuett
      95              : ! **************************************************************************************************
      96            3 :    SUBROUTINE glbopt_master_init(this, para_env, root_section, n_walkers, iw)
      97              :       TYPE(glbopt_master_type), INTENT(INOUT)            :: this
      98              :       TYPE(mp_para_env_type), POINTER                    :: para_env
      99              :       TYPE(section_vals_type), POINTER                   :: root_section
     100              :       INTEGER, INTENT(IN)                                :: n_walkers, iw
     101              : 
     102              :       TYPE(cp_logger_type), POINTER                      :: logger
     103              : 
     104            3 :       NULLIFY (logger)
     105              : 
     106            3 :       this%iw = iw
     107              : 
     108            3 :       this%glbopt_section => section_vals_get_subs_vals(root_section, "SWARM%GLOBAL_OPT")
     109            3 :       CALL section_vals_retain(this%glbopt_section)
     110              : 
     111            3 :       CALL section_vals_val_get(this%glbopt_section, "E_TARGET", r_val=this%E_target)
     112            3 :       CALL section_vals_val_get(this%glbopt_section, "METHOD", i_val=this%method)
     113              : 
     114            3 :       CALL glbopt_read_particle_set(this, para_env, root_section)
     115              : 
     116            3 :       logger => cp_get_default_logger()
     117              :       this%progress_traj_unit = cp_print_key_unit_nr(logger, &
     118              :                                                      this%glbopt_section, "PROGRESS_TRAJECTORY", &
     119              :                                                      middle_name="progress", extension=".xyz", &
     120            3 :                                                      file_action="WRITE", file_position="REWIND")
     121              : 
     122            5 :       SELECT CASE (this%method)
     123              :       CASE (glbopt_do_minhop)
     124            2 :          ALLOCATE (this%minhop)
     125            2 :          CALL minhop_init(this%minhop, this%glbopt_section, n_walkers, iw)
     126              :       CASE (glbopt_do_mincrawl)
     127           27 :          ALLOCATE (this%mincrawl)
     128            1 :          CALL mincrawl_init(this%mincrawl, this%glbopt_section, n_walkers, iw, this%particle_set)
     129              :       CASE DEFAULT
     130            3 :          CPABORT("Unknown glbopt_method")
     131              :       END SELECT
     132            3 :    END SUBROUTINE glbopt_master_init
     133              : 
     134              : ! **************************************************************************************************
     135              : !> \brief Helper-routine for glbopt_master_init, reads part of SUBSYS-section
     136              : !> \param this ...
     137              : !> \param para_env ...
     138              : !> \param root_section ...
     139              : !> \author Ole Schuett
     140              : ! **************************************************************************************************
     141            3 :    SUBROUTINE glbopt_read_particle_set(this, para_env, root_section)
     142              :       TYPE(glbopt_master_type), INTENT(INOUT)            :: this
     143              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     144              :       TYPE(section_vals_type), POINTER                   :: root_section
     145              : 
     146            3 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     147            3 :       TYPE(colvar_p_type), DIMENSION(:), POINTER         :: colvar_p
     148            3 :       TYPE(exclusion_type), DIMENSION(:), POINTER        :: exclusions
     149              :       TYPE(global_constraint_type), POINTER              :: gci
     150            3 :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     151            3 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     152            3 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     153              :       TYPE(section_vals_type), POINTER                   :: force_env_section, subsys_section
     154              : 
     155            3 :       NULLIFY (atomic_kind_set, particle_set, molecule_kind_set, molecule_set)
     156            3 :       NULLIFY (colvar_p, gci, exclusions, force_env_section, subsys_section)
     157              : 
     158            6 :       force_env_section => section_vals_get_subs_vals(root_section, "FORCE_EVAL")
     159            3 :       subsys_section => section_vals_get_subs_vals(root_section, "FORCE_EVAL%SUBSYS")
     160              : 
     161              :       CALL topology_control(atomic_kind_set, &
     162              :                             particle_set, &
     163              :                             molecule_kind_set, &
     164              :                             molecule_set, &
     165              :                             colvar_p, &
     166              :                             gci, &
     167              :                             root_section=root_section, &
     168              :                             para_env=para_env, &
     169              :                             force_env_section=force_env_section, &
     170              :                             subsys_section=subsys_section, &
     171              :                             use_motion_section=.FALSE., &
     172            3 :                             exclusions=exclusions)
     173              : 
     174              :       !This is the only thing we need to write trajectories.
     175            3 :       this%atomic_kind_set => atomic_kind_set
     176            3 :       this%particle_set => particle_set
     177            3 :       CALL exclusion_release(exclusions)
     178            3 :       CALL deallocate_molecule_set(molecule_set)
     179            3 :       CALL deallocate_molecule_kind_set(molecule_kind_set)
     180            3 :       CALL deallocate_global_constraint(gci)
     181            3 :       CALL colvar_p_release(colvar_p)
     182              : 
     183            3 :    END SUBROUTINE glbopt_read_particle_set
     184              : 
     185              : ! **************************************************************************************************
     186              : !> \brief Central steering routine of global optimizer
     187              : !> \param this ...
     188              : !> \param report ...
     189              : !> \param cmd ...
     190              : !> \param should_stop ...
     191              : !> \author Ole Schuett
     192              : ! **************************************************************************************************
     193           31 :    SUBROUTINE glbopt_master_steer(this, report, cmd, should_stop)
     194              :       TYPE(glbopt_master_type), INTENT(INOUT)            :: this
     195              :       TYPE(swarm_message_type)                           :: report, cmd
     196              :       LOGICAL, INTENT(INOUT)                             :: should_stop
     197              : 
     198           31 :       CALL progress_report(this, report)
     199              : 
     200           44 :       SELECT CASE (this%method)
     201              :       CASE (glbopt_do_minhop)
     202           13 :          CALL minhop_steer(this%minhop, report, cmd)
     203              :       CASE (glbopt_do_mincrawl)
     204           18 :          CALL mincrawl_steer(this%mincrawl, report, cmd)
     205              :       CASE DEFAULT
     206           31 :          CPABORT("Unknown glbopt_method")
     207              :       END SELECT
     208              : 
     209           31 :       IF (this%E_lowest < this%E_target) THEN
     210            2 :          IF (this%iw > 0) WRITE (this%iw, "(A,I8,A)") &
     211            2 :             " GLBOPT| Reached E_pot < E_target after ", this%i_iteration, " iterations. Quitting."
     212            2 :          should_stop = .TRUE.
     213              :       END IF
     214           31 :    END SUBROUTINE glbopt_master_steer
     215              : 
     216              : ! **************************************************************************************************
     217              : !> \brief Helper routine for glbopt_master_steer(), updates stats, etc.
     218              : !> \param this ...
     219              : !> \param report ...
     220              : !> \author Ole Schuett
     221              : ! **************************************************************************************************
     222           31 :    SUBROUTINE progress_report(this, report)
     223              :       TYPE(glbopt_master_type), INTENT(INOUT)            :: this
     224              :       TYPE(swarm_message_type)                           :: report
     225              : 
     226              :       CHARACTER(len=default_string_length)               :: status
     227              :       INTEGER                                            :: gopt_steps, md_steps, report_worker_id
     228              :       REAL(KIND=dp)                                      :: report_Epot
     229              : 
     230           31 :       this%i_iteration = this%i_iteration + 1
     231              : 
     232           31 :       CALL swarm_message_get(report, "worker_id", report_worker_id)
     233           31 :       CALL swarm_message_get(report, "status", status)
     234              : 
     235           31 :       IF (TRIM(status) == "ok") THEN
     236           28 :          CALL swarm_message_get(report, "Epot", report_Epot)
     237           28 :          CALL swarm_message_get(report, "md_steps", md_steps)
     238           28 :          CALL swarm_message_get(report, "gopt_steps", gopt_steps)
     239           28 :          this%total_md_steps = this%total_md_steps + md_steps
     240           28 :          this%total_gopt_steps = this%total_gopt_steps + gopt_steps
     241           28 :          this%count_reports = this%count_reports + 1
     242              : 
     243           28 :          IF (report_Epot < this%E_lowest) THEN
     244           15 :             this%E_lowest = report_Epot
     245           15 :             CALL write_progress_traj(this, report)
     246              :          END IF
     247              : 
     248           28 :          IF (this%iw > 0) THEN
     249              :             WRITE (this%iw, '(A,46X,I8)') &
     250           28 :                " GLBOPT| Reporting worker ", report_worker_id
     251              :             WRITE (this%iw, '(A,20X,E15.8)') &
     252           28 :                " GLBOPT| Reported potential energy [Hartree] ", report_Epot
     253              :             WRITE (this%iw, '(A,13X,E15.8)') &
     254           28 :                " GLBOPT| Lowest reported potential energy [Hartree] ", this%E_lowest
     255              :             WRITE (this%iw, '(A,T71,F10.1)') &
     256           28 :                " GLBOPT| Average number of MD steps", REAL(this%total_md_steps, KIND=dp)/this%count_reports
     257              :             WRITE (this%iw, '(A,T71,F10.1)') &
     258           28 :                " GLBOPT| Average number of Geo-Opt steps", REAL(this%total_gopt_steps, KIND=dp)/this%count_reports
     259              :          END IF
     260              :       END IF
     261           31 :    END SUBROUTINE progress_report
     262              : 
     263              : ! **************************************************************************************************
     264              : !> \brief Helper routine for progress_report(), write frames to trajectory.
     265              : !> \param this ...
     266              : !> \param report ...
     267              : !> \author Ole Schuett
     268              : ! **************************************************************************************************
     269           45 :    SUBROUTINE write_progress_traj(this, report)
     270              :       TYPE(glbopt_master_type), INTENT(INOUT)            :: this
     271              :       TYPE(swarm_message_type), INTENT(IN)               :: report
     272              : 
     273              :       CHARACTER(len=default_string_length)               :: title, unit_str
     274              :       INTEGER                                            :: report_worker_id
     275              :       REAL(KIND=dp)                                      :: report_Epot, unit_conv
     276           15 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: report_positions
     277              : 
     278           15 :       NULLIFY (report_positions)
     279              : 
     280            0 :       IF (this%progress_traj_unit <= 0) RETURN
     281              : 
     282           15 :       CALL swarm_message_get(report, "worker_id", report_worker_id)
     283           15 :       CALL swarm_message_get(report, "positions", report_positions)
     284           15 :       CALL swarm_message_get(report, "Epot", report_Epot)
     285              : 
     286           15 :       WRITE (title, '(A,I8,A,I5,A,F20.10)') 'i = ', this%i_iteration, &
     287           30 :          ' worker_id = ', report_worker_id, ' Epot = ', report_Epot
     288              : 
     289              :       !get the conversion factor for the length unit
     290              :       CALL section_vals_val_get(this%glbopt_section, "PROGRESS_TRAJECTORY%UNIT", &
     291           15 :                                 c_val=unit_str)
     292           15 :       unit_conv = cp_unit_from_cp2k(1.0_dp, TRIM(unit_str))
     293              :       CALL write_particle_coordinates(this%particle_set, &
     294              :                                       iunit=this%progress_traj_unit, &
     295              :                                       output_format=dump_xmol, &
     296              :                                       content="POS", &
     297              :                                       title=TRIM(title), &
     298              :                                       array=report_positions, &
     299           15 :                                       unit_conv=unit_conv)
     300           15 :       DEALLOCATE (report_positions)
     301           15 :    END SUBROUTINE write_progress_traj
     302              : 
     303              : ! **************************************************************************************************
     304              : !> \brief Finalized the master of the global optimizer
     305              : !> \param this ...
     306              : !> \author Ole
     307              : ! **************************************************************************************************
     308            3 :    SUBROUTINE glbopt_master_finalize(this)
     309              :       TYPE(glbopt_master_type), INTENT(INOUT)            :: this
     310              : 
     311              :       TYPE(cp_logger_type), POINTER                      :: logger
     312              : 
     313            3 :       NULLIFY (logger)
     314              : 
     315            5 :       SELECT CASE (this%method)
     316              :       CASE (glbopt_do_minhop)
     317            2 :          CALL minhop_finalize(this%minhop)
     318            4 :          DEALLOCATE (this%minhop)
     319              :       CASE (glbopt_do_mincrawl)
     320            1 :          CALL mincrawl_finalize(this%mincrawl)
     321            1 :          DEALLOCATE (this%mincrawl)
     322              :       CASE DEFAULT
     323            3 :          CPABORT("Unknown glbopt_method")
     324              :       END SELECT
     325              : 
     326            3 :       logger => cp_get_default_logger()
     327              :       CALL cp_print_key_finished_output(this%progress_traj_unit, logger, &
     328            3 :                                         this%glbopt_section, "PROGRESS_TRAJECTORY")
     329              : 
     330            3 :       CALL section_vals_release(this%glbopt_section)
     331            3 :       CALL deallocate_particle_set(this%particle_set)
     332            3 :       CALL deallocate_atomic_kind_set(this%atomic_kind_set)
     333              : 
     334            3 :    END SUBROUTINE glbopt_master_finalize
     335              : 
     336            0 : END MODULE glbopt_master
     337              : 
        

Generated by: LCOV version 2.0-1