LCOV - code coverage report
Current view: top level - src/swarm - glbopt_master.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:262480d) Lines: 96 98 98.0 %
Date: 2024-11-22 07:00:40 Functions: 6 7 85.7 %

          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 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          54 :    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          54 :       CALL progress_report(this, report)
     199             : 
     200          67 :       SELECT CASE (this%method)
     201             :       CASE (glbopt_do_minhop)
     202          13 :          CALL minhop_steer(this%minhop, report, cmd)
     203             :       CASE (glbopt_do_mincrawl)
     204          41 :          CALL mincrawl_steer(this%mincrawl, report, cmd)
     205             :       CASE DEFAULT
     206          54 :          CPABORT("Unknown glbopt_method")
     207             :       END SELECT
     208             : 
     209          54 :       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          54 :    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          54 :    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          54 :       this%i_iteration = this%i_iteration + 1
     231             : 
     232          54 :       CALL swarm_message_get(report, "worker_id", report_worker_id)
     233          54 :       CALL swarm_message_get(report, "status", status)
     234             : 
     235          54 :       IF (TRIM(status) == "ok") THEN
     236          51 :          CALL swarm_message_get(report, "Epot", report_Epot)
     237          51 :          CALL swarm_message_get(report, "md_steps", md_steps)
     238          51 :          CALL swarm_message_get(report, "gopt_steps", gopt_steps)
     239          51 :          this%total_md_steps = this%total_md_steps + md_steps
     240          51 :          this%total_gopt_steps = this%total_gopt_steps + gopt_steps
     241          51 :          this%count_reports = this%count_reports + 1
     242             : 
     243          51 :          IF (report_Epot < this%E_lowest) THEN
     244          14 :             this%E_lowest = report_Epot
     245          14 :             CALL write_progress_traj(this, report)
     246             :          END IF
     247             : 
     248          51 :          IF (this%iw > 0) THEN
     249             :             WRITE (this%iw, '(A,46X,I8)') &
     250          51 :                " GLBOPT| Reporting worker ", report_worker_id
     251             :             WRITE (this%iw, '(A,20X,E15.8)') &
     252          51 :                " GLBOPT| Reported potential energy [Hartree] ", report_Epot
     253             :             WRITE (this%iw, '(A,13X,E15.8)') &
     254          51 :                " GLBOPT| Lowest reported potential energy [Hartree] ", this%E_lowest
     255             :             WRITE (this%iw, '(A,T71,F10.1)') &
     256          51 :                " 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          51 :                " GLBOPT| Average number of Geo-Opt steps", REAL(this%total_gopt_steps, KIND=dp)/this%count_reports
     259             :          END IF
     260             :       END IF
     261          54 :    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          42 :    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          14 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: report_positions
     277             : 
     278          14 :       NULLIFY (report_positions)
     279             : 
     280           0 :       IF (this%progress_traj_unit <= 0) RETURN
     281             : 
     282          14 :       CALL swarm_message_get(report, "worker_id", report_worker_id)
     283          14 :       CALL swarm_message_get(report, "positions", report_positions)
     284          14 :       CALL swarm_message_get(report, "Epot", report_Epot)
     285             : 
     286          14 :       WRITE (title, '(A,I8,A,I5,A,F20.10)') 'i = ', this%i_iteration, &
     287          28 :          ' 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          14 :                                 c_val=unit_str)
     292          14 :       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          14 :                                       unit_conv=unit_conv)
     300          14 :       DEALLOCATE (report_positions)
     301          14 :    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 1.15