LCOV - code coverage report
Current view: top level - src/motion - gopt_f_methods.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:96bff0e) Lines: 389 392 99.2 %
Date: 2024-07-27 06:51:10 Functions: 15 15 100.0 %

          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 contains a functional that calculates the energy and its derivatives
      10             : !>      for the geometry optimizer
      11             : !> \par History
      12             : !>      none
      13             : ! **************************************************************************************************
      14             : MODULE gopt_f_methods
      15             : 
      16             :    USE atomic_kind_list_types, ONLY: atomic_kind_list_type
      17             :    USE atomic_kind_types, ONLY: atomic_kind_type, &
      18             :                                 get_atomic_kind_set
      19             :    USE cell_methods, ONLY: cell_create, &
      20             :                            init_cell
      21             :    USE cell_types, ONLY: cell_copy, &
      22             :                          cell_release, &
      23             :                          cell_type, &
      24             :                          real_to_scaled, &
      25             :                          scaled_to_real
      26             :    USE cp_log_handling, ONLY: cp_to_string
      27             :    USE cp_subsys_types, ONLY: cp_subsys_get, &
      28             :                               cp_subsys_set, &
      29             :                               cp_subsys_type, &
      30             :                               pack_subsys_particles
      31             :    USE cp_units, ONLY: cp_unit_from_cp2k
      32             :    USE dimer_types, ONLY: dimer_env_type
      33             :    USE dimer_utils, ONLY: update_dimer_vec
      34             :    USE distribution_1d_types, ONLY: distribution_1d_type
      35             :    USE force_env_types, ONLY: force_env_get, &
      36             :                               force_env_get_natom, &
      37             :                               force_env_get_nparticle, &
      38             :                               force_env_type, &
      39             :                               use_qmmm, &
      40             :                               use_qmmmx
      41             :    USE gopt_f_types, ONLY: gopt_f_type
      42             :    USE gopt_param_types, ONLY: gopt_param_type
      43             :    USE input_constants, ONLY: default_cell_direct_id, &
      44             :                               default_cell_geo_opt_id, &
      45             :                               default_cell_md_id, &
      46             :                               default_cell_method_id, &
      47             :                               default_minimization_method_id, &
      48             :                               default_shellcore_method_id, &
      49             :                               default_ts_method_id, &
      50             :                               fix_none
      51             :    USE input_cp2k_restarts, ONLY: write_restart
      52             :    USE input_section_types, ONLY: section_vals_type, &
      53             :                                   section_vals_val_get
      54             :    USE kinds, ONLY: default_string_length, &
      55             :                     dp, &
      56             :                     int_8
      57             :    USE machine, ONLY: m_flush
      58             :    USE md_energies, ONLY: sample_memory
      59             :    USE message_passing, ONLY: mp_para_env_type
      60             :    USE motion_utils, ONLY: write_simulation_cell, &
      61             :                            write_stress_tensor, &
      62             :                            write_trajectory
      63             :    USE particle_list_types, ONLY: particle_list_type
      64             :    USE particle_methods, ONLY: write_structure_data
      65             :    USE particle_types, ONLY: particle_type
      66             :    USE qmmm_util, ONLY: apply_qmmm_translate
      67             :    USE qmmmx_util, ONLY: apply_qmmmx_translate
      68             :    USE virial_methods, ONLY: virial_evaluate
      69             :    USE virial_types, ONLY: virial_type
      70             : #include "../base/base_uses.f90"
      71             : 
      72             :    IMPLICIT NONE
      73             :    PRIVATE
      74             : 
      75             :    #:include "gopt_f77_methods.fypp"
      76             : 
      77             :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
      78             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'gopt_f_methods'
      79             : 
      80             :    PUBLIC :: gopt_f_create_x0, &
      81             :              print_geo_opt_header, print_geo_opt_nc, &
      82             :              gopt_f_io_init, gopt_f_io, gopt_f_io_finalize, gopt_f_ii, &
      83             :              apply_cell_change
      84             : 
      85             : CONTAINS
      86             : 
      87             : ! **************************************************************************************************
      88             : !> \brief returns the value of the parameters for the actual configuration
      89             : !> \param gopt_env the geometry optimization environment you want the info about
      90             : !>      x0: the parameter vector (is allocated by this routine)
      91             : !> \param x0 ...
      92             : !> \par History
      93             : !>      - Cell optimization revised (06.11.2012,MK)
      94             : ! **************************************************************************************************
      95        1966 :    SUBROUTINE gopt_f_create_x0(gopt_env, x0)
      96             : 
      97             :       TYPE(gopt_f_type), POINTER                         :: gopt_env
      98             :       REAL(KIND=dp), DIMENSION(:), POINTER               :: x0
      99             : 
     100             :       INTEGER                                            :: i, idg, j, nparticle
     101             :       TYPE(cell_type), POINTER                           :: cell
     102             :       TYPE(cp_subsys_type), POINTER                      :: subsys
     103             : 
     104        1966 :       NULLIFY (cell)
     105        1966 :       NULLIFY (subsys)
     106             : 
     107        3722 :       SELECT CASE (gopt_env%type_id)
     108             :       CASE (default_minimization_method_id, default_ts_method_id)
     109        1756 :          CALL force_env_get(gopt_env%force_env, subsys=subsys)
     110             :          ! before starting we handle the case of translating coordinates (QM/MM)
     111        1756 :          IF (gopt_env%force_env%in_use == use_qmmm) &
     112          36 :             CALL apply_qmmm_translate(gopt_env%force_env%qmmm_env)
     113        1756 :          IF (gopt_env%force_env%in_use == use_qmmmx) &
     114           0 :             CALL apply_qmmmx_translate(gopt_env%force_env%qmmmx_env)
     115        1756 :          nparticle = force_env_get_nparticle(gopt_env%force_env)
     116        5268 :          ALLOCATE (x0(3*nparticle))
     117        1756 :          CALL pack_subsys_particles(subsys=subsys, r=x0)
     118             :       CASE (default_cell_method_id)
     119         378 :          SELECT CASE (gopt_env%cell_method_id)
     120             :          CASE (default_cell_direct_id)
     121         168 :             CALL force_env_get(gopt_env%force_env, subsys=subsys, cell=cell)
     122             :             ! Store reference cell
     123        4368 :             gopt_env%h_ref = cell%hmat
     124             :             ! before starting we handle the case of translating coordinates (QM/MM)
     125         168 :             IF (gopt_env%force_env%in_use == use_qmmm) &
     126           0 :                CALL apply_qmmm_translate(gopt_env%force_env%qmmm_env)
     127         168 :             IF (gopt_env%force_env%in_use == use_qmmmx) &
     128           0 :                CALL apply_qmmmx_translate(gopt_env%force_env%qmmmx_env)
     129         168 :             nparticle = force_env_get_nparticle(gopt_env%force_env)
     130         504 :             ALLOCATE (x0(3*nparticle + 6))
     131         168 :             CALL pack_subsys_particles(subsys=subsys, r=x0)
     132         168 :             idg = 3*nparticle
     133         672 :             DO i = 1, 3
     134        1680 :                DO j = 1, i
     135        1008 :                   idg = idg + 1
     136        1512 :                   x0(idg) = cell%hmat(j, i)
     137             :                END DO
     138             :             END DO
     139             :          CASE (default_cell_geo_opt_id, default_cell_md_id)
     140          42 :             CALL force_env_get(gopt_env%force_env, cell=cell)
     141          42 :             ALLOCATE (x0(6))
     142          42 :             idg = 0
     143         168 :             DO i = 1, 3
     144         420 :                DO j = 1, i
     145         252 :                   idg = idg + 1
     146         378 :                   x0(idg) = cell%hmat(j, i)
     147             :                END DO
     148             :             END DO
     149             :          CASE DEFAULT
     150         210 :             CPABORT("")
     151             :          END SELECT
     152             :       CASE DEFAULT
     153        1966 :          CPABORT("")
     154             :       END SELECT
     155             : 
     156        1966 :    END SUBROUTINE gopt_f_create_x0
     157             : 
     158             : ! **************************************************************************************************
     159             : !> \brief Prints iteration step of the optimization procedure on screen
     160             : !> \param its ...
     161             : !> \param output_unit ...
     162             : !> \author Teodoro Laino [tlaino] - University of Zurich - 03.2008
     163             : ! **************************************************************************************************
     164       13633 :    SUBROUTINE gopt_f_ii(its, output_unit)
     165             : 
     166             :       INTEGER, INTENT(IN)                                :: its, output_unit
     167             : 
     168       13633 :       IF (output_unit > 0) THEN
     169        6614 :          WRITE (UNIT=output_unit, FMT="(/,T2,26('-'))")
     170        6614 :          WRITE (UNIT=output_unit, FMT="(T2,A,I6)") "OPTIMIZATION STEP: ", its
     171        6614 :          WRITE (UNIT=output_unit, FMT="(T2,26('-'))")
     172        6614 :          CALL m_flush(output_unit)
     173             :       END IF
     174             : 
     175       13633 :    END SUBROUTINE gopt_f_ii
     176             : 
     177             : ! **************************************************************************************************
     178             : !> \brief Handles the Output during an optimization run
     179             : !> \param gopt_env ...
     180             : !> \param output_unit ...
     181             : !> \param opt_energy ...
     182             : !> \param wildcard ...
     183             : !> \param its ...
     184             : !> \param used_time ...
     185             : !> \author Teodoro Laino [tlaino] - University of Zurich - 03.2008
     186             : ! **************************************************************************************************
     187        1726 :    SUBROUTINE gopt_f_io_init(gopt_env, output_unit, opt_energy, wildcard, its, used_time)
     188             :       TYPE(gopt_f_type), POINTER                         :: gopt_env
     189             :       INTEGER, INTENT(IN)                                :: output_unit
     190             :       REAL(KIND=dp)                                      :: opt_energy
     191             :       CHARACTER(LEN=5)                                   :: wildcard
     192             :       INTEGER, INTENT(IN)                                :: its
     193             :       REAL(KIND=dp)                                      :: used_time
     194             : 
     195             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     196             :       REAL(KIND=dp)                                      :: pres_int
     197             :       INTEGER(KIND=int_8)                                :: max_memory
     198             :       LOGICAL                                            :: print_memory
     199             : 
     200        1726 :       NULLIFY (para_env)
     201        1726 :       CALL section_vals_val_get(gopt_env%motion_section, "PRINT%MEMORY_INFO", l_val=print_memory)
     202        1726 :       max_memory = 0
     203        1726 :       IF (print_memory) THEN
     204        1726 :          CALL force_env_get(gopt_env%force_env, para_env=para_env)
     205        1726 :          max_memory = sample_memory(para_env)
     206             :       END IF
     207             : 
     208        3268 :       SELECT CASE (gopt_env%type_id)
     209             :       CASE (default_ts_method_id, default_minimization_method_id)
     210             :          ! Geometry Optimization (Minimization and Transition State Search)
     211        1542 :          IF (.NOT. gopt_env%dimer_rotation) THEN
     212             :             CALL write_cycle_infos(output_unit, it=its, etot=opt_energy, wildcard=wildcard, &
     213        1410 :                                    used_time=used_time, max_memory=max_memory)
     214             :          ELSE
     215             :             CALL write_rot_cycle_infos(output_unit, it=its, etot=opt_energy, dimer_env=gopt_env%dimer_env, &
     216         132 :                                        wildcard=wildcard, used_time=used_time, max_memory=max_memory)
     217             :          END IF
     218             :       CASE (default_cell_method_id)
     219             :          ! Cell Optimization
     220         164 :          pres_int = gopt_env%cell_env%pres_int
     221             :          CALL write_cycle_infos(output_unit, it=its, etot=opt_energy, pres_int=pres_int, &
     222         164 :                                 wildcard=wildcard, used_time=used_time, max_memory=max_memory)
     223             :       CASE (default_shellcore_method_id)
     224             :          CALL write_cycle_infos(output_unit, it=its, etot=opt_energy, wildcard=wildcard, &
     225        1726 :                                 used_time=used_time, max_memory=max_memory)
     226             :       END SELECT
     227             : 
     228        1726 :    END SUBROUTINE gopt_f_io_init
     229             : 
     230             : ! **************************************************************************************************
     231             : !> \brief Handles the Output during an optimization run
     232             : !> \param gopt_env ...
     233             : !> \param force_env ...
     234             : !> \param root_section ...
     235             : !> \param its ...
     236             : !> \param opt_energy ...
     237             : !> \param output_unit ...
     238             : !> \param eold ...
     239             : !> \param emin ...
     240             : !> \param wildcard ...
     241             : !> \param gopt_param ...
     242             : !> \param ndf ...
     243             : !> \param dx ...
     244             : !> \param xi ...
     245             : !> \param conv ...
     246             : !> \param pred ...
     247             : !> \param rat ...
     248             : !> \param step ...
     249             : !> \param rad ...
     250             : !> \param used_time ...
     251             : !> \author Teodoro Laino [tlaino] - University of Zurich - 03.2008
     252             : ! **************************************************************************************************
     253       27266 :    SUBROUTINE gopt_f_io(gopt_env, force_env, root_section, its, opt_energy, &
     254       13633 :                         output_unit, eold, emin, wildcard, gopt_param, ndf, dx, xi, conv, pred, rat, &
     255             :                         step, rad, used_time)
     256             :       TYPE(gopt_f_type), POINTER                         :: gopt_env
     257             :       TYPE(force_env_type), POINTER                      :: force_env
     258             :       TYPE(section_vals_type), POINTER                   :: root_section
     259             :       INTEGER, INTENT(IN)                                :: its
     260             :       REAL(KIND=dp), INTENT(IN)                          :: opt_energy
     261             :       INTEGER, INTENT(IN)                                :: output_unit
     262             :       REAL(KIND=dp)                                      :: eold, emin
     263             :       CHARACTER(LEN=5)                                   :: wildcard
     264             :       TYPE(gopt_param_type), POINTER                     :: gopt_param
     265             :       INTEGER, INTENT(IN), OPTIONAL                      :: ndf
     266             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), OPTIONAL  :: dx
     267             :       REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER     :: xi
     268             :       LOGICAL, OPTIONAL                                  :: conv
     269             :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: pred, rat, step, rad
     270             :       REAL(KIND=dp)                                      :: used_time
     271             : 
     272             :       INTEGER(KIND=int_8)                                :: max_memory
     273             :       LOGICAL                                            :: print_memory
     274             :       REAL(KIND=dp)                                      :: pres_diff, pres_diff_constr, pres_int, &
     275             :                                                             pres_tol
     276             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     277             : 
     278       13633 :       NULLIFY (para_env)
     279       13633 :       CALL section_vals_val_get(gopt_env%motion_section, "PRINT%MEMORY_INFO", l_val=print_memory)
     280       13633 :       max_memory = 0
     281       13633 :       IF (print_memory) THEN
     282       13633 :          CALL force_env_get(force_env, para_env=para_env)
     283       13633 :          max_memory = sample_memory(para_env)
     284             :       END IF
     285             : 
     286       22998 :       SELECT CASE (gopt_env%type_id)
     287             :       CASE (default_ts_method_id, default_minimization_method_id)
     288             :          ! Geometry Optimization (Minimization and Transition State Search)
     289        9365 :          IF (.NOT. gopt_env%dimer_rotation) THEN
     290             :             CALL geo_opt_io(force_env=force_env, root_section=root_section, &
     291        8639 :                             motion_section=gopt_env%motion_section, its=its, opt_energy=opt_energy)
     292             :             CALL write_cycle_infos(output_unit, its, etot=opt_energy, ediff=opt_energy - eold, &
     293             :                                    pred=pred, rat=rat, step=step, rad=rad, emin=emin, &
     294        8639 :                                    wildcard=wildcard, used_time=used_time, max_memory=max_memory)
     295             :             ! Possibly check convergence
     296        8639 :             IF (PRESENT(conv)) THEN
     297        8639 :                CPASSERT(PRESENT(ndf))
     298        8639 :                CPASSERT(PRESENT(dx))
     299        8639 :                CPASSERT(PRESENT(xi))
     300        8639 :                CALL check_converg(ndf, dx, xi, output_unit, conv, gopt_param, max_memory)
     301             :             END IF
     302             :          ELSE
     303         726 :             CALL update_dimer_vec(gopt_env%dimer_env, gopt_env%motion_section)
     304         726 :             CALL write_restart(force_env=force_env, root_section=root_section)
     305             :             CALL write_rot_cycle_infos(output_unit, its, opt_energy, opt_energy - eold, emin, gopt_env%dimer_env, &
     306         726 :                                        wildcard=wildcard, used_time=used_time, max_memory=max_memory)
     307             :             ! Possibly check convergence
     308         726 :             IF (PRESENT(conv)) THEN
     309         726 :                CPASSERT(ASSOCIATED(gopt_env%dimer_env))
     310         726 :                CALL check_rot_conv(gopt_env%dimer_env, output_unit, conv)
     311             :             END IF
     312             :          END IF
     313             :       CASE (default_cell_method_id)
     314             :          ! Cell Optimization
     315        4098 :          pres_diff = gopt_env%cell_env%pres_int - gopt_env%cell_env%pres_ext
     316        4098 :          pres_int = gopt_env%cell_env%pres_int
     317        4098 :          pres_tol = gopt_env%cell_env%pres_tol
     318             :          CALL geo_opt_io(force_env=force_env, root_section=root_section, &
     319        4098 :                          motion_section=gopt_env%motion_section, its=its, opt_energy=opt_energy)
     320             :          CALL write_cycle_infos(output_unit, its, etot=opt_energy, ediff=opt_energy - eold, &
     321             :                                 pred=pred, rat=rat, step=step, rad=rad, emin=emin, pres_int=pres_int, &
     322        4098 :                                 wildcard=wildcard, used_time=used_time, max_memory=max_memory)
     323             :          ! Possibly check convergence
     324        4098 :          IF (PRESENT(conv)) THEN
     325        4098 :             CPASSERT(PRESENT(ndf))
     326        4098 :             CPASSERT(PRESENT(dx))
     327        4098 :             CPASSERT(PRESENT(xi))
     328        4098 :             IF (gopt_env%cell_env%constraint_id == fix_none) THEN
     329        4082 :                CALL check_converg(ndf, dx, xi, output_unit, conv, gopt_param, max_memory, pres_diff, pres_tol)
     330             :             ELSE
     331          16 :                pres_diff_constr = gopt_env%cell_env%pres_constr - gopt_env%cell_env%pres_ext
     332             :                CALL check_converg(ndf, dx, xi, output_unit, conv, gopt_param, max_memory, pres_diff, &
     333          16 :                                   pres_tol, pres_diff_constr)
     334             :             END IF
     335             :          END IF
     336             :       CASE (default_shellcore_method_id)
     337             :          CALL write_cycle_infos(output_unit, its, etot=opt_energy, ediff=opt_energy - eold, &
     338             :                                 pred=pred, rat=rat, step=step, rad=rad, emin=emin, wildcard=wildcard, &
     339         170 :                                 used_time=used_time, max_memory=max_memory)
     340             :          ! Possibly check convergence
     341       13803 :          IF (PRESENT(conv)) THEN
     342         170 :             CPASSERT(PRESENT(ndf))
     343         170 :             CPASSERT(PRESENT(dx))
     344         170 :             CPASSERT(PRESENT(xi))
     345         170 :             CALL check_converg(ndf, dx, xi, output_unit, conv, gopt_param, max_memory)
     346             :          END IF
     347             :       END SELECT
     348             : 
     349       13633 :    END SUBROUTINE gopt_f_io
     350             : 
     351             : ! **************************************************************************************************
     352             : !> \brief Handles the Output at the end of an optimization run
     353             : !> \param gopt_env ...
     354             : !> \param force_env ...
     355             : !> \param x0 ...
     356             : !> \param conv ...
     357             : !> \param its ...
     358             : !> \param root_section ...
     359             : !> \param para_env ...
     360             : !> \param master ...
     361             : !> \param output_unit ...
     362             : !> \author Teodoro Laino [tlaino] - University of Zurich - 03.2008
     363             : ! **************************************************************************************************
     364        2118 :    RECURSIVE SUBROUTINE gopt_f_io_finalize(gopt_env, force_env, x0, conv, its, root_section, &
     365             :                                            para_env, master, output_unit)
     366             :       TYPE(gopt_f_type), POINTER                         :: gopt_env
     367             :       TYPE(force_env_type), POINTER                      :: force_env
     368             :       REAL(KIND=dp), DIMENSION(:), POINTER               :: x0
     369             :       LOGICAL                                            :: conv
     370             :       INTEGER                                            :: its
     371             :       TYPE(section_vals_type), POINTER                   :: root_section
     372             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     373             :       INTEGER, INTENT(IN)                                :: master, output_unit
     374             : 
     375        2118 :       IF (gopt_env%eval_opt_geo) THEN
     376        1202 :          IF (.NOT. gopt_env%dimer_rotation) THEN
     377             :             CALL write_final_info(output_unit, conv, its, gopt_env, x0, master, &
     378        1070 :                                   para_env, force_env, gopt_env%motion_section, root_section)
     379             :          ELSE
     380         132 :             CALL update_dimer_vec(gopt_env%dimer_env, gopt_env%motion_section)
     381         132 :             CALL write_restart(force_env=force_env, root_section=root_section)
     382             :          END IF
     383             :       END IF
     384             : 
     385        2118 :    END SUBROUTINE gopt_f_io_finalize
     386             : 
     387             : ! **************************************************************************************************
     388             : !> \brief ...
     389             : !> \param output_unit ...
     390             : !> \param it ...
     391             : !> \param etot ...
     392             : !> \param ediff ...
     393             : !> \param pred ...
     394             : !> \param rat ...
     395             : !> \param step ...
     396             : !> \param rad ...
     397             : !> \param emin ...
     398             : !> \param pres_int ...
     399             : !> \param wildcard ...
     400             : !> \param used_time ...
     401             : ! **************************************************************************************************
     402       14501 :    SUBROUTINE write_cycle_infos(output_unit, it, etot, ediff, pred, rat, step, rad, emin, &
     403             :                                 pres_int, wildcard, used_time, max_memory)
     404             : 
     405             :       INTEGER, INTENT(IN)                                :: output_unit, it
     406             :       REAL(KIND=dp), INTENT(IN)                          :: etot
     407             :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: ediff, pred, rat, step, rad, emin, &
     408             :                                                             pres_int
     409             :       CHARACTER(LEN=5), INTENT(IN)                       :: wildcard
     410             :       REAL(KIND=dp), INTENT(IN)                          :: used_time
     411             :       INTEGER(KIND=int_8), INTENT(IN)                    :: max_memory
     412             : 
     413             :       CHARACTER(LEN=5)                                   :: tag
     414             :       REAL(KIND=dp)                                      :: tmp_r1
     415             : 
     416       14501 :       IF (output_unit > 0) THEN
     417        7054 :          tag = "OPT| "
     418        7054 :          WRITE (UNIT=output_unit, FMT="(/,T2,A)") tag//REPEAT("*", 74)
     419             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,I25)") &
     420        7054 :             tag//"Step number", it
     421             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,A25)") &
     422        7054 :             tag//"Optimization method", wildcard
     423             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     424        7054 :             tag//"Total energy [hartree]", etot
     425        7054 :          IF (PRESENT(pres_int)) THEN
     426        2131 :             tmp_r1 = cp_unit_from_cp2k(pres_int, "bar")
     427             :             WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     428        2131 :                tag//"Internal pressure [bar]", tmp_r1
     429             :          END IF
     430        7054 :          IF (PRESENT(ediff)) THEN
     431             :             WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     432        6251 :                tag//"Effective energy change [hartree]", ediff
     433             :          END IF
     434        7054 :          IF (PRESENT(pred)) THEN
     435             :             WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     436        3297 :                tag//"Predicted energy change [hartree]", pred
     437             :          END IF
     438        7054 :          IF (PRESENT(rat)) THEN
     439             :             WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     440        3297 :                tag//"Scaling factor", rat
     441             :          END IF
     442        7054 :          IF (PRESENT(step)) THEN
     443             :             WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     444        3297 :                tag//"Step size", step
     445             :          END IF
     446        7054 :          IF (PRESENT(rad)) THEN
     447             :             WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     448        3297 :                tag//"Trust radius", rad
     449             :          END IF
     450        7054 :          IF (PRESENT(emin)) THEN
     451        6251 :             IF (etot < emin) THEN
     452             :                WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     453        5692 :                   tag//"Decrease in energy", " YES"
     454             :             ELSE
     455             :                WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     456         559 :                   tag//"Decrease in energy", "  NO"
     457             :             END IF
     458             :          END IF
     459             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.3)") &
     460        7054 :             tag//"Used time [s]", used_time
     461        7054 :          IF (it == 0) THEN
     462         797 :             WRITE (UNIT=output_unit, FMT="(T2,A)") tag//REPEAT("*", 74)
     463         797 :             IF (max_memory /= 0) THEN
     464             :                WRITE (UNIT=output_unit, FMT="(T2,A,T60,1X,I20)") &
     465         797 :                   tag//"Estimated peak process memory [MiB]", &
     466        1594 :                   (max_memory + (1024*1024) - 1)/(1024*1024)
     467             :             END IF
     468             :          END IF
     469             :       END IF
     470             : 
     471       14501 :    END SUBROUTINE write_cycle_infos
     472             : 
     473             : ! **************************************************************************************************
     474             : !> \brief ...
     475             : !> \param output_unit ...
     476             : !> \param it ...
     477             : !> \param etot ...
     478             : !> \param ediff ...
     479             : !> \param emin ...
     480             : !> \param dimer_env ...
     481             : !> \param used_time ...
     482             : !> \param wildcard ...
     483             : !> \date  01.2008
     484             : !> \author Luca Bellucci and Teodoro Laino - created [tlaino]
     485             : ! **************************************************************************************************
     486         858 :    SUBROUTINE write_rot_cycle_infos(output_unit, it, etot, ediff, emin, dimer_env, used_time, &
     487             :                                     wildcard, max_memory)
     488             : 
     489             :       INTEGER, INTENT(IN)                                :: output_unit, it
     490             :       REAL(KIND=dp), INTENT(IN)                          :: etot
     491             :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: ediff, emin
     492             :       TYPE(dimer_env_type), POINTER                      :: dimer_env
     493             :       REAL(KIND=dp), INTENT(IN)                          :: used_time
     494             :       CHARACTER(LEN=5), INTENT(IN)                       :: wildcard
     495             :       INTEGER(KIND=int_8), INTENT(IN)                    :: max_memory
     496             : 
     497             :       CHARACTER(LEN=5)                                   :: tag
     498             : 
     499         858 :       IF (output_unit > 0) THEN
     500         429 :          tag = "OPT| "
     501         429 :          WRITE (UNIT=output_unit, FMT="(/,T2,A)") tag//REPEAT("*", 74)
     502             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,I25)") &
     503         429 :             tag//"Rotational step number", it
     504             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,A25)") &
     505         429 :             tag//"Optimization method", wildcard
     506             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     507         429 :             tag//"Local curvature", dimer_env%rot%curvature, &
     508         858 :             tag//"Total rotational force", etot
     509         429 :          IF (PRESENT(ediff)) THEN
     510             :             WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     511         363 :                tag//"Rotational force change", ediff
     512             :          END IF
     513         429 :          IF (PRESENT(emin)) THEN
     514         363 :             IF (etot < emin) THEN
     515             :                WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     516         157 :                   tag//"Decrease in rotational force", " YES"
     517             :             ELSE
     518             :                WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     519         206 :                   tag//"Decrease in rotational force", "  NO"
     520             :             END IF
     521             :          END IF
     522             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.3)") &
     523         429 :             tag//"Used time [s]", used_time
     524         429 :          IF (it == 0) THEN
     525          66 :             WRITE (UNIT=output_unit, FMT="(T2,A)") tag//REPEAT("*", 74)
     526          66 :             IF (max_memory /= 0) THEN
     527             :                WRITE (UNIT=output_unit, FMT="(T2,A,T60,1X,I20)") &
     528          66 :                   tag//"Estimated peak process memory [MiB]", &
     529         132 :                   (max_memory + (1024*1024) - 1)/(1024*1024)
     530             :             END IF
     531             :          END IF
     532             :       END IF
     533             : 
     534         858 :    END SUBROUTINE write_rot_cycle_infos
     535             : 
     536             : ! **************************************************************************************************
     537             : !> \brief ...
     538             : !> \param ndf ...
     539             : !> \param dr ...
     540             : !> \param g ...
     541             : !> \param output_unit ...
     542             : !> \param conv ...
     543             : !> \param gopt_param ...
     544             : !> \param max_memory ...
     545             : !> \param pres_diff ...
     546             : !> \param pres_tol ...
     547             : !> \param pres_diff_constr ...
     548             : ! **************************************************************************************************
     549       12907 :    SUBROUTINE check_converg(ndf, dr, g, output_unit, conv, gopt_param, max_memory, pres_diff, &
     550             :                             pres_tol, pres_diff_constr)
     551             : 
     552             :       INTEGER, INTENT(IN)                                :: ndf
     553             :       REAL(KIND=dp), INTENT(IN)                          :: dr(ndf), g(ndf)
     554             :       INTEGER, INTENT(IN)                                :: output_unit
     555             :       LOGICAL, INTENT(OUT)                               :: conv
     556             :       TYPE(gopt_param_type), POINTER                     :: gopt_param
     557             :       INTEGER(KIND=int_8), INTENT(IN)                    :: max_memory
     558             :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: pres_diff, pres_tol, pres_diff_constr
     559             : 
     560             :       CHARACTER(LEN=5)                                   :: tag
     561             :       INTEGER                                            :: indf
     562             :       LOGICAL                                            :: conv_dx, conv_g, conv_p, conv_rdx, &
     563             :                                                             conv_rg
     564             :       REAL(KIND=dp)                                      :: dumm, dxcon, gcon, maxdum(4), rmsgcon, &
     565             :                                                             rmsxcon, tmp_r1
     566             : 
     567       12907 :       dxcon = gopt_param%max_dr
     568       12907 :       gcon = gopt_param%max_force
     569       12907 :       rmsgcon = gopt_param%rms_force
     570       12907 :       rmsxcon = gopt_param%rms_dr
     571             : 
     572       12907 :       conv = .FALSE.
     573       12907 :       conv_dx = .TRUE.
     574       12907 :       conv_rdx = .TRUE.
     575       12907 :       conv_g = .TRUE.
     576       12907 :       conv_rg = .TRUE.
     577       12907 :       conv_p = .TRUE.
     578             : 
     579       12907 :       dumm = 0.0_dp
     580     2936560 :       DO indf = 1, ndf
     581     2923653 :          IF (indf == 1) maxdum(1) = ABS(dr(indf))
     582     2923653 :          dumm = dumm + dr(indf)**2
     583     2923653 :          IF (ABS(dr(indf)) > dxcon) conv_dx = .FALSE.
     584     2936560 :          IF (ABS(dr(indf)) > maxdum(1)) maxdum(1) = ABS(dr(indf))
     585             :       END DO
     586             :       ! SQRT(dumm/ndf) > rmsxcon
     587       12907 :       IF (dumm > (rmsxcon*rmsxcon*ndf)) conv_rdx = .FALSE.
     588       12907 :       maxdum(2) = SQRT(dumm/ndf)
     589             : 
     590       12907 :       dumm = 0.0_dp
     591     2936560 :       DO indf = 1, ndf
     592     2923653 :          IF (indf == 1) maxdum(3) = ABS(g(indf))
     593     2923653 :          dumm = dumm + g(indf)**2
     594     2923653 :          IF (ABS(g(indf)) > gcon) conv_g = .FALSE.
     595     2936560 :          IF (ABS(g(indf)) > maxdum(3)) maxdum(3) = ABS(g(indf))
     596             :       END DO
     597             :       ! SQRT(dumm/ndf) > rmsgcon
     598       12907 :       IF (dumm > (rmsgcon*rmsgcon*ndf)) conv_rg = .FALSE.
     599       12907 :       maxdum(4) = SQRT(dumm/ndf)
     600             : 
     601       12907 :       IF (PRESENT(pres_diff_constr) .AND. PRESENT(pres_tol)) THEN
     602          16 :          conv_p = ABS(pres_diff_constr) < ABS(pres_tol)
     603       12891 :       ELSEIF (PRESENT(pres_diff) .AND. PRESENT(pres_tol)) THEN
     604        4082 :          conv_p = ABS(pres_diff) < ABS(pres_tol)
     605             :       END IF
     606             : 
     607       12907 :       IF (output_unit > 0) THEN
     608             : 
     609        6251 :          tag = "OPT| "
     610             : 
     611        6251 :          WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
     612             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     613        6251 :             tag//"Maximum step size", maxdum(1), &
     614       12502 :             tag//"Convergence limit for maximum step size", dxcon
     615        6251 :          IF (conv_dx) THEN
     616             :             WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     617        1442 :                tag//"Maximum step size is converged", " YES"
     618             :          ELSE
     619             :             WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     620        4809 :                tag//"Maximum step size is converged", "  NO"
     621             :          END IF
     622             : 
     623        6251 :          WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
     624             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     625        6251 :             tag//"RMS step size", maxdum(2), &
     626       12502 :             tag//"Convergence limit for RMS step size", rmsxcon
     627        6251 :          IF (conv_rdx) THEN
     628             :             WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     629        1575 :                tag//"RMS step size is converged", " YES"
     630             :          ELSE
     631             :             WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     632        4676 :                tag//"RMS step size is converged", "  NO"
     633             :          END IF
     634             : 
     635        6251 :          WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
     636             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     637        6251 :             tag//"Maximum gradient", maxdum(3), &
     638       12502 :             tag//"Convergence limit for maximum gradient", gcon
     639        6251 :          IF (conv_g) THEN
     640             :             WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     641        1491 :                tag//"Maximum gradient is converged", " YES"
     642             :          ELSE
     643             :             WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     644        4760 :                tag//"Maximum gradient is converged", "  NO"
     645             :          END IF
     646             : 
     647        6251 :          WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
     648             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     649        6251 :             tag//"RMS gradient", maxdum(4), &
     650       12502 :             tag//"Convergence limit for RMS gradient", rmsgcon
     651        6251 :          IF (conv_rg) THEN
     652             :             WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     653        1778 :                tag//"RMS gradient is converged", " YES"
     654             :          ELSE
     655             :             WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     656        4473 :                tag//"RMS gradient is converged", "  NO"
     657             :          END IF
     658             : 
     659        6251 :          IF (PRESENT(pres_diff) .AND. PRESENT(pres_tol)) THEN
     660        2049 :             tmp_r1 = cp_unit_from_cp2k(pres_diff, "bar")
     661        2049 :             WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
     662        2049 :             IF (PRESENT(pres_diff_constr)) THEN
     663             :                WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     664           8 :                   tag//"Pressure deviation without constraint [bar]", tmp_r1
     665           8 :                tmp_r1 = cp_unit_from_cp2k(pres_diff_constr, "bar")
     666             :                WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     667           8 :                   tag//"Pressure deviation with constraint [bar]", tmp_r1
     668             :             ELSE
     669             :                WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     670        2041 :                   tag//"Pressure deviation [bar]", tmp_r1
     671             :             END IF
     672        2049 :             tmp_r1 = cp_unit_from_cp2k(pres_tol, "bar")
     673             :             WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     674        2049 :                tag//"Pressure tolerance [bar]", tmp_r1
     675        2049 :             IF (conv_p) THEN
     676             :                WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     677         307 :                   tag//"Pressure is converged", " YES"
     678             :             ELSE
     679             :                WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     680        1742 :                   tag//"Pressure is converged", "  NO"
     681             :             END IF
     682             :          END IF
     683             : 
     684        6251 :          WRITE (UNIT=output_unit, FMT="(T2,A)") tag//REPEAT("*", 74)
     685             : 
     686        6251 :          IF (max_memory /= 0) THEN
     687             :             WRITE (UNIT=output_unit, FMT="(T2,A,T60,1X,I20)") &
     688        6251 :                tag//"Estimated peak process memory after this step [MiB]", &
     689       12502 :                (max_memory + (1024*1024) - 1)/(1024*1024)
     690             :          END IF
     691             : 
     692             :       END IF
     693             : 
     694       12907 :       IF (conv_dx .AND. conv_rdx .AND. conv_g .AND. conv_rg .AND. conv_p) conv = .TRUE.
     695             : 
     696       12907 :       IF ((conv) .AND. (output_unit > 0)) THEN
     697         653 :          WRITE (UNIT=output_unit, FMT="(/,T2,A)") REPEAT("*", 79)
     698             :          WRITE (UNIT=output_unit, FMT="(T2,A,T25,A,T78,A)") &
     699         653 :             "***", "GEOMETRY OPTIMIZATION COMPLETED", "***"
     700         653 :          WRITE (UNIT=output_unit, FMT="(T2,A)") REPEAT("*", 79)
     701             :       END IF
     702             : 
     703       12907 :    END SUBROUTINE check_converg
     704             : 
     705             : ! **************************************************************************************************
     706             : !> \brief ...
     707             : !> \param dimer_env ...
     708             : !> \param output_unit ...
     709             : !> \param conv ...
     710             : !> \date  01.2008
     711             : !> \author Luca Bellucci and Teodoro Laino - created [tlaino]
     712             : ! **************************************************************************************************
     713         726 :    SUBROUTINE check_rot_conv(dimer_env, output_unit, conv)
     714             : 
     715             :       TYPE(dimer_env_type), POINTER                      :: dimer_env
     716             :       INTEGER, INTENT(IN)                                :: output_unit
     717             :       LOGICAL, INTENT(OUT)                               :: conv
     718             : 
     719             :       CHARACTER(LEN=5)                                   :: tag
     720             : 
     721         726 :       conv = (ABS(dimer_env%rot%angle2) < dimer_env%rot%angle_tol)
     722             : 
     723         726 :       IF (output_unit > 0) THEN
     724         363 :          tag = "OPT| "
     725         363 :          WRITE (UNIT=output_unit, FMT="(T2,A)") TRIM(tag)
     726             :          WRITE (UNIT=output_unit, FMT="(T2,A,T55,1X,F25.10)") &
     727         363 :             tag//"Predicted angle step size", dimer_env%rot%angle1, &
     728         363 :             tag//"Effective angle step size", dimer_env%rot%angle2, &
     729         726 :             tag//"Convergence limit for angle step size", dimer_env%rot%angle_tol
     730         363 :          IF (conv) THEN
     731             :             WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     732          55 :                tag//"Angle step size is converged", " YES"
     733             :          ELSE
     734             :             WRITE (UNIT=output_unit, FMT="(T2,A,T77,A4)") &
     735         308 :                tag//"Angle step size is converged", "  NO"
     736             :          END IF
     737         363 :          WRITE (UNIT=output_unit, FMT="(T2,A)") tag//REPEAT("*", 74)
     738             :       END IF
     739             : 
     740         726 :       IF ((conv) .AND. (output_unit > 0)) THEN
     741          55 :          WRITE (UNIT=output_unit, FMT="(/,T2,A)") REPEAT("*", 79)
     742             :          WRITE (UNIT=output_unit, FMT="(T2,A,T25,A,T78,A)") &
     743          55 :             "***", "ROTATION OPTIMIZATION COMPLETED", "***"
     744          55 :          WRITE (UNIT=output_unit, FMT="(T2,A)") REPEAT("*", 79)
     745             :       END IF
     746             : 
     747         726 :    END SUBROUTINE check_rot_conv
     748             : 
     749             : ! **************************************************************************************************
     750             : !> \brief ...
     751             : !> \param output_unit ...
     752             : !> \param conv ...
     753             : !> \param it ...
     754             : !> \param gopt_env ...
     755             : !> \param x0 ...
     756             : !> \param master ...
     757             : !> \param para_env ...
     758             : !> \param force_env ...
     759             : !> \param motion_section ...
     760             : !> \param root_section ...
     761             : !> \date  11.2007
     762             : !> \author Teodoro Laino [tlaino] - University of Zurich
     763             : ! **************************************************************************************************
     764        1070 :    RECURSIVE SUBROUTINE write_final_info(output_unit, conv, it, gopt_env, x0, master, para_env, force_env, &
     765             :                                          motion_section, root_section)
     766             :       INTEGER, INTENT(IN)                                :: output_unit
     767             :       LOGICAL, INTENT(IN)                                :: conv
     768             :       INTEGER, INTENT(INOUT)                             :: it
     769             :       TYPE(gopt_f_type), POINTER                         :: gopt_env
     770             :       REAL(KIND=dp), DIMENSION(:), POINTER               :: x0
     771             :       INTEGER, INTENT(IN)                                :: master
     772             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     773             :       TYPE(force_env_type), POINTER                      :: force_env
     774             :       TYPE(section_vals_type), POINTER                   :: motion_section, root_section
     775             : 
     776             :       REAL(KIND=dp)                                      :: etot
     777             :       TYPE(cell_type), POINTER                           :: cell
     778             :       TYPE(cp_subsys_type), POINTER                      :: subsys
     779             :       TYPE(particle_list_type), POINTER                  :: particles
     780        1070 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     781             : 
     782        1070 :       CALL force_env_get(force_env, cell=cell, subsys=subsys)
     783        1070 :       CALL cp_subsys_get(subsys=subsys, particles=particles)
     784        1070 :       particle_set => particles%els
     785        1070 :       IF (conv) THEN
     786         391 :          it = it + 1
     787         391 :          CALL write_structure_data(particle_set, cell, motion_section)
     788         391 :          CALL write_restart(force_env=force_env, root_section=root_section)
     789             : 
     790         391 :          IF (output_unit > 0) &
     791         201 :             WRITE (UNIT=output_unit, FMT="(/,T20,' Reevaluating energy at the minimum')")
     792             : 
     793             :          CALL cp_eval_at(gopt_env, x0, f=etot, master=master, final_evaluation=.TRUE., &
     794         391 :                          para_env=para_env)
     795         391 :          CALL write_geo_traj(force_env, root_section, it, etot)
     796             :       END IF
     797             : 
     798        1070 :    END SUBROUTINE write_final_info
     799             : 
     800             : ! **************************************************************************************************
     801             : !> \brief  Specific driver for dumping trajectory during a GEO_OPT
     802             : !> \param force_env ...
     803             : !> \param root_section ...
     804             : !> \param it ...
     805             : !> \param etot ...
     806             : !> \date   11.2007
     807             : !> \par    History
     808             : !>         09.2010: Output of core and shell positions and forces (MK)
     809             : !> \author Teodoro Laino [tlaino] - University of Zurich
     810             : ! **************************************************************************************************
     811       26256 :    SUBROUTINE write_geo_traj(force_env, root_section, it, etot)
     812             : 
     813             :       TYPE(force_env_type), POINTER                      :: force_env
     814             :       TYPE(section_vals_type), POINTER                   :: root_section
     815             :       INTEGER, INTENT(IN)                                :: it
     816             :       REAL(KIND=dp), INTENT(IN)                          :: etot
     817             : 
     818             :       LOGICAL                                            :: shell_adiabatic, shell_present
     819             :       TYPE(atomic_kind_list_type), POINTER               :: atomic_kinds
     820       13128 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     821             :       TYPE(cp_subsys_type), POINTER                      :: subsys
     822             :       TYPE(particle_list_type), POINTER                  :: core_particles, shell_particles
     823             : 
     824       13128 :       NULLIFY (atomic_kinds)
     825       13128 :       NULLIFY (atomic_kind_set)
     826       13128 :       NULLIFY (core_particles)
     827       13128 :       NULLIFY (shell_particles)
     828       13128 :       NULLIFY (subsys)
     829             : 
     830       13128 :       CALL write_trajectory(force_env, root_section, it, 0.0_dp, 0.0_dp, etot)
     831             :       ! Print Force
     832       13128 :       CALL write_trajectory(force_env, root_section, it, 0.0_dp, 0.0_dp, etot, "FORCES", middle_name="frc")
     833       13128 :       CALL force_env_get(force_env, subsys=subsys)
     834       13128 :       CALL cp_subsys_get(subsys, atomic_kinds=atomic_kinds)
     835       13128 :       atomic_kind_set => atomic_kinds%els
     836             :       CALL get_atomic_kind_set(atomic_kind_set, &
     837             :                                shell_present=shell_present, &
     838       13128 :                                shell_adiabatic=shell_adiabatic)
     839       13128 :       IF (shell_present) THEN
     840             :          CALL cp_subsys_get(subsys, &
     841             :                             core_particles=core_particles, &
     842        4106 :                             shell_particles=shell_particles)
     843             :          CALL write_trajectory(force_env, root_section, it=it, time=0.0_dp, dtime=0.0_dp, &
     844             :                                etot=etot, pk_name="SHELL_TRAJECTORY", middle_name="shpos", &
     845        4106 :                                particles=shell_particles)
     846        4106 :          IF (shell_adiabatic) THEN
     847             :             CALL write_trajectory(force_env, root_section, it=it, time=0.0_dp, dtime=0.0_dp, &
     848             :                                   etot=etot, pk_name="SHELL_FORCES", middle_name="shfrc", &
     849        4106 :                                   particles=shell_particles)
     850             :             CALL write_trajectory(force_env, root_section, it=it, time=0.0_dp, dtime=0.0_dp, &
     851             :                                   etot=etot, pk_name="CORE_TRAJECTORY", middle_name="copos", &
     852        4106 :                                   particles=core_particles)
     853             :             CALL write_trajectory(force_env, root_section, it=it, time=0.0_dp, dtime=0.0_dp, &
     854             :                                   etot=etot, pk_name="CORE_FORCES", middle_name="cofrc", &
     855        4106 :                                   particles=core_particles)
     856             :          END IF
     857             :       END IF
     858             : 
     859       13128 :    END SUBROUTINE write_geo_traj
     860             : 
     861             : ! **************************************************************************************************
     862             : !> \brief ...
     863             : !> \param gopt_env ...
     864             : !> \param output_unit ...
     865             : !> \param label ...
     866             : !> \date  01.2008
     867             : !> \author Teodoro Laino [tlaino] - University of Zurich
     868             : ! **************************************************************************************************
     869        2118 :    SUBROUTINE print_geo_opt_header(gopt_env, output_unit, label)
     870             : 
     871             :       TYPE(gopt_f_type), POINTER                         :: gopt_env
     872             :       INTEGER, INTENT(IN)                                :: output_unit
     873             :       CHARACTER(LEN=*), INTENT(IN)                       :: label
     874             : 
     875             :       CHARACTER(LEN=default_string_length)               :: my_format, my_label
     876             :       INTEGER                                            :: ix
     877             : 
     878        2118 :       IF (output_unit > 0) THEN
     879        1065 :          WRITE (UNIT=output_unit, FMT="(/,T2,A)") REPEAT("*", 79)
     880        1065 :          IF (gopt_env%dimer_rotation) THEN
     881          66 :             my_label = "OPTIMIZING DIMER ROTATION"
     882             :          ELSE
     883         999 :             my_label = "STARTING "//gopt_env%tag(1:8)//" OPTIMIZATION"
     884             :          END IF
     885             : 
     886        1065 :          ix = (80 - 7 - LEN_TRIM(my_label))/2
     887        1065 :          ix = ix + 5
     888        1065 :          my_format = "(T2,A,T"//cp_to_string(ix)//",A,T78,A)"
     889        1065 :          WRITE (UNIT=output_unit, FMT=TRIM(my_format)) "***", TRIM(my_label), "***"
     890             : 
     891        1065 :          ix = (80 - 7 - LEN_TRIM(label))/2
     892        1065 :          ix = ix + 5
     893        1065 :          my_format = "(T2,A,T"//cp_to_string(ix)//",A,T78,A)"
     894        1065 :          WRITE (UNIT=output_unit, FMT=TRIM(my_format)) "***", TRIM(label), "***"
     895             : 
     896        1065 :          WRITE (UNIT=output_unit, FMT="(T2,A)") REPEAT("*", 79)
     897        1065 :          CALL m_flush(output_unit)
     898             :       END IF
     899        2118 :    END SUBROUTINE print_geo_opt_header
     900             : 
     901             : ! **************************************************************************************************
     902             : !> \brief ...
     903             : !> \param gopt_env ...
     904             : !> \param output_unit ...
     905             : !> \date  01.2008
     906             : !> \author Teodoro Laino [tlaino] - University of Zurich
     907             : ! **************************************************************************************************
     908         701 :    SUBROUTINE print_geo_opt_nc(gopt_env, output_unit)
     909             : 
     910             :       TYPE(gopt_f_type), POINTER                         :: gopt_env
     911             :       INTEGER, INTENT(IN)                                :: output_unit
     912             : 
     913         701 :       IF (output_unit > 0) THEN
     914             :          WRITE (UNIT=output_unit, FMT="(/,T2,A)") &
     915         351 :             "*** MAXIMUM NUMBER OF OPTIMIZATION STEPS REACHED ***"
     916         351 :          IF (.NOT. gopt_env%dimer_rotation) THEN
     917             :             WRITE (UNIT=output_unit, FMT="(T2,A)") &
     918         340 :                "***        EXITING GEOMETRY OPTIMIZATION         ***"
     919             :          ELSE
     920             :             WRITE (UNIT=output_unit, FMT="(T2,A)") &
     921          11 :                "***        EXITING ROTATION OPTIMIZATION         ***"
     922             :          END IF
     923         351 :          CALL m_flush(output_unit)
     924             :       END IF
     925             : 
     926         701 :    END SUBROUTINE print_geo_opt_nc
     927             : 
     928             : ! **************************************************************************************************
     929             : !> \brief   Prints information during GEO_OPT common to all optimizers
     930             : !> \param force_env ...
     931             : !> \param root_section ...
     932             : !> \param motion_section ...
     933             : !> \param its ...
     934             : !> \param opt_energy ...
     935             : !> \date    02.2008
     936             : !> \author  Teodoro Laino [tlaino] - University of Zurich
     937             : !> \version 1.0
     938             : ! **************************************************************************************************
     939       12737 :    SUBROUTINE geo_opt_io(force_env, root_section, motion_section, its, opt_energy)
     940             : 
     941             :       TYPE(force_env_type), POINTER                      :: force_env
     942             :       TYPE(section_vals_type), POINTER                   :: root_section, motion_section
     943             :       INTEGER, INTENT(IN)                                :: its
     944             :       REAL(KIND=dp), INTENT(IN)                          :: opt_energy
     945             : 
     946             :       TYPE(atomic_kind_list_type), POINTER               :: atomic_kinds
     947       12737 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     948             :       TYPE(cell_type), POINTER                           :: cell
     949             :       TYPE(cp_subsys_type), POINTER                      :: subsys
     950             :       TYPE(distribution_1d_type), POINTER                :: local_particles
     951             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     952             :       TYPE(particle_list_type), POINTER                  :: particles
     953       12737 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     954             :       TYPE(virial_type), POINTER                         :: virial
     955             : 
     956       12737 :       NULLIFY (para_env, atomic_kind_set, subsys, particle_set, &
     957       12737 :                local_particles, atomic_kinds, particles)
     958             : 
     959             :       ! Write Restart File
     960       12737 :       CALL write_restart(force_env=force_env, root_section=root_section)
     961             : 
     962             :       ! Write Trajectory
     963       12737 :       CALL write_geo_traj(force_env, root_section, its, opt_energy)
     964             : 
     965             :       ! Write the stress Tensor
     966             :       CALL force_env_get(force_env, cell=cell, para_env=para_env, &
     967       12737 :                          subsys=subsys)
     968             :       CALL cp_subsys_get(subsys=subsys, atomic_kinds=atomic_kinds, local_particles=local_particles, &
     969       12737 :                          particles=particles, virial=virial)
     970       12737 :       atomic_kind_set => atomic_kinds%els
     971       12737 :       particle_set => particles%els
     972             :       CALL virial_evaluate(atomic_kind_set, particle_set, local_particles, &
     973       12737 :                            virial, para_env)
     974       12737 :       CALL write_stress_tensor(virial, cell, motion_section, its, 0.0_dp)
     975             : 
     976             :       ! Write the cell
     977       12737 :       CALL write_simulation_cell(cell, motion_section, its, 0.0_dp)
     978             : 
     979       12737 :    END SUBROUTINE geo_opt_io
     980             : 
     981             : ! **************************************************************************************************
     982             : !> \brief   Apply coordinate transformations after cell (shape) change
     983             : !> \param gopt_env ...
     984             : !> \param cell ...
     985             : !> \param x ...
     986             : !> \param update_forces ...
     987             : !> \date    05.11.2012 (revised version of unbiase_coordinates moved here, MK)
     988             : !> \author  Matthias Krack
     989             : !> \version 1.0
     990             : ! **************************************************************************************************
     991        8894 :    SUBROUTINE apply_cell_change(gopt_env, cell, x, update_forces)
     992             : 
     993             :       TYPE(gopt_f_type), POINTER                         :: gopt_env
     994             :       TYPE(cell_type), POINTER                           :: cell
     995             :       REAL(KIND=dp), DIMENSION(:), POINTER               :: x
     996             :       LOGICAL, INTENT(IN)                                :: update_forces
     997             : 
     998             :       INTEGER                                            :: i, iatom, idg, j, natom, nparticle, &
     999             :                                                             shell_index
    1000             :       REAL(KIND=dp)                                      :: fc, fs, mass
    1001             :       REAL(KIND=dp), DIMENSION(3)                        :: s
    1002             :       TYPE(cell_type), POINTER                           :: cell_ref
    1003             :       TYPE(cp_subsys_type), POINTER                      :: subsys
    1004             :       TYPE(particle_list_type), POINTER                  :: core_particles, particles, &
    1005             :                                                             shell_particles
    1006             : 
    1007        8894 :       NULLIFY (cell_ref)
    1008        8894 :       NULLIFY (core_particles)
    1009        8894 :       NULLIFY (particles)
    1010        8894 :       NULLIFY (shell_particles)
    1011        8894 :       NULLIFY (subsys)
    1012             : 
    1013        8894 :       natom = force_env_get_natom(gopt_env%force_env)
    1014        8894 :       nparticle = force_env_get_nparticle(gopt_env%force_env)
    1015             :       CALL force_env_get(gopt_env%force_env, &
    1016        8894 :                          subsys=subsys)
    1017             :       CALL cp_subsys_get(subsys=subsys, &
    1018             :                          core_particles=core_particles, &
    1019             :                          particles=particles, &
    1020        8894 :                          shell_particles=shell_particles)
    1021             : 
    1022             :       ! Retrieve the reference cell
    1023        8894 :       CALL cell_create(cell_ref)
    1024        8894 :       CALL cell_copy(cell, cell_ref, tag="CELL_OPT_REF")
    1025             : 
    1026             :       ! Load the updated cell information
    1027       16848 :       SELECT CASE (gopt_env%cell_method_id)
    1028             :       CASE (default_cell_direct_id)
    1029        7954 :          idg = 3*nparticle
    1030        7954 :          CALL init_cell(cell_ref, hmat=gopt_env%h_ref)
    1031             :       CASE (default_cell_geo_opt_id, default_cell_md_id)
    1032        8894 :          idg = 0
    1033             :       END SELECT
    1034        8894 :       CPASSERT((SIZE(x) == idg + 6))
    1035             : 
    1036        8894 :       IF (update_forces) THEN
    1037             : 
    1038             :          ! Transform particle forces back to reference cell
    1039             :          idg = 1
    1040      231854 :          DO iatom = 1, natom
    1041      228840 :             CALL real_to_scaled(s, x(idg:idg + 2), cell)
    1042      228840 :             CALL scaled_to_real(x(idg:idg + 2), s, cell_ref)
    1043      231854 :             idg = idg + 3
    1044             :          END DO
    1045             : 
    1046             :       ELSE
    1047             : 
    1048             :          ! Update cell
    1049       23520 :          DO i = 1, 3
    1050       58800 :             DO j = 1, i
    1051       35280 :                idg = idg + 1
    1052       52920 :                cell%hmat(j, i) = x(idg)
    1053             :             END DO
    1054             :          END DO
    1055        5880 :          CALL init_cell(cell)
    1056        5880 :          CALL cp_subsys_set(subsys, cell=cell)
    1057             : 
    1058             :          ! Retrieve particle coordinates for the current cell
    1059        5880 :          SELECT CASE (gopt_env%cell_method_id)
    1060             :          CASE (default_cell_direct_id)
    1061             :             idg = 1
    1062      434492 :             DO iatom = 1, natom
    1063      429552 :                CALL real_to_scaled(s, x(idg:idg + 2), cell_ref)
    1064      429552 :                shell_index = particles%els(iatom)%shell_index
    1065      429552 :                IF (shell_index == 0) THEN
    1066      138588 :                   CALL scaled_to_real(particles%els(iatom)%r, s, cell)
    1067             :                ELSE
    1068      290964 :                   CALL scaled_to_real(core_particles%els(shell_index)%r, s, cell)
    1069      290964 :                   i = 3*(natom + shell_index - 1) + 1
    1070      290964 :                   CALL real_to_scaled(s, x(i:i + 2), cell_ref)
    1071      290964 :                   CALL scaled_to_real(shell_particles%els(shell_index)%r, s, cell)
    1072             :                   ! Update atomic position due to core and shell motion
    1073      290964 :                   mass = particles%els(iatom)%atomic_kind%mass
    1074      290964 :                   fc = core_particles%els(shell_index)%atomic_kind%shell%mass_core/mass
    1075      290964 :                   fs = shell_particles%els(shell_index)%atomic_kind%shell%mass_shell/mass
    1076             :                   particles%els(iatom)%r(1:3) = fc*core_particles%els(shell_index)%r(1:3) + &
    1077     2327712 :                                                 fs*shell_particles%els(shell_index)%r(1:3)
    1078             :                END IF
    1079      434492 :                idg = idg + 3
    1080             :             END DO
    1081             :          CASE (default_cell_geo_opt_id, default_cell_md_id)
    1082       46096 :             DO iatom = 1, natom
    1083       39276 :                shell_index = particles%els(iatom)%shell_index
    1084       40216 :                IF (shell_index == 0) THEN
    1085       35244 :                   CALL real_to_scaled(s, particles%els(iatom)%r, cell_ref)
    1086       35244 :                   CALL scaled_to_real(particles%els(iatom)%r, s, cell)
    1087             :                ELSE
    1088        4032 :                   CALL real_to_scaled(s, core_particles%els(shell_index)%r, cell_ref)
    1089        4032 :                   CALL scaled_to_real(core_particles%els(shell_index)%r, s, cell)
    1090        4032 :                   i = 3*(natom + shell_index - 1) + 1
    1091        4032 :                   CALL real_to_scaled(s, shell_particles%els(shell_index)%r, cell_ref)
    1092        4032 :                   CALL scaled_to_real(shell_particles%els(shell_index)%r, s, cell)
    1093             :                   ! Update atomic position due to core and shell motion
    1094        4032 :                   mass = particles%els(iatom)%atomic_kind%mass
    1095        4032 :                   fc = core_particles%els(shell_index)%atomic_kind%shell%mass_core/mass
    1096        4032 :                   fs = shell_particles%els(shell_index)%atomic_kind%shell%mass_shell/mass
    1097             :                   particles%els(iatom)%r(1:3) = fc*core_particles%els(shell_index)%r(1:3) + &
    1098       32256 :                                                 fs*shell_particles%els(shell_index)%r(1:3)
    1099             :                END IF
    1100             :             END DO
    1101             :          END SELECT
    1102             : 
    1103             :       END IF
    1104             : 
    1105        8894 :       CALL cell_release(cell_ref)
    1106             : 
    1107        8894 :    END SUBROUTINE apply_cell_change
    1108             : 
    1109             : END MODULE gopt_f_methods

Generated by: LCOV version 1.15