LCOV - code coverage report
Current view: top level - src/motion - gopt_f77_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:7641cd9) Lines: 99.0 % 97 96
Test Date: 2026-05-25 07:16:39 Functions: 100.0 % 1 1

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief evaluete the potential energy and its gradients using an array
      10              : !>      with same dimension as the particle_set
      11              : !> \param gopt_env the geometry optimization environment
      12              : !> \param x the position where the function should be evaluated
      13              : !> \param f the function value
      14              : !> \param gradient the value of its gradient
      15              : !> \param master ...
      16              : !> \param final_evaluation ...
      17              : !> \param para_env ...
      18              : !> \par History
      19              : !>       CELL OPTIMIZATION:  Teodoro Laino [tlaino] - University of Zurich - 03.2008
      20              : !>       07.2020 Pierre Cazade [pcazade] Space Group Symmetry
      21              : !> \author Teodoro Laino [tlaino] - University of Zurich - 01.2008
      22              : ! **************************************************************************************************
      23        16539 : SUBROUTINE cp_eval_at(gopt_env, x, f, gradient, master, &
      24              :                       final_evaluation, para_env)
      25              : 
      26              :    USE cp_log_handling, ONLY: cp_logger_type
      27              :    USE averages_types, ONLY: average_quantities_type, &
      28              :                              create_averages, &
      29              :                              release_averages
      30              :    USE bibliography, ONLY: Henkelman1999, &
      31              :                            cite_reference
      32              :    USE cell_opt_utils, ONLY: get_dg_dh, &
      33              :                              gopt_new_logger_create, &
      34              :                              gopt_new_logger_release, &
      35              :                              rescale_new_cell_volume
      36              :    USE cell_types, ONLY: cell_type
      37              :    USE cell_methods, ONLY: write_cell
      38              :    USE message_passing, ONLY: mp_para_env_type
      39              :    USE cp_subsys_types, ONLY: cp_subsys_get, &
      40              :                               cp_subsys_type, &
      41              :                               pack_subsys_particles, &
      42              :                               unpack_subsys_particles
      43              :    USE dimer_methods, ONLY: cp_eval_at_ts
      44              :    USE force_env_methods, ONLY: force_env_calc_energy_force
      45              :    USE force_env_types, ONLY: force_env_get, &
      46              :                               force_env_get_nparticle
      47              :    USE geo_opt, ONLY: cp_geo_opt
      48              :    USE gopt_f_types, ONLY: gopt_f_type
      49              :    USE gopt_f_methods, ONLY: apply_cell_change
      50              :    USE input_constants, ONLY: default_minimization_method_id, &
      51              :                               default_ts_method_id, &
      52              :                               default_cell_method_id, &
      53              :                               default_shellcore_method_id, &
      54              :                               fix_none
      55              :    USE input_section_types, ONLY: section_vals_get, &
      56              :                                   section_vals_get_subs_vals, &
      57              :                                   section_vals_type, &
      58              :                                   section_vals_val_get
      59              :    USE md_run, ONLY: qs_mol_dyn
      60              :    USE kinds, ONLY: dp
      61              :    USE particle_list_types, ONLY: particle_list_type
      62              :    USE particle_methods, ONLY: write_structure_data
      63              :    USE virial_methods, ONLY: virial_update
      64              :    USE virial_types, ONLY: virial_type
      65              :    USE cp_log_handling, ONLY: cp_add_default_logger, &
      66              :                               cp_rm_default_logger
      67              :    USE space_groups_types, ONLY: spgr_type
      68              :    USE space_groups, ONLY: spgr_apply_rotations_stress, &
      69              :                            spgr_apply_rotations_coord, &
      70              :                            spgr_apply_rotations_force, &
      71              :                            spgr_write_stress_tensor
      72              : 
      73              : #include "../base/base_uses.f90"
      74              :    IMPLICIT NONE
      75              :    TYPE(gopt_f_type), POINTER               :: gopt_env
      76              :    REAL(KIND=dp), DIMENSION(:), POINTER     :: x
      77              :    REAL(KIND=dp), INTENT(OUT), OPTIONAL     :: f
      78              :    REAL(KIND=dp), DIMENSION(:), OPTIONAL, &
      79              :       POINTER                                :: gradient
      80              :    INTEGER, INTENT(IN)                      :: master
      81              :    LOGICAL, INTENT(IN), OPTIONAL            :: final_evaluation
      82              :    TYPE(mp_para_env_type), POINTER          :: para_env
      83              : 
      84              :    CHARACTER(len=*), PARAMETER :: routineN = 'cp_eval_at'
      85              : 
      86              :    INTEGER                                  :: handle, idg, idir, ip, &
      87              :                                                nparticle, nsize, shell_index
      88              :    LOGICAL                                  :: my_final_evaluation
      89              :    REAL(KIND=dp)                            :: f_ts, potential_energy
      90              :    REAL(KIND=dp), DIMENSION(3, 3)           :: av_ptens
      91        16539 :    REAL(KIND=dp), DIMENSION(:), POINTER     :: cell_gradient, gradient_ts
      92              :    TYPE(cell_type), POINTER                 :: cell
      93              :    TYPE(cp_subsys_type), POINTER            :: subsys
      94              :    TYPE(particle_list_type), POINTER        :: core_particles, particles, &
      95              :                                                shell_particles
      96              :    TYPE(virial_type), POINTER               :: virial
      97              :    TYPE(cp_logger_type), POINTER            :: new_logger
      98              :    TYPE(average_quantities_type), POINTER   :: averages
      99              :    TYPE(spgr_type), POINTER                 :: spgr
     100              : 
     101        16539 :    NULLIFY (averages)
     102        16539 :    NULLIFY (cell)
     103        16539 :    NULLIFY (core_particles)
     104        16539 :    NULLIFY (gradient_ts)
     105        16539 :    NULLIFY (particles)
     106        16539 :    NULLIFY (shell_particles)
     107        16539 :    NULLIFY (subsys)
     108        16539 :    NULLIFY (virial)
     109        16539 :    NULLIFY (new_logger)
     110        16539 :    NULLIFY (spgr)
     111              : 
     112        16539 :    CALL timeset(routineN, handle)
     113              : 
     114        16539 :    CALL force_env_get(gopt_env%force_env, subsys=subsys, cell=cell)
     115              :    CALL cp_subsys_get(subsys, &
     116              :                       core_particles=core_particles, &
     117              :                       particles=particles, &
     118              :                       shell_particles=shell_particles, &
     119        16539 :                       virial=virial)
     120              : 
     121        16539 :    spgr => gopt_env%spgr
     122              : 
     123        16539 :    my_final_evaluation = .FALSE.
     124        16539 :    IF (PRESENT(final_evaluation)) my_final_evaluation = final_evaluation
     125              : 
     126        24810 :    SELECT CASE (gopt_env%type_id)
     127              :    CASE (default_minimization_method_id, default_ts_method_id)
     128         8271 :       CALL unpack_subsys_particles(subsys=subsys, r=x)
     129         8271 :       CALL write_structure_data(particles%els, cell, gopt_env%motion_section)
     130        14726 :       SELECT CASE (gopt_env%type_id)
     131              :       CASE (default_minimization_method_id)
     132              :          ! Geometry Minimization
     133              :          CALL force_env_calc_energy_force(gopt_env%force_env, &
     134              :                                           calc_force=PRESENT(gradient), &
     135         6455 :                                           require_consistent_energy_force=gopt_env%require_consistent_energy_force)
     136              :          ! Possibly take the potential energy
     137         6455 :          IF (PRESENT(f)) THEN
     138         6455 :             CALL force_env_get(gopt_env%force_env, potential_energy=f)
     139              :          END IF
     140              :          ! Possibly take the gradients
     141         6455 :          IF (PRESENT(gradient)) THEN
     142         5905 :             IF (master == para_env%mepos) THEN ! we are on the master
     143         5754 :                CALL pack_subsys_particles(subsys=subsys, f=gradient, fscale=-1.0_dp)
     144         5754 :                IF (spgr%keep_space_group) THEN
     145            8 :                   CALL spgr_apply_rotations_force(spgr, gradient)
     146            8 :                   CALL unpack_subsys_particles(subsys=subsys, f=gradient, fscale=-1.0_dp)
     147              :                END IF
     148              :             END IF
     149              :          END IF
     150              :       CASE (default_ts_method_id)
     151              :          ! Transition State Optimization
     152         5448 :          ALLOCATE (gradient_ts(particles%n_els*3))
     153              :          ! Real calculation of energy and forces for transition state optimization:
     154              :          ! When doing dimer methods forces have to be always computed since the function
     155              :          ! to minimize is not the energy but the effective force
     156         1816 :          CALL cp_eval_at_ts(gopt_env, x, f_ts, gradient_ts, calc_force=.TRUE.)
     157         1816 :          CALL cite_reference(Henkelman1999)
     158              :          ! Possibly take the potential energy
     159         1816 :          IF (PRESENT(f)) f = f_ts
     160              :          ! Possibly take the gradients
     161         1816 :          IF (PRESENT(gradient)) THEN
     162          854 :             IF (master == para_env%mepos) THEN ! we are on the master
     163          854 :                CPASSERT(ASSOCIATED(gradient))
     164        29452 :                gradient = gradient_ts
     165              :             END IF
     166              :          END IF
     167        10087 :          DEALLOCATE (gradient_ts)
     168              :       END SELECT
     169              :       ! This call is necessary for QM/MM if a Translation is applied
     170              :       ! this makes the geometry optimizer consistent
     171         8271 :       CALL unpack_subsys_particles(subsys=subsys, r=x)
     172              :    CASE (default_cell_method_id)
     173              :       ! Check for VIRIAL
     174         7928 :       IF (.NOT. virial%pv_availability) &
     175              :          CALL cp_abort(__LOCATION__, &
     176              :                        "For a cell optimization task with CELL_OPT/TYPE "// &
     177              :                        "DIRECT_CELL_OPT, the FORCE_EVAL/STRESS_TENSOR "// &
     178              :                        "keyword MUST be defined in the input file for the "// &
     179            0 :                        "evaluation of the stress tensor, but none is found!")
     180         7928 :       IF (gopt_env%cell_env%keep_volume) THEN
     181         2278 :          nparticle = force_env_get_nparticle(gopt_env%force_env)
     182         2278 :          idg = 3*nparticle
     183         2278 :          CALL rescale_new_cell_volume(cell%deth, x, idg)
     184              :       END IF
     185              : 
     186         7928 :       CALL apply_cell_change(gopt_env, cell, x, update_forces=.FALSE.)
     187              :       ! Possibly output the new cell used for the next calculation
     188         7928 :       CALL write_cell(cell, gopt_env%geo_section)
     189              :       ! Compute the pressure tensor
     190         7928 :       BLOCK
     191              :          TYPE(virial_type) :: virial_avg
     192              :          CALL force_env_calc_energy_force(gopt_env%force_env, &
     193              :                                           calc_force=PRESENT(gradient), &
     194         7928 :                                           require_consistent_energy_force=gopt_env%require_consistent_energy_force)
     195              :          ! Possibly take the potential energy
     196         7928 :          CALL force_env_get(gopt_env%force_env, potential_energy=potential_energy)
     197         7928 :          virial_avg = virial
     198         7928 :          CALL virial_update(virial_avg, subsys, para_env)
     199         7928 :          IF (PRESENT(f)) THEN
     200         7928 :             CALL force_env_get(gopt_env%force_env, potential_energy=f)
     201              :          END IF
     202              :          ! Possibly take the gradients
     203      1966144 :          IF (PRESENT(gradient)) THEN
     204         6606 :             CPASSERT(ANY(virial_avg%pv_total /= 0))
     205              :             ! Convert the average ptens
     206        85878 :             av_ptens(:, :) = virial_avg%pv_total(:, :)/cell%deth
     207         6606 :             IF (master == para_env%mepos) THEN ! we are on the master
     208         5062 :                CPASSERT(ASSOCIATED(gradient))
     209         5062 :                nparticle = force_env_get_nparticle(gopt_env%force_env)
     210         5062 :                nsize = 3*nparticle
     211         5062 :                CPASSERT((SIZE(gradient) == nsize + 6))
     212         5062 :                CALL pack_subsys_particles(subsys=subsys, f=gradient(1:nsize), fscale=-1.0_dp)
     213         5062 :                CALL apply_cell_change(gopt_env, cell, gradient, update_forces=.TRUE.)
     214         5062 :                IF (spgr%keep_space_group) THEN
     215          544 :                   CALL spgr_apply_rotations_force(spgr, gradient)
     216          544 :                   CALL spgr_apply_rotations_stress(spgr, cell, av_ptens)
     217          544 :                   CALL spgr_write_stress_tensor(av_ptens, spgr)
     218              :                END IF
     219         5062 :                cell_gradient => gradient(nsize + 1:nsize + 6)
     220        35434 :                cell_gradient = 0.0_dp
     221              :                CALL get_dg_dh(cell_gradient, av_ptens, gopt_env%cell_env%pres_ext, cell, gopt_env%cell_env%mtrx, &
     222              :                               keep_angles=gopt_env%cell_env%keep_angles, &
     223              :                               keep_symmetry=gopt_env%cell_env%keep_symmetry, &
     224              :                               pres_int=gopt_env%cell_env%pres_int, &
     225              :                               pres_constr=gopt_env%cell_env%pres_constr, &
     226         5062 :                               constraint_id=gopt_env%cell_env%constraint_id)
     227              :             END IF
     228              :             ! some callers expect pres_int to be available on all ranks. Also, here master is not necessarily a single rank.
     229              :             ! Assume at least master==0
     230         6606 :             CALL para_env%bcast(gopt_env%cell_env%pres_int, 0)
     231         6606 :             IF (gopt_env%cell_env%constraint_id /= fix_none) &
     232           24 :                CALL para_env%bcast(gopt_env%cell_env%pres_constr, 0)
     233              :          END IF
     234              :       END BLOCK
     235              :    CASE (default_shellcore_method_id)
     236              :       idg = 0
     237        32980 :       DO ip = 1, particles%n_els
     238        32640 :          shell_index = particles%els(ip)%shell_index
     239        32980 :          IF (shell_index /= 0) THEN
     240       130560 :             DO idir = 1, 3
     241        97920 :                idg = 3*(shell_index - 1) + idir
     242       130560 :                shell_particles%els(shell_index)%r(idir) = core_particles%els(ip)%r(idir) - x(idg)
     243              :             END DO
     244              :          END IF
     245              :       END DO
     246          340 :       CALL write_structure_data(particles%els, cell, gopt_env%motion_section)
     247              : 
     248              :       ! Shell-core optimization
     249              :       CALL force_env_calc_energy_force(gopt_env%force_env, &
     250              :                                        calc_force=PRESENT(gradient), &
     251          340 :                                        require_consistent_energy_force=gopt_env%require_consistent_energy_force)
     252              : 
     253              :       ! Possibly take the potential energy
     254          340 :       IF (PRESENT(f)) THEN
     255          340 :          CALL force_env_get(gopt_env%force_env, potential_energy=f)
     256              :       END IF
     257              : 
     258              :       ! Possibly take the gradients
     259          340 :       IF (PRESENT(gradient)) THEN
     260          340 :          IF (master == para_env%mepos) THEN ! we are on the master
     261          340 :             CPASSERT(ASSOCIATED(gradient))
     262          340 :             idg = 0
     263        32980 :             DO ip = 1, shell_particles%n_els
     264       130900 :                DO idir = 1, 3
     265        97920 :                   idg = idg + 1
     266       130560 :                   gradient(idg) = -(core_particles%els(ip)%f(idir) - shell_particles%els(ip)%f(idir))
     267              :                END DO
     268              :             END DO
     269              :          END IF
     270              :       END IF
     271              :    CASE DEFAULT
     272        16539 :       CPABORT("Invalid or not yet implemented type of optimization")
     273              :    END SELECT
     274              : 
     275        16539 :    CALL timestop(handle)
     276              : 
     277        33078 : END SUBROUTINE cp_eval_at
        

Generated by: LCOV version 2.0-1