LCOV - code coverage report
Current view: top level - src - colvar_methods.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 2827 3495 80.9 %
Date: 2024-12-21 06:28:57 Functions: 43 48 89.6 %

          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 defines collective variables s({R}) and the derivative of this variable wrt R
      10             : !>      these can then be used in constraints, restraints and metadynamics ...
      11             : !> \par History
      12             : !>      04.2004 created
      13             : !>      01.2006 Refactored [Joost VandeVondele]
      14             : !> \author Alessandro Laio,Fawzi Mohamed
      15             : ! **************************************************************************************************
      16             : MODULE colvar_methods
      17             : 
      18             :    USE cell_types,                      ONLY: cell_type,&
      19             :                                               pbc
      20             :    USE colvar_types,                    ONLY: &
      21             :         HBP_colvar_id, Wc_colvar_id, acid_hyd_dist_colvar_id, acid_hyd_shell_colvar_id, &
      22             :         angle_colvar_id, colvar_create, colvar_setup, colvar_type, combine_colvar_id, &
      23             :         coord_colvar_id, dfunct_colvar_id, dist_colvar_id, distance_from_path_colvar_id, &
      24             :         do_clv_fix_point, do_clv_geo_center, do_clv_x, do_clv_xy, do_clv_xz, do_clv_y, do_clv_yz, &
      25             :         do_clv_z, eval_point_der, eval_point_mass, eval_point_pos, gyration_colvar_id, &
      26             :         hydronium_dist_colvar_id, hydronium_shell_colvar_id, mindist_colvar_id, plane_def_atoms, &
      27             :         plane_def_vec, plane_distance_colvar_id, plane_plane_angle_colvar_id, &
      28             :         population_colvar_id, qparm_colvar_id, reaction_path_colvar_id, ring_puckering_colvar_id, &
      29             :         rmsd_colvar_id, rotation_colvar_id, torsion_colvar_id, u_colvar_id, xyz_diag_colvar_id, &
      30             :         xyz_outerdiag_colvar_id
      31             :    USE constraint_fxd,                  ONLY: check_fixed_atom_cns_colv
      32             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      33             :                                               cp_logger_get_default_io_unit,&
      34             :                                               cp_logger_type,&
      35             :                                               cp_to_string
      36             :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      37             :                                               cp_print_key_unit_nr
      38             :    USE cp_parser_methods,               ONLY: parser_get_next_line,&
      39             :                                               parser_get_object
      40             :    USE cp_parser_types,                 ONLY: cp_parser_type,&
      41             :                                               parser_create,&
      42             :                                               parser_release
      43             :    USE cp_subsys_types,                 ONLY: cp_subsys_get,&
      44             :                                               cp_subsys_p_type,&
      45             :                                               cp_subsys_type
      46             :    USE cp_units,                        ONLY: cp_unit_to_cp2k
      47             :    USE force_env_types,                 ONLY: force_env_get,&
      48             :                                               force_env_type,&
      49             :                                               use_mixed_force
      50             :    USE force_fields_util,               ONLY: get_generic_info
      51             :    USE fparser,                         ONLY: EvalErrType,&
      52             :                                               evalf,&
      53             :                                               evalfd,&
      54             :                                               finalizef,&
      55             :                                               initf,&
      56             :                                               parsef
      57             :    USE input_constants,                 ONLY: rmsd_all,&
      58             :                                               rmsd_list,&
      59             :                                               rmsd_weightlist
      60             :    USE input_cp2k_colvar,               ONLY: create_colvar_xyz_d_section,&
      61             :                                               create_colvar_xyz_od_section
      62             :    USE input_enumeration_types,         ONLY: enum_i2c,&
      63             :                                               enumeration_type
      64             :    USE input_keyword_types,             ONLY: keyword_get,&
      65             :                                               keyword_type
      66             :    USE input_section_types,             ONLY: section_get_keyword,&
      67             :                                               section_release,&
      68             :                                               section_type,&
      69             :                                               section_vals_get,&
      70             :                                               section_vals_get_subs_vals,&
      71             :                                               section_vals_type,&
      72             :                                               section_vals_val_get
      73             :    USE kahan_sum,                       ONLY: accurate_sum
      74             :    USE kinds,                           ONLY: default_path_length,&
      75             :                                               default_string_length,&
      76             :                                               dp
      77             :    USE mathconstants,                   ONLY: fac,&
      78             :                                               maxfac,&
      79             :                                               pi,&
      80             :                                               twopi
      81             :    USE mathlib,                         ONLY: vector_product
      82             :    USE memory_utilities,                ONLY: reallocate
      83             :    USE message_passing,                 ONLY: mp_para_env_type
      84             :    USE mixed_energy_types,              ONLY: mixed_force_type
      85             :    USE mixed_environment_utils,         ONLY: get_subsys_map_index
      86             :    USE molecule_kind_types,             ONLY: fixd_constraint_type
      87             :    USE particle_list_types,             ONLY: particle_list_p_type,&
      88             :                                               particle_list_type
      89             :    USE particle_types,                  ONLY: particle_type
      90             :    USE qs_environment_types,            ONLY: get_qs_env,&
      91             :                                               qs_environment_type
      92             :    USE rmsd,                            ONLY: rmsd3
      93             :    USE spherical_harmonics,             ONLY: dlegendre,&
      94             :                                               legendre
      95             :    USE string_utilities,                ONLY: compress,&
      96             :                                               uppercase
      97             :    USE wannier_states_types,            ONLY: wannier_centres_type
      98             : #include "./base/base_uses.f90"
      99             : 
     100             :    IMPLICIT NONE
     101             :    PRIVATE
     102             : 
     103             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'colvar_methods'
     104             :    REAL(KIND=dp), PRIVATE, PARAMETER    :: tolerance_acos = 1.0E-5_dp
     105             : 
     106             :    PUBLIC :: colvar_read, &
     107             :              colvar_eval_glob_f, &
     108             :              colvar_eval_mol_f
     109             : 
     110             : CONTAINS
     111             : 
     112             : ! **************************************************************************************************
     113             : !> \brief reads a colvar from the input
     114             : !> \param colvar the place where to store what will be read
     115             : !> \param icol number of the current colvar (repetition in colvar_section)
     116             : !> \param colvar_section the colvar section
     117             : !> \param para_env ...
     118             : !> \par History
     119             : !>      04.2004 created [alessandro laio and fawzi mohamed]
     120             : !> \author teo
     121             : ! **************************************************************************************************
     122         498 :    RECURSIVE SUBROUTINE colvar_read(colvar, icol, colvar_section, para_env)
     123             :       TYPE(colvar_type), POINTER                         :: colvar
     124             :       INTEGER, INTENT(IN)                                :: icol
     125             :       TYPE(section_vals_type), POINTER                   :: colvar_section
     126             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     127             : 
     128             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'colvar_read'
     129             : 
     130             :       CHARACTER(LEN=3)                                   :: fmid
     131             :       CHARACTER(LEN=7)                                   :: tag, tag_comp, tag_comp1, tag_comp2
     132             :       CHARACTER(LEN=default_path_length)                 :: path_function
     133             :       CHARACTER(LEN=default_string_length)               :: tmpStr, tmpStr2
     134             :       CHARACTER(LEN=default_string_length), &
     135         498 :          DIMENSION(:), POINTER                           :: c_kinds, my_par
     136             :       INTEGER                                            :: handle, i, iatm, icomponent, iend, &
     137             :                                                             ifunc, ii, isize, istart, iw, iw1, j, &
     138             :                                                             k, kk, n_var, n_var_k, ncol, ndim, &
     139             :                                                             nr_frame, v_count
     140         498 :       INTEGER, DIMENSION(:), POINTER                     :: iatms
     141         498 :       INTEGER, DIMENSION(:, :), POINTER                  :: p_bounds
     142             :       LOGICAL                                            :: check, use_mixed_energy
     143             :       LOGICAL, DIMENSION(26)                             :: my_subsection
     144         498 :       REAL(dp), DIMENSION(:), POINTER                    :: s1, wei, weights
     145         498 :       REAL(dp), DIMENSION(:, :), POINTER                 :: p_range, s1v
     146             :       REAL(KIND=dp), DIMENSION(1)                        :: my_val
     147         498 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: g_range, grid_point, grid_sp, my_vals, &
     148         498 :                                                             range
     149             :       TYPE(cp_logger_type), POINTER                      :: logger
     150             :       TYPE(enumeration_type), POINTER                    :: enum
     151             :       TYPE(keyword_type), POINTER                        :: keyword
     152             :       TYPE(section_type), POINTER                        :: section
     153             :       TYPE(section_vals_type), POINTER :: acid_hyd_dist_section, acid_hyd_shell_section, &
     154             :          angle_section, colvar_subsection, combine_section, coordination_section, dfunct_section, &
     155             :          distance_from_path_section, distance_section, frame_section, gyration_section, &
     156             :          HBP_section, hydronium_dist_section, hydronium_shell_section, mindist_section, &
     157             :          path_section, plane_dist_section, plane_plane_angle_section, plane_sections, &
     158             :          point_section, population_section, qparm_section, reaction_path_section, &
     159             :          ring_puckering_section, rmsd_section, rotation_section, torsion_section, u_section, &
     160             :          Wc_section, wrk_section
     161             :       TYPE(section_vals_type), POINTER :: xyz_diag_section, xyz_outerdiag_section
     162             : 
     163         498 :       CALL timeset(routineN, handle)
     164         498 :       NULLIFY (logger, c_kinds, iatms)
     165         498 :       logger => cp_get_default_logger()
     166         498 :       my_subsection = .FALSE.
     167         498 :       distance_section => section_vals_get_subs_vals(colvar_section, "DISTANCE", i_rep_section=icol)
     168             :       dfunct_section => section_vals_get_subs_vals(colvar_section, "DISTANCE_FUNCTION", &
     169         498 :                                                    i_rep_section=icol)
     170         498 :       angle_section => section_vals_get_subs_vals(colvar_section, "ANGLE", i_rep_section=icol)
     171         498 :       torsion_section => section_vals_get_subs_vals(colvar_section, "TORSION", i_rep_section=icol)
     172         498 :       coordination_section => section_vals_get_subs_vals(colvar_section, "COORDINATION", i_rep_section=icol)
     173         498 :       plane_dist_section => section_vals_get_subs_vals(colvar_section, "DISTANCE_POINT_PLANE", i_rep_section=icol)
     174             :       plane_plane_angle_section &
     175         498 :          => section_vals_get_subs_vals(colvar_section, "ANGLE_PLANE_PLANE", i_rep_section=icol)
     176         498 :       rotation_section => section_vals_get_subs_vals(colvar_section, "BOND_ROTATION", i_rep_section=icol)
     177         498 :       qparm_section => section_vals_get_subs_vals(colvar_section, "QPARM", i_rep_section=icol)
     178         498 :       hydronium_shell_section => section_vals_get_subs_vals(colvar_section, "HYDRONIUM_SHELL", i_rep_section=icol)
     179         498 :       hydronium_dist_section => section_vals_get_subs_vals(colvar_section, "HYDRONIUM_DISTANCE", i_rep_section=icol)
     180         498 :       acid_hyd_dist_section => section_vals_get_subs_vals(colvar_section, "ACID_HYDRONIUM_DISTANCE", i_rep_section=icol)
     181             :       acid_hyd_shell_section &
     182         498 :          => section_vals_get_subs_vals(colvar_section, "ACID_HYDRONIUM_SHELL", i_rep_section=icol)
     183             :       reaction_path_section => section_vals_get_subs_vals(colvar_section, "REACTION_PATH", i_rep_section=icol, &
     184         498 :                                                           can_return_null=.TRUE.)
     185             :       distance_from_path_section &
     186             :          => section_vals_get_subs_vals(colvar_section, "DISTANCE_FROM_PATH", &
     187         498 :                                        i_rep_section=icol, can_return_null=.TRUE.)
     188             :       combine_section => section_vals_get_subs_vals(colvar_section, "COMBINE_COLVAR", i_rep_section=icol, &
     189         498 :                                                     can_return_null=.TRUE.)
     190         498 :       population_section => section_vals_get_subs_vals(colvar_section, "POPULATION", i_rep_section=icol)
     191         498 :       gyration_section => section_vals_get_subs_vals(colvar_section, "GYRATION_RADIUS", i_rep_section=icol)
     192         498 :       rmsd_section => section_vals_get_subs_vals(colvar_section, "RMSD", i_rep_section=icol)
     193         498 :       xyz_diag_section => section_vals_get_subs_vals(colvar_section, "XYZ_DIAG", i_rep_section=icol)
     194         498 :       xyz_outerdiag_section => section_vals_get_subs_vals(colvar_section, "XYZ_OUTERDIAG", i_rep_section=icol)
     195         498 :       u_section => section_vals_get_subs_vals(colvar_section, "U", i_rep_section=icol)
     196         498 :       Wc_section => section_vals_get_subs_vals(colvar_section, "WC", i_rep_section=icol)
     197         498 :       HBP_section => section_vals_get_subs_vals(colvar_section, "HBP", i_rep_section=icol)
     198             :       ring_puckering_section &
     199         498 :          => section_vals_get_subs_vals(colvar_section, "RING_PUCKERING", i_rep_section=icol)
     200         498 :       mindist_section => section_vals_get_subs_vals(colvar_section, "CONDITIONED_DISTANCE", i_rep_section=icol)
     201             : 
     202         498 :       CALL section_vals_get(distance_section, explicit=my_subsection(1))
     203         498 :       CALL section_vals_get(angle_section, explicit=my_subsection(2))
     204         498 :       CALL section_vals_get(torsion_section, explicit=my_subsection(3))
     205         498 :       CALL section_vals_get(coordination_section, explicit=my_subsection(4))
     206         498 :       CALL section_vals_get(plane_dist_section, explicit=my_subsection(5))
     207         498 :       CALL section_vals_get(rotation_section, explicit=my_subsection(6))
     208         498 :       CALL section_vals_get(dfunct_section, explicit=my_subsection(7))
     209         498 :       CALL section_vals_get(qparm_section, explicit=my_subsection(8))
     210         498 :       CALL section_vals_get(hydronium_shell_section, explicit=my_subsection(9))
     211             :       ! These are just special cases since they are not present in their own defition of COLVARS
     212         498 :       IF (ASSOCIATED(reaction_path_section)) THEN
     213             :          CALL section_vals_get(reaction_path_section, &
     214         462 :                                explicit=my_subsection(10))
     215             :       END IF
     216         498 :       IF (ASSOCIATED(distance_from_path_section)) THEN
     217             :          CALL section_vals_get(distance_from_path_section, &
     218         462 :                                explicit=my_subsection(16))
     219             :       END IF
     220         498 :       IF (ASSOCIATED(combine_section)) THEN
     221         462 :          CALL section_vals_get(combine_section, explicit=my_subsection(11))
     222             :       END IF
     223         498 :       CALL section_vals_get(population_section, explicit=my_subsection(12))
     224             :       CALL section_vals_get(plane_plane_angle_section, &
     225         498 :                             explicit=my_subsection(13))
     226         498 :       CALL section_vals_get(gyration_section, explicit=my_subsection(14))
     227         498 :       CALL section_vals_get(rmsd_section, explicit=my_subsection(15))
     228         498 :       CALL section_vals_get(xyz_diag_section, explicit=my_subsection(17))
     229         498 :       CALL section_vals_get(xyz_outerdiag_section, explicit=my_subsection(18))
     230         498 :       CALL section_vals_get(u_section, explicit=my_subsection(19))
     231         498 :       CALL section_vals_get(Wc_section, explicit=my_subsection(20))
     232         498 :       CALL section_vals_get(HBP_section, explicit=my_subsection(21))
     233             :       CALL section_vals_get(ring_puckering_section, &
     234         498 :                             explicit=my_subsection(22))
     235         498 :       CALL section_vals_get(mindist_section, explicit=my_subsection(23))
     236         498 :       CALL section_vals_get(acid_hyd_dist_section, explicit=my_subsection(24))
     237         498 :       CALL section_vals_get(acid_hyd_shell_section, explicit=my_subsection(25))
     238         498 :       CALL section_vals_get(hydronium_dist_section, explicit=my_subsection(26))
     239             : 
     240             :       ! Only one colvar can be present
     241       13446 :       CPASSERT(COUNT(my_subsection) == 1)
     242         498 :       CPASSERT(.NOT. ASSOCIATED(colvar))
     243             : 
     244         498 :       IF (my_subsection(1)) THEN
     245             :          ! Distance
     246         206 :          wrk_section => distance_section
     247         206 :          CALL colvar_create(colvar, dist_colvar_id)
     248         206 :          CALL colvar_check_points(colvar, distance_section)
     249         206 :          CALL section_vals_val_get(distance_section, "ATOMS", i_vals=iatms)
     250         206 :          colvar%dist_param%i_at = iatms(1)
     251         206 :          colvar%dist_param%j_at = iatms(2)
     252         206 :          CALL section_vals_val_get(distance_section, "AXIS", i_val=colvar%dist_param%axis_id)
     253         206 :          CALL section_vals_val_get(distance_section, "SIGN", l_val=colvar%dist_param%sign_d)
     254         292 :       ELSE IF (my_subsection(2)) THEN
     255             :          ! Angle
     256          52 :          wrk_section => angle_section
     257          52 :          CALL colvar_create(colvar, angle_colvar_id)
     258          52 :          CALL colvar_check_points(colvar, angle_section)
     259          52 :          CALL section_vals_val_get(angle_section, "ATOMS", i_vals=iatms)
     260         364 :          colvar%angle_param%i_at_angle = iatms
     261         240 :       ELSE IF (my_subsection(3)) THEN
     262             :          ! Torsion
     263          46 :          wrk_section => torsion_section
     264          46 :          CALL colvar_create(colvar, torsion_colvar_id)
     265          46 :          CALL colvar_check_points(colvar, torsion_section)
     266          46 :          CALL section_vals_val_get(torsion_section, "ATOMS", i_vals=iatms)
     267         414 :          colvar%torsion_param%i_at_tors = iatms
     268          46 :          colvar%torsion_param%o0 = 0.0_dp
     269         194 :       ELSE IF (my_subsection(4)) THEN
     270             :          ! Coordination
     271          52 :          wrk_section => coordination_section
     272          52 :          CALL colvar_create(colvar, coord_colvar_id)
     273          52 :          CALL colvar_check_points(colvar, coordination_section)
     274          52 :          NULLIFY (colvar%coord_param%i_at_from, colvar%coord_param%c_kinds_from)
     275          52 :          NULLIFY (colvar%coord_param%i_at_to, colvar%coord_param%c_kinds_to)
     276          52 :          NULLIFY (colvar%coord_param%i_at_to_b, colvar%coord_param%c_kinds_to_b)
     277             :          ! This section can be repeated
     278          52 :          CALL section_vals_val_get(coordination_section, "ATOMS_FROM", n_rep_val=n_var)
     279          52 :          ndim = 0
     280          52 :          IF (n_var /= 0) THEN
     281             :             ! INDEX LIST
     282          92 :             DO k = 1, n_var
     283          46 :                CALL section_vals_val_get(coordination_section, "ATOMS_FROM", i_rep_val=k, i_vals=iatms)
     284          46 :                CALL reallocate(colvar%coord_param%i_at_from, 1, ndim + SIZE(iatms))
     285         138 :                colvar%coord_param%i_at_from(ndim + 1:ndim + SIZE(iatms)) = iatms
     286          92 :                ndim = ndim + SIZE(iatms)
     287             :             END DO
     288          46 :             colvar%coord_param%n_atoms_from = ndim
     289          46 :             colvar%coord_param%use_kinds_from = .FALSE.
     290             :          ELSE
     291             :             ! KINDS
     292           6 :             CALL section_vals_val_get(coordination_section, "KINDS_FROM", n_rep_val=n_var)
     293           6 :             CPASSERT(n_var > 0)
     294          12 :             DO k = 1, n_var
     295           6 :                CALL section_vals_val_get(coordination_section, "KINDS_FROM", i_rep_val=k, c_vals=c_kinds)
     296           6 :                CALL reallocate(colvar%coord_param%c_kinds_from, 1, ndim + SIZE(c_kinds))
     297          18 :                colvar%coord_param%c_kinds_from(ndim + 1:ndim + SIZE(c_kinds)) = c_kinds
     298          12 :                ndim = ndim + SIZE(c_kinds)
     299             :             END DO
     300           6 :             colvar%coord_param%n_atoms_from = 0
     301           6 :             colvar%coord_param%use_kinds_from = .TRUE.
     302             :             ! Uppercase the label
     303          12 :             DO k = 1, ndim
     304          12 :                CALL uppercase(colvar%coord_param%c_kinds_from(k))
     305             :             END DO
     306             :          END IF
     307             :          ! This section can be repeated
     308          52 :          CALL section_vals_val_get(coordination_section, "ATOMS_TO", n_rep_val=n_var)
     309          52 :          ndim = 0
     310          52 :          IF (n_var /= 0) THEN
     311             :             ! INDEX LIST
     312          92 :             DO k = 1, n_var
     313          46 :                CALL section_vals_val_get(coordination_section, "ATOMS_TO", i_rep_val=k, i_vals=iatms)
     314          46 :                CALL reallocate(colvar%coord_param%i_at_to, 1, ndim + SIZE(iatms))
     315         190 :                colvar%coord_param%i_at_to(ndim + 1:ndim + SIZE(iatms)) = iatms
     316          92 :                ndim = ndim + SIZE(iatms)
     317             :             END DO
     318          46 :             colvar%coord_param%n_atoms_to = ndim
     319          46 :             colvar%coord_param%use_kinds_to = .FALSE.
     320             :          ELSE
     321             :             ! KINDS
     322           6 :             CALL section_vals_val_get(coordination_section, "KINDS_TO", n_rep_val=n_var)
     323           6 :             CPASSERT(n_var > 0)
     324          12 :             DO k = 1, n_var
     325           6 :                CALL section_vals_val_get(coordination_section, "KINDS_TO", i_rep_val=k, c_vals=c_kinds)
     326           6 :                CALL reallocate(colvar%coord_param%c_kinds_to, 1, ndim + SIZE(c_kinds))
     327          18 :                colvar%coord_param%c_kinds_to(ndim + 1:ndim + SIZE(c_kinds)) = c_kinds
     328          12 :                ndim = ndim + SIZE(c_kinds)
     329             :             END DO
     330           6 :             colvar%coord_param%n_atoms_to = 0
     331           6 :             colvar%coord_param%use_kinds_to = .TRUE.
     332             :             ! Uppercase the label
     333          12 :             DO k = 1, ndim
     334          12 :                CALL uppercase(colvar%coord_param%c_kinds_to(k))
     335             :             END DO
     336             :          END IF
     337             :          ! Let's finish reading the other parameters
     338          52 :          CALL section_vals_val_get(coordination_section, "R0", r_val=colvar%coord_param%r_0)
     339          52 :          CALL section_vals_val_get(coordination_section, "NN", i_val=colvar%coord_param%nncrd)
     340          52 :          CALL section_vals_val_get(coordination_section, "ND", i_val=colvar%coord_param%ndcrd)
     341             :          ! This section can be repeated
     342          52 :          CALL section_vals_val_get(coordination_section, "ATOMS_TO_B", n_rep_val=n_var)
     343          52 :          CALL section_vals_val_get(coordination_section, "KINDS_TO_B", n_rep_val=n_var_k)
     344          52 :          ndim = 0
     345          52 :          IF (n_var /= 0 .OR. n_var_k /= 0) THEN
     346           4 :             colvar%coord_param%do_chain = .TRUE.
     347           4 :             IF (n_var /= 0) THEN
     348             :                ! INDEX LIST
     349           4 :                DO k = 1, n_var
     350           2 :                   CALL section_vals_val_get(coordination_section, "ATOMS_TO_B", i_rep_val=k, i_vals=iatms)
     351           2 :                   CALL reallocate(colvar%coord_param%i_at_to_b, 1, ndim + SIZE(iatms))
     352           6 :                   colvar%coord_param%i_at_to_b(ndim + 1:ndim + SIZE(iatms)) = iatms
     353           4 :                   ndim = ndim + SIZE(iatms)
     354             :                END DO
     355           2 :                colvar%coord_param%n_atoms_to_b = ndim
     356           2 :                colvar%coord_param%use_kinds_to_b = .FALSE.
     357             :             ELSE
     358             :                ! KINDS
     359           2 :                CALL section_vals_val_get(coordination_section, "KINDS_TO_B", n_rep_val=n_var_k)
     360           2 :                CPASSERT(n_var_k > 0)
     361           4 :                DO k = 1, n_var_k
     362           2 :                   CALL section_vals_val_get(coordination_section, "KINDS_TO_B", i_rep_val=k, c_vals=c_kinds)
     363           2 :                   CALL reallocate(colvar%coord_param%c_kinds_to_b, 1, ndim + SIZE(c_kinds))
     364           6 :                   colvar%coord_param%c_kinds_to_b(ndim + 1:ndim + SIZE(c_kinds)) = c_kinds
     365           4 :                   ndim = ndim + SIZE(c_kinds)
     366             :                END DO
     367           2 :                colvar%coord_param%n_atoms_to_b = 0
     368           2 :                colvar%coord_param%use_kinds_to_b = .TRUE.
     369             :                ! Uppercase the label
     370           4 :                DO k = 1, ndim
     371           4 :                   CALL uppercase(colvar%coord_param%c_kinds_to_b(k))
     372             :                END DO
     373             :             END IF
     374             :             ! Let's finish reading the other parameters
     375           4 :             CALL section_vals_val_get(coordination_section, "R0_B", r_val=colvar%coord_param%r_0_b)
     376           4 :             CALL section_vals_val_get(coordination_section, "NN_B", i_val=colvar%coord_param%nncrd_b)
     377           4 :             CALL section_vals_val_get(coordination_section, "ND_B", i_val=colvar%coord_param%ndcrd_b)
     378             :          ELSE
     379          48 :             colvar%coord_param%do_chain = .FALSE.
     380          48 :             colvar%coord_param%n_atoms_to_b = 0
     381          48 :             colvar%coord_param%use_kinds_to_b = .FALSE.
     382          48 :             NULLIFY (colvar%coord_param%i_at_to_b)
     383          48 :             NULLIFY (colvar%coord_param%c_kinds_to_b)
     384          48 :             colvar%coord_param%nncrd_b = 0
     385          48 :             colvar%coord_param%ndcrd_b = 0
     386          48 :             colvar%coord_param%r_0_b = 0._dp
     387             :          END IF
     388             : 
     389         142 :       ELSE IF (my_subsection(5)) THEN
     390             :          ! Distance point from plane
     391          28 :          wrk_section => plane_dist_section
     392          28 :          CALL colvar_create(colvar, plane_distance_colvar_id)
     393          28 :          CALL colvar_check_points(colvar, plane_dist_section)
     394          28 :          CALL section_vals_val_get(plane_dist_section, "ATOMS_PLANE", i_vals=iatms)
     395          28 :          CPASSERT(SIZE(iatms) == 3)
     396         196 :          colvar%plane_distance_param%plane = iatms
     397          28 :          CALL section_vals_val_get(plane_dist_section, "ATOM_POINT", i_val=iatm)
     398          28 :          colvar%plane_distance_param%point = iatm
     399          28 :          CALL section_vals_val_get(plane_dist_section, "PBC", l_val=colvar%plane_distance_param%use_pbc)
     400         114 :       ELSE IF (my_subsection(6)) THEN
     401             :          ! Rotation colvar of a segment w.r.t. another segment
     402           2 :          wrk_section => rotation_section
     403           2 :          CALL colvar_create(colvar, rotation_colvar_id)
     404           2 :          CALL colvar_check_points(colvar, rotation_section)
     405           2 :          CALL section_vals_val_get(rotation_section, "P1_BOND1", i_val=colvar%rotation_param%i_at1_bond1)
     406           2 :          CALL section_vals_val_get(rotation_section, "P2_BOND1", i_val=colvar%rotation_param%i_at2_bond1)
     407           2 :          CALL section_vals_val_get(rotation_section, "P1_BOND2", i_val=colvar%rotation_param%i_at1_bond2)
     408           2 :          CALL section_vals_val_get(rotation_section, "P2_BOND2", i_val=colvar%rotation_param%i_at2_bond2)
     409         112 :       ELSE IF (my_subsection(7)) THEN
     410             :          ! Difference of two distances
     411           6 :          wrk_section => dfunct_section
     412           6 :          CALL colvar_create(colvar, dfunct_colvar_id)
     413           6 :          CALL colvar_check_points(colvar, dfunct_section)
     414           6 :          CALL section_vals_val_get(dfunct_section, "ATOMS", i_vals=iatms)
     415          54 :          colvar%dfunct_param%i_at_dfunct = iatms
     416           6 :          CALL section_vals_val_get(dfunct_section, "COEFFICIENT", r_val=colvar%dfunct_param%coeff)
     417           6 :          CALL section_vals_val_get(dfunct_section, "PBC", l_val=colvar%dfunct_param%use_pbc)
     418         106 :       ELSE IF (my_subsection(8)) THEN
     419             :          ! Q Parameter
     420           2 :          wrk_section => qparm_section
     421           2 :          CALL colvar_create(colvar, qparm_colvar_id)
     422           2 :          CALL colvar_check_points(colvar, qparm_section)
     423           2 :          CALL section_vals_val_get(qparm_section, "RCUT", r_val=colvar%qparm_param%rcut)
     424           2 :          CALL section_vals_val_get(qparm_section, "RSTART", r_val=colvar%qparm_param%rstart)
     425           2 :          CALL section_vals_val_get(qparm_section, "INCLUDE_IMAGES", l_val=colvar%qparm_param%include_images)
     426             :          !CALL section_vals_val_get(qparm_section, "ALPHA", r_val=colvar%qparm_param%alpha)
     427           2 :          CALL section_vals_val_get(qparm_section, "L", i_val=colvar%qparm_param%l)
     428           2 :          NULLIFY (colvar%qparm_param%i_at_from)
     429           2 :          NULLIFY (colvar%qparm_param%i_at_to)
     430           2 :          CALL section_vals_val_get(qparm_section, "ATOMS_FROM", n_rep_val=n_var)
     431           2 :          ndim = 0
     432          24 :          DO k = 1, n_var
     433          22 :             CALL section_vals_val_get(qparm_section, "ATOMS_FROM", i_rep_val=k, i_vals=iatms)
     434          22 :             CALL reallocate(colvar%qparm_param%i_at_from, 1, ndim + SIZE(iatms))
     435         454 :             colvar%qparm_param%i_at_from(ndim + 1:ndim + SIZE(iatms)) = iatms
     436          24 :             ndim = ndim + SIZE(iatms)
     437             :          END DO
     438           2 :          colvar%qparm_param%n_atoms_from = ndim
     439             :          ! This section can be repeated
     440           2 :          CALL section_vals_val_get(qparm_section, "ATOMS_TO", n_rep_val=n_var)
     441           2 :          ndim = 0
     442          24 :          DO k = 1, n_var
     443          22 :             CALL section_vals_val_get(qparm_section, "ATOMS_TO", i_rep_val=k, i_vals=iatms)
     444          22 :             CALL reallocate(colvar%qparm_param%i_at_to, 1, ndim + SIZE(iatms))
     445         454 :             colvar%qparm_param%i_at_to(ndim + 1:ndim + SIZE(iatms)) = iatms
     446          24 :             ndim = ndim + SIZE(iatms)
     447             :          END DO
     448           2 :          colvar%qparm_param%n_atoms_to = ndim
     449         104 :       ELSE IF (my_subsection(9)) THEN
     450             :          ! Hydronium
     451           2 :          CALL colvar_create(colvar, hydronium_shell_colvar_id)
     452           2 :          NULLIFY (colvar%hydronium_shell_param%i_oxygens)
     453           2 :          NULLIFY (colvar%hydronium_shell_param%i_hydrogens)
     454             :          CALL read_hydronium_colvars(hydronium_shell_section, colvar, hydronium_shell_colvar_id, &
     455             :                                      colvar%hydronium_shell_param%n_oxygens, &
     456             :                                      colvar%hydronium_shell_param%n_hydrogens, &
     457             :                                      colvar%hydronium_shell_param%i_oxygens, &
     458           2 :                                      colvar%hydronium_shell_param%i_hydrogens)
     459         102 :       ELSE IF (my_subsection(10) .OR. my_subsection(16)) THEN
     460             :          !reaction path or distance from reaction path
     461          18 :          IF (my_subsection(10)) THEN
     462          10 :             path_section => reaction_path_section
     463          10 :             CALL colvar_create(colvar, reaction_path_colvar_id)
     464          10 :             fmid = "POS"
     465          10 :             ifunc = 1
     466           8 :          ELSE IF (my_subsection(16)) THEN
     467           8 :             path_section => distance_from_path_section
     468           8 :             CALL colvar_create(colvar, distance_from_path_colvar_id)
     469           8 :             fmid = "DIS"
     470           8 :             ifunc = 2
     471             :          END IF
     472          18 :          colvar%use_points = .FALSE.
     473          18 :          CALL section_vals_val_get(path_section, "LAMBDA", r_val=colvar%reaction_path_param%lambda)
     474          18 :          CALL section_vals_val_get(path_section, "DISTANCES_RMSD", l_val=colvar%reaction_path_param%dist_rmsd)
     475          18 :          CALL section_vals_val_get(path_section, "RMSD", l_val=colvar%reaction_path_param%rmsd)
     476          18 :          IF (colvar%reaction_path_param%dist_rmsd .AND. colvar%reaction_path_param%rmsd) THEN
     477           0 :             CPABORT("CV REACTION PATH: only one between DISTANCES_RMSD and RMSD can be used ")
     478             :          END IF
     479          18 :          IF (colvar%reaction_path_param%dist_rmsd .OR. colvar%reaction_path_param%rmsd) THEN
     480           8 :             NULLIFY (colvar%reaction_path_param%i_rmsd, colvar%reaction_path_param%r_ref)
     481           8 :             frame_section => section_vals_get_subs_vals(path_section, "FRAME")
     482           8 :             CALL section_vals_get(frame_section, n_repetition=nr_frame)
     483             : 
     484           8 :             colvar%reaction_path_param%nr_frames = nr_frame
     485             :             CALL read_frames(frame_section, para_env, nr_frame, colvar%reaction_path_param%r_ref, &
     486           8 :                              colvar%reaction_path_param%n_components)
     487           8 :             CALL section_vals_val_get(path_section, "SUBSET_TYPE", i_val=colvar%reaction_path_param%subset)
     488           8 :             IF (colvar%reaction_path_param%subset == rmsd_all) THEN
     489           0 :                ALLOCATE (colvar%reaction_path_param%i_rmsd(colvar%reaction_path_param%n_components))
     490           0 :                DO i = 1, colvar%reaction_path_param%n_components
     491           0 :                   colvar%reaction_path_param%i_rmsd(i) = i
     492             :                END DO
     493           8 :             ELSE IF (colvar%reaction_path_param%subset == rmsd_list) THEN
     494             :                ! This section can be repeated
     495           8 :                CALL section_vals_val_get(path_section, "ATOMS", n_rep_val=n_var)
     496           8 :                ndim = 0
     497           8 :                IF (n_var /= 0) THEN
     498             :                   ! INDEX LIST
     499          16 :                   DO k = 1, n_var
     500           8 :                      CALL section_vals_val_get(path_section, "ATOMS", i_rep_val=k, i_vals=iatms)
     501           8 :                      CALL reallocate(colvar%reaction_path_param%i_rmsd, 1, ndim + SIZE(iatms))
     502         152 :                      colvar%reaction_path_param%i_rmsd(ndim + 1:ndim + SIZE(iatms)) = iatms
     503          16 :                      ndim = ndim + SIZE(iatms)
     504             :                   END DO
     505           8 :                   colvar%reaction_path_param%n_components = ndim
     506             :                ELSE
     507           0 :                   CPABORT("CV REACTION PATH: if SUBSET_TYPE=LIST a list of atoms needs to be provided ")
     508             :                END IF
     509             :             END IF
     510             : 
     511           8 :             CALL section_vals_val_get(path_section, "ALIGN_FRAMES", l_val=colvar%reaction_path_param%align_frames)
     512             :          ELSE
     513          10 :             colvar_subsection => section_vals_get_subs_vals(path_section, "COLVAR")
     514          10 :             CALL section_vals_get(colvar_subsection, n_repetition=ncol)
     515          50 :             ALLOCATE (colvar%reaction_path_param%colvar_p(ncol))
     516          10 :             IF (ncol > 0) THEN
     517          30 :                DO i = 1, ncol
     518          20 :                   NULLIFY (colvar%reaction_path_param%colvar_p(i)%colvar)
     519          30 :                   CALL colvar_read(colvar%reaction_path_param%colvar_p(i)%colvar, i, colvar_subsection, para_env)
     520             :                END DO
     521             :             ELSE
     522           0 :                CPABORT("CV REACTION PATH: the number of CV to define the path must be >0 ")
     523             :             END IF
     524          10 :             colvar%reaction_path_param%n_components = ncol
     525          10 :             NULLIFY (range)
     526          10 :             CALL section_vals_val_get(path_section, "RANGE", r_vals=range)
     527          10 :             CALL section_vals_val_get(path_section, "STEP_SIZE", r_val=colvar%reaction_path_param%step_size)
     528          10 :             iend = CEILING(MAX(RANGE(1), RANGE(2))/colvar%reaction_path_param%step_size)
     529          10 :             istart = FLOOR(MIN(RANGE(1), RANGE(2))/colvar%reaction_path_param%step_size)
     530          10 :             colvar%reaction_path_param%function_bounds(1) = istart
     531          10 :             colvar%reaction_path_param%function_bounds(2) = iend
     532          10 :             colvar%reaction_path_param%nr_frames = 2 !iend - istart + 1
     533          40 :             ALLOCATE (colvar%reaction_path_param%f_vals(ncol, istart:iend))
     534          10 :             CALL section_vals_val_get(path_section, "VARIABLE", c_vals=my_par, i_rep_val=1)
     535          10 :             CALL section_vals_val_get(path_section, "FUNCTION", n_rep_val=ncol)
     536          10 :             check = (ncol == SIZE(colvar%reaction_path_param%colvar_p))
     537          10 :             CPASSERT(check)
     538          10 :             CALL initf(ncol)
     539          30 :             DO i = 1, ncol
     540          20 :                CALL section_vals_val_get(path_section, "FUNCTION", c_val=path_function, i_rep_val=i)
     541          20 :                CALL compress(path_function, full=.TRUE.)
     542          20 :                CALL parsef(i, TRIM(path_function), my_par)
     543       78050 :                DO j = istart, iend
     544      156040 :                   my_val = REAL(j, kind=dp)*colvar%reaction_path_param%step_size
     545       78040 :                   colvar%reaction_path_param%f_vals(i, j) = evalf(i, my_val)
     546             :                END DO
     547             :             END DO
     548          10 :             CALL finalizef()
     549             : 
     550             :             iw1 = cp_print_key_unit_nr(logger, path_section, &
     551          10 :                                        "MAP", middle_name=fmid, extension=".dat", file_status="REPLACE")
     552          10 :             IF (iw1 > 0) THEN
     553           5 :                CALL section_vals_val_get(path_section, "MAP%GRID_SPACING", n_rep_val=ncol)
     554          15 :                ALLOCATE (grid_sp(ncol))
     555          15 :                DO i = 1, ncol
     556          15 :                   CALL section_vals_val_get(path_section, "MAP%GRID_SPACING", r_val=grid_sp(i))
     557             :                END DO
     558           5 :                CALL section_vals_val_get(path_section, "MAP%RANGE", n_rep_val=ncol)
     559           5 :                CPASSERT(ncol == SIZE(grid_sp))
     560          15 :                ALLOCATE (p_range(2, ncol))
     561          15 :                ALLOCATE (p_bounds(2, ncol))
     562          15 :                DO i = 1, ncol
     563          10 :                   CALL section_vals_val_get(path_section, "MAP%RANGE", r_vals=g_range)
     564          50 :                   p_range(:, i) = g_range(:)
     565          10 :                   p_bounds(2, i) = CEILING(MAX(p_range(1, i), p_range(2, i))/grid_sp(i))
     566          15 :                   p_bounds(1, i) = FLOOR(MIN(p_range(1, i), p_range(2, i))/grid_sp(i))
     567             :                END DO
     568          15 :                ALLOCATE (s1v(2, istart:iend))
     569           5 :                ALLOCATE (s1(2))
     570          15 :                ALLOCATE (grid_point(ncol))
     571           5 :                v_count = 0
     572             :                kk = rec_eval_grid(iw1, ncol, colvar%reaction_path_param%f_vals, v_count, &
     573             :                                   grid_point, grid_sp, colvar%reaction_path_param%step_size, istart, &
     574             :                                   iend, s1v, s1, p_bounds, colvar%reaction_path_param%lambda, ifunc=ifunc, &
     575           5 :                                   nconf=colvar%reaction_path_param%nr_frames)
     576           5 :                DEALLOCATE (grid_sp)
     577           5 :                DEALLOCATE (p_range)
     578           5 :                DEALLOCATE (p_bounds)
     579           5 :                DEALLOCATE (s1v)
     580           5 :                DEALLOCATE (s1)
     581          15 :                DEALLOCATE (grid_point)
     582             :             END IF
     583             :             CALL cp_print_key_finished_output(iw1, logger, path_section, &
     584          30 :                                               "MAP")
     585             :          END IF
     586             : 
     587          84 :       ELSE IF (my_subsection(11)) THEN
     588             :          ! combine colvar
     589           8 :          CALL colvar_create(colvar, combine_colvar_id)
     590           8 :          colvar%use_points = .FALSE.
     591           8 :          colvar_subsection => section_vals_get_subs_vals(combine_section, "COLVAR")
     592           8 :          CALL section_vals_get(colvar_subsection, n_repetition=ncol)
     593          40 :          ALLOCATE (colvar%combine_cvs_param%colvar_p(ncol))
     594             :          ! In case we need to print some information..
     595             :          iw = cp_print_key_unit_nr(logger, colvar_section, &
     596           8 :                                    "PRINT%PROGRAM_RUN_INFO", extension=".colvarLog")
     597           8 :          IF (iw > 0) THEN
     598             :             WRITE (iw, '( A )') '          '// &
     599           4 :                '**********************************************************************'
     600           4 :             WRITE (iw, '( A,I8)') ' COLVARS| COLVAR INPUT INDEX: ', icol
     601           4 :             WRITE (iw, '( A,T49,4I8)') ' COLVARS| COMBINATION OF THE FOLLOWING COLVARS:'
     602             :          END IF
     603             :          CALL cp_print_key_finished_output(iw, logger, colvar_section, &
     604           8 :                                            "PRINT%PROGRAM_RUN_INFO")
     605             :          ! Parsing the real COLVARs
     606          24 :          DO i = 1, ncol
     607          16 :             NULLIFY (colvar%combine_cvs_param%colvar_p(i)%colvar)
     608          24 :             CALL colvar_read(colvar%combine_cvs_param%colvar_p(i)%colvar, i, colvar_subsection, para_env)
     609             :          END DO
     610             :          ! Function definition
     611           8 :          CALL section_vals_val_get(combine_section, "FUNCTION", c_val=colvar%combine_cvs_param%function)
     612           8 :          CALL compress(colvar%combine_cvs_param%function, full=.TRUE.)
     613             :          ! Variables
     614           8 :          CALL section_vals_val_get(combine_section, "VARIABLES", c_vals=my_par)
     615          24 :          ALLOCATE (colvar%combine_cvs_param%variables(SIZE(my_par)))
     616          40 :          colvar%combine_cvs_param%variables = my_par
     617             :          ! Check that the number of COLVAR provided is equal to the number of variables..
     618           8 :          IF (SIZE(my_par) /= ncol) &
     619             :             CALL cp_abort(__LOCATION__, &
     620             :                           "Number of defined COLVAR for COMBINE_COLVAR is different from the "// &
     621             :                           "number of variables! It is not possible to define COLVARs in a COMBINE_COLVAR "// &
     622           0 :                           "and avoid their usage in the combininig function!")
     623             :          ! Parameters
     624           8 :          ALLOCATE (colvar%combine_cvs_param%c_parameters(0))
     625           8 :          CALL section_vals_val_get(combine_section, "PARAMETERS", n_rep_val=ncol)
     626          12 :          DO i = 1, ncol
     627           4 :             isize = SIZE(colvar%combine_cvs_param%c_parameters)
     628           4 :             CALL section_vals_val_get(combine_section, "PARAMETERS", c_vals=my_par, i_rep_val=i)
     629           4 :             CALL reallocate(colvar%combine_cvs_param%c_parameters, 1, isize + SIZE(my_par))
     630          20 :             colvar%combine_cvs_param%c_parameters(isize + 1:isize + SIZE(my_par)) = my_par
     631             :          END DO
     632           8 :          ALLOCATE (colvar%combine_cvs_param%v_parameters(0))
     633           8 :          CALL section_vals_val_get(combine_section, "VALUES", n_rep_val=ncol)
     634          12 :          DO i = 1, ncol
     635           4 :             isize = SIZE(colvar%combine_cvs_param%v_parameters)
     636           4 :             CALL section_vals_val_get(combine_section, "VALUES", r_vals=my_vals, i_rep_val=i)
     637           4 :             CALL reallocate(colvar%combine_cvs_param%v_parameters, 1, isize + SIZE(my_vals))
     638          20 :             colvar%combine_cvs_param%v_parameters(isize + 1:isize + SIZE(my_vals)) = my_vals
     639             :          END DO
     640             :          ! Info on derivative evaluation
     641           8 :          CALL section_vals_val_get(combine_section, "DX", r_val=colvar%combine_cvs_param%dx)
     642          32 :          CALL section_vals_val_get(combine_section, "ERROR_LIMIT", r_val=colvar%combine_cvs_param%lerr)
     643          76 :       ELSE IF (my_subsection(12)) THEN
     644             :          ! Population
     645           8 :          wrk_section => population_section
     646           8 :          CALL colvar_create(colvar, population_colvar_id)
     647           8 :          CALL colvar_check_points(colvar, population_section)
     648             : 
     649           8 :          NULLIFY (colvar%population_param%i_at_from, colvar%population_param%c_kinds_from)
     650           8 :          NULLIFY (colvar%population_param%i_at_to, colvar%population_param%c_kinds_to)
     651             :          ! This section can be repeated
     652             : 
     653           8 :          CALL section_vals_val_get(population_section, "ATOMS_FROM", n_rep_val=n_var)
     654           8 :          ndim = 0
     655           8 :          IF (n_var /= 0) THEN
     656             :             ! INDEX LIST
     657          16 :             DO k = 1, n_var
     658           8 :                CALL section_vals_val_get(population_section, "ATOMS_FROM", i_rep_val=k, i_vals=iatms)
     659           8 :                CALL reallocate(colvar%population_param%i_at_from, 1, ndim + SIZE(iatms))
     660          24 :                colvar%population_param%i_at_from(ndim + 1:ndim + SIZE(iatms)) = iatms
     661          16 :                ndim = ndim + SIZE(iatms)
     662             :             END DO
     663           8 :             colvar%population_param%n_atoms_from = ndim
     664           8 :             colvar%population_param%use_kinds_from = .FALSE.
     665             :          ELSE
     666             :             ! KINDS
     667           0 :             CALL section_vals_val_get(population_section, "KINDS_FROM", n_rep_val=n_var)
     668           0 :             CPASSERT(n_var > 0)
     669           0 :             DO k = 1, n_var
     670           0 :                CALL section_vals_val_get(population_section, "KINDS_FROM", i_rep_val=k, c_vals=c_kinds)
     671           0 :                CALL reallocate(colvar%population_param%c_kinds_from, 1, ndim + SIZE(c_kinds))
     672           0 :                colvar%population_param%c_kinds_from(ndim + 1:ndim + SIZE(c_kinds)) = c_kinds
     673           0 :                ndim = ndim + SIZE(c_kinds)
     674             :             END DO
     675           0 :             colvar%population_param%n_atoms_from = 0
     676           0 :             colvar%population_param%use_kinds_from = .TRUE.
     677             :             ! Uppercase the label
     678           0 :             DO k = 1, ndim
     679           0 :                CALL uppercase(colvar%population_param%c_kinds_from(k))
     680             :             END DO
     681             :          END IF
     682             :          ! This section can be repeated
     683           8 :          CALL section_vals_val_get(population_section, "ATOMS_TO", n_rep_val=n_var)
     684           8 :          ndim = 0
     685           8 :          IF (n_var /= 0) THEN
     686             :             ! INDEX LIST
     687           0 :             DO k = 1, n_var
     688           0 :                CALL section_vals_val_get(population_section, "ATOMS_TO", i_rep_val=k, i_vals=iatms)
     689           0 :                CALL reallocate(colvar%population_param%i_at_to, 1, ndim + SIZE(iatms))
     690           0 :                colvar%population_param%i_at_to(ndim + 1:ndim + SIZE(iatms)) = iatms
     691           0 :                ndim = ndim + SIZE(iatms)
     692             :             END DO
     693           0 :             colvar%population_param%n_atoms_to = ndim
     694           0 :             colvar%population_param%use_kinds_to = .FALSE.
     695             :          ELSE
     696             :             ! KINDS
     697           8 :             CALL section_vals_val_get(population_section, "KINDS_TO", n_rep_val=n_var)
     698           8 :             CPASSERT(n_var > 0)
     699          16 :             DO k = 1, n_var
     700           8 :                CALL section_vals_val_get(population_section, "KINDS_TO", i_rep_val=k, c_vals=c_kinds)
     701           8 :                CALL reallocate(colvar%population_param%c_kinds_to, 1, ndim + SIZE(c_kinds))
     702          24 :                colvar%population_param%c_kinds_to(ndim + 1:ndim + SIZE(c_kinds)) = c_kinds
     703          16 :                ndim = ndim + SIZE(c_kinds)
     704             :             END DO
     705           8 :             colvar%population_param%n_atoms_to = 0
     706           8 :             colvar%population_param%use_kinds_to = .TRUE.
     707             :             ! Uppercase the label
     708          16 :             DO k = 1, ndim
     709          16 :                CALL uppercase(colvar%population_param%c_kinds_to(k))
     710             :             END DO
     711             :          END IF
     712             :          ! Let's finish reading the other parameters
     713           8 :          CALL section_vals_val_get(population_section, "R0", r_val=colvar%population_param%r_0)
     714           8 :          CALL section_vals_val_get(population_section, "NN", i_val=colvar%population_param%nncrd)
     715           8 :          CALL section_vals_val_get(population_section, "ND", i_val=colvar%population_param%ndcrd)
     716           8 :          CALL section_vals_val_get(population_section, "N0", i_val=colvar%population_param%n0)
     717           8 :          CALL section_vals_val_get(population_section, "SIGMA", r_val=colvar%population_param%sigma)
     718          68 :       ELSE IF (my_subsection(13)) THEN
     719             :          ! Angle between two planes
     720           4 :          wrk_section => plane_plane_angle_section
     721           4 :          CALL colvar_create(colvar, plane_plane_angle_colvar_id)
     722           4 :          CALL colvar_check_points(colvar, plane_plane_angle_section)
     723             :          ! Read the specification of the two planes
     724           4 :          plane_sections => section_vals_get_subs_vals(plane_plane_angle_section, "PLANE")
     725           4 :          CALL section_vals_get(plane_sections, n_repetition=n_var)
     726           4 :          IF (n_var /= 2) &
     727           0 :             CPABORT("PLANE_PLANE_ANGLE Colvar section: Two PLANE sections must be provided!")
     728             :          ! Plane 1
     729             :          CALL section_vals_val_get(plane_sections, "DEF_TYPE", i_rep_section=1, &
     730           4 :                                    i_val=colvar%plane_plane_angle_param%plane1%type_of_def)
     731           4 :          IF (colvar%plane_plane_angle_param%plane1%type_of_def == plane_def_vec) THEN
     732             :             CALL section_vals_val_get(plane_sections, "NORMAL_VECTOR", i_rep_section=1, &
     733           0 :                                       r_vals=s1)
     734           0 :             colvar%plane_plane_angle_param%plane1%normal_vec = s1
     735             :          ELSE
     736             :             CALL section_vals_val_get(plane_sections, "ATOMS", i_rep_section=1, &
     737           4 :                                       i_vals=iatms)
     738          28 :             colvar%plane_plane_angle_param%plane1%points = iatms
     739             :          END IF
     740             : 
     741             :          ! Plane 2
     742             :          CALL section_vals_val_get(plane_sections, "DEF_TYPE", i_rep_section=2, &
     743           4 :                                    i_val=colvar%plane_plane_angle_param%plane2%type_of_def)
     744           4 :          IF (colvar%plane_plane_angle_param%plane2%type_of_def == plane_def_vec) THEN
     745             :             CALL section_vals_val_get(plane_sections, "NORMAL_VECTOR", i_rep_section=2, &
     746           2 :                                       r_vals=s1)
     747          14 :             colvar%plane_plane_angle_param%plane2%normal_vec = s1
     748             :          ELSE
     749             :             CALL section_vals_val_get(plane_sections, "ATOMS", i_rep_section=2, &
     750           2 :                                       i_vals=iatms)
     751          14 :             colvar%plane_plane_angle_param%plane2%points = iatms
     752             :          END IF
     753          64 :       ELSE IF (my_subsection(14)) THEN
     754             :          ! Gyration Radius
     755           2 :          wrk_section => gyration_section
     756           2 :          CALL colvar_create(colvar, gyration_colvar_id)
     757           2 :          CALL colvar_check_points(colvar, gyration_section)
     758             : 
     759           2 :          NULLIFY (colvar%gyration_param%i_at, colvar%gyration_param%c_kinds)
     760             : 
     761             :          ! This section can be repeated
     762           2 :          CALL section_vals_val_get(gyration_section, "ATOMS", n_rep_val=n_var)
     763           2 :          ndim = 0
     764           2 :          IF (n_var /= 0) THEN
     765             :             ! INDEX LIST
     766           0 :             DO k = 1, n_var
     767           0 :                CALL section_vals_val_get(gyration_section, "ATOMS", i_rep_val=k, i_vals=iatms)
     768           0 :                CALL reallocate(colvar%gyration_param%i_at, 1, ndim + SIZE(iatms))
     769           0 :                colvar%gyration_param%i_at(ndim + 1:ndim + SIZE(iatms)) = iatms
     770           0 :                ndim = ndim + SIZE(iatms)
     771             :             END DO
     772           0 :             colvar%gyration_param%n_atoms = ndim
     773           0 :             colvar%gyration_param%use_kinds = .FALSE.
     774             :          ELSE
     775             :             ! KINDS
     776           2 :             CALL section_vals_val_get(gyration_section, "KINDS", n_rep_val=n_var)
     777           2 :             CPASSERT(n_var > 0)
     778           4 :             DO k = 1, n_var
     779           2 :                CALL section_vals_val_get(gyration_section, "KINDS", i_rep_val=k, c_vals=c_kinds)
     780           2 :                CALL reallocate(colvar%gyration_param%c_kinds, 1, ndim + SIZE(c_kinds))
     781           6 :                colvar%gyration_param%c_kinds(ndim + 1:ndim + SIZE(c_kinds)) = c_kinds
     782           4 :                ndim = ndim + SIZE(c_kinds)
     783             :             END DO
     784           2 :             colvar%gyration_param%n_atoms = 0
     785           2 :             colvar%gyration_param%use_kinds = .TRUE.
     786             :             ! Uppercase the label
     787           4 :             DO k = 1, ndim
     788           4 :                CALL uppercase(colvar%gyration_param%c_kinds(k))
     789             :             END DO
     790             :          END IF
     791          62 :       ELSE IF (my_subsection(15)) THEN
     792             :          ! RMSD_AB
     793           4 :          wrk_section => rmsd_section
     794           4 :          CALL colvar_create(colvar, rmsd_colvar_id)
     795             : 
     796           4 :          NULLIFY (colvar%rmsd_param%i_rmsd, colvar%rmsd_param%r_ref, colvar%rmsd_param%weights)
     797             : 
     798           4 :          frame_section => section_vals_get_subs_vals(rmsd_section, "FRAME")
     799           4 :          CALL section_vals_get(frame_section, n_repetition=nr_frame)
     800             : 
     801           4 :          colvar%rmsd_param%nr_frames = nr_frame
     802             :          ! Calculation is aborted if reference frame are less than 1 and more than 2
     803           4 :          CPASSERT(nr_frame >= 1 .AND. nr_frame <= 2)
     804             :          CALL read_frames(frame_section, para_env, nr_frame, colvar%rmsd_param%r_ref, &
     805           4 :                           colvar%rmsd_param%n_atoms)
     806          12 :          ALLOCATE (colvar%rmsd_param%weights(colvar%rmsd_param%n_atoms))
     807          52 :          colvar%rmsd_param%weights = 0.0_dp
     808           4 :          CALL section_vals_val_get(rmsd_section, "SUBSET_TYPE", i_val=colvar%rmsd_param%subset)
     809           4 :          IF (colvar%rmsd_param%subset == rmsd_all) THEN
     810           0 :             ALLOCATE (colvar%rmsd_param%i_rmsd(colvar%rmsd_param%n_atoms))
     811           0 :             DO i = 1, colvar%rmsd_param%n_atoms
     812           0 :                colvar%rmsd_param%i_rmsd(i) = i
     813             :             END DO
     814           4 :          ELSE IF (colvar%rmsd_param%subset == rmsd_list) THEN
     815             :             ! This section can be repeated
     816           4 :             CALL section_vals_val_get(rmsd_section, "ATOMS", n_rep_val=n_var)
     817           4 :             ndim = 0
     818           4 :             IF (n_var /= 0) THEN
     819             :                ! INDEX LIST
     820           8 :                DO k = 1, n_var
     821           4 :                   CALL section_vals_val_get(rmsd_section, "ATOMS", i_rep_val=k, i_vals=iatms)
     822           4 :                   CALL reallocate(colvar%rmsd_param%i_rmsd, 1, ndim + SIZE(iatms))
     823          52 :                   colvar%rmsd_param%i_rmsd(ndim + 1:ndim + SIZE(iatms)) = iatms
     824           8 :                   ndim = ndim + SIZE(iatms)
     825             :                END DO
     826           4 :                colvar%rmsd_param%n_atoms = ndim
     827             :             ELSE
     828           0 :                CPABORT("CV RMSD: if SUBSET_TYPE=LIST a list of atoms needs to be provided ")
     829             :             END IF
     830           0 :          ELSE IF (colvar%rmsd_param%subset == rmsd_weightlist) THEN
     831           0 :             CALL section_vals_val_get(rmsd_section, "ATOMS", n_rep_val=n_var)
     832           0 :             ndim = 0
     833           0 :             IF (n_var /= 0) THEN
     834             :                ! INDEX LIST
     835           0 :                DO k = 1, n_var
     836           0 :                   CALL section_vals_val_get(rmsd_section, "ATOMS", i_rep_val=k, i_vals=iatms)
     837           0 :                   CALL reallocate(colvar%rmsd_param%i_rmsd, 1, ndim + SIZE(iatms))
     838           0 :                   colvar%rmsd_param%i_rmsd(ndim + 1:ndim + SIZE(iatms)) = iatms
     839           0 :                   ndim = ndim + SIZE(iatms)
     840             :                END DO
     841           0 :                colvar%rmsd_param%n_atoms = ndim
     842             :             ELSE
     843           0 :                CPABORT("CV RMSD: if SUBSET_TYPE=WEIGHT_LIST a list of atoms needs to be provided ")
     844             :             END IF
     845           0 :             CALL section_vals_val_get(rmsd_section, "WEIGHTS", n_rep_val=n_var)
     846           0 :             ndim = 0
     847           0 :             IF (n_var /= 0) THEN
     848             :                ! INDEX LIST
     849           0 :                DO k = 1, n_var
     850           0 :                   CALL section_vals_val_get(rmsd_section, "WEIGHTS", i_rep_val=k, r_vals=wei)
     851           0 :                   CALL reallocate(weights, 1, ndim + SIZE(wei))
     852           0 :                   weights(ndim + 1:ndim + SIZE(wei)) = wei
     853           0 :                   ndim = ndim + SIZE(wei)
     854             :                END DO
     855           0 :                IF (ndim /= colvar%rmsd_param%n_atoms) &
     856             :                   CALL cp_abort(__LOCATION__, "CV RMSD: list of atoms and list of "// &
     857           0 :                                 "weights need to contain same number of entries. ")
     858           0 :                DO i = 1, ndim
     859           0 :                   ii = colvar%rmsd_param%i_rmsd(i)
     860           0 :                   colvar%rmsd_param%weights(ii) = weights(i)
     861             :                END DO
     862           0 :                DEALLOCATE (weights)
     863             :             ELSE
     864           0 :                CPABORT("CV RMSD: if SUBSET_TYPE=WEIGHT_LIST a list of weights need to be provided. ")
     865             :             END IF
     866             : 
     867             :          ELSE
     868           0 :             CPABORT("CV RMSD: unknown SUBSET_TYPE.")
     869             :          END IF
     870             : 
     871           8 :          CALL section_vals_val_get(rmsd_section, "ALIGN_FRAMES", l_val=colvar%rmsd_param%align_frames)
     872             : 
     873          58 :       ELSE IF (my_subsection(17)) THEN
     874             :          ! Work on XYZ positions of atoms
     875           6 :          wrk_section => xyz_diag_section
     876           6 :          CALL colvar_create(colvar, xyz_diag_colvar_id)
     877           6 :          CALL colvar_check_points(colvar, wrk_section)
     878           6 :          CALL section_vals_val_get(wrk_section, "ATOM", i_val=iatm)
     879           6 :          CALL section_vals_val_get(wrk_section, "COMPONENT", i_val=icomponent)
     880           6 :          CALL section_vals_val_get(wrk_section, "PBC", l_val=colvar%xyz_diag_param%use_pbc)
     881           6 :          CALL section_vals_val_get(wrk_section, "ABSOLUTE_POSITION", l_val=colvar%xyz_diag_param%use_absolute_position)
     882           6 :          colvar%xyz_diag_param%i_atom = iatm
     883           6 :          colvar%xyz_diag_param%component = icomponent
     884          52 :       ELSE IF (my_subsection(18)) THEN
     885             :          ! Work on the outer diagonal (two atoms A,B) XYZ positions
     886           6 :          wrk_section => xyz_outerdiag_section
     887           6 :          CALL colvar_create(colvar, xyz_outerdiag_colvar_id)
     888           6 :          CALL colvar_check_points(colvar, wrk_section)
     889           6 :          CALL section_vals_val_get(wrk_section, "ATOMS", i_vals=iatms)
     890          30 :          colvar%xyz_outerdiag_param%i_atoms = iatms
     891           6 :          CALL section_vals_val_get(wrk_section, "COMPONENT_A", i_val=icomponent)
     892           6 :          colvar%xyz_outerdiag_param%components(1) = icomponent
     893           6 :          CALL section_vals_val_get(wrk_section, "COMPONENT_B", i_val=icomponent)
     894           6 :          colvar%xyz_outerdiag_param%components(2) = icomponent
     895           6 :          CALL section_vals_val_get(wrk_section, "PBC", l_val=colvar%xyz_outerdiag_param%use_pbc)
     896          46 :       ELSE IF (my_subsection(19)) THEN
     897             :          ! Energy
     898           6 :          wrk_section => u_section
     899           6 :          CALL colvar_create(colvar, u_colvar_id)
     900           6 :          colvar%u_param%mixed_energy_section => section_vals_get_subs_vals(wrk_section, "MIXED")
     901           6 :          CALL section_vals_get(colvar%u_param%mixed_energy_section, explicit=use_mixed_energy)
     902           6 :          IF (.NOT. use_mixed_energy) NULLIFY (colvar%u_param%mixed_energy_section)
     903          40 :       ELSE IF (my_subsection(20)) THEN
     904             :          ! Wc hydrogen bond
     905           0 :          wrk_section => Wc_section
     906           0 :          CALL colvar_create(colvar, Wc_colvar_id)
     907           0 :          CALL colvar_check_points(colvar, Wc_section)
     908           0 :          CALL section_vals_val_get(Wc_section, "ATOMS", i_vals=iatms)
     909           0 :          CALL section_vals_val_get(wrk_section, "RCUT", r_val=my_val(1))
     910           0 :          colvar%Wc%rcut = cp_unit_to_cp2k(my_val(1), "angstrom")
     911           0 :          colvar%Wc%ids = iatms
     912          40 :       ELSE IF (my_subsection(21)) THEN
     913             :          ! HBP colvar
     914           2 :          wrk_section => HBP_section
     915           2 :          CALL colvar_create(colvar, HBP_colvar_id)
     916           2 :          CALL colvar_check_points(colvar, HBP_section)
     917           2 :          CALL section_vals_val_get(wrk_section, "NPOINTS", i_val=colvar%HBP%nPoints)
     918           2 :          CALL section_vals_val_get(wrk_section, "RCUT", r_val=my_val(1))
     919           2 :          colvar%HBP%rcut = cp_unit_to_cp2k(my_val(1), "angstrom")
     920           2 :          CALL section_vals_val_get(wrk_section, "RCUT", r_val=colvar%HBP%shift)
     921             : 
     922           6 :          ALLOCATE (colvar%HBP%ids(colvar%HBP%nPoints, 3))
     923           6 :          ALLOCATE (colvar%HBP%ewc(colvar%HBP%nPoints))
     924           4 :          DO i = 1, colvar%HBP%nPoints
     925           2 :             CALL section_vals_val_get(wrk_section, "ATOMS", i_rep_val=i, i_vals=iatms)
     926          16 :             colvar%HBP%ids(i, :) = iatms
     927             :          END DO
     928          38 :       ELSE IF (my_subsection(22)) THEN
     929             :          ! Ring Puckering
     930          32 :          CALL colvar_create(colvar, ring_puckering_colvar_id)
     931          32 :          CALL section_vals_val_get(ring_puckering_section, "ATOMS", i_vals=iatms)
     932          32 :          colvar%ring_puckering_param%nring = SIZE(iatms)
     933          96 :          ALLOCATE (colvar%ring_puckering_param%atoms(SIZE(iatms)))
     934         388 :          colvar%ring_puckering_param%atoms = iatms
     935             :          CALL section_vals_val_get(ring_puckering_section, "COORDINATE", &
     936          32 :                                    i_val=colvar%ring_puckering_param%iq)
     937             :          ! test the validity of the parameters
     938          32 :          ndim = colvar%ring_puckering_param%nring
     939          32 :          IF (ndim <= 3) &
     940           0 :             CPABORT("CV Ring Puckering: Ring size has to be 4 or larger. ")
     941          32 :          ii = colvar%ring_puckering_param%iq
     942          32 :          IF (ABS(ii) == 1 .OR. ii < -(ndim - 1)/2 .OR. ii > ndim/2) &
     943           0 :             CPABORT("CV Ring Puckering: Invalid coordinate number.")
     944           6 :       ELSE IF (my_subsection(23)) THEN
     945             :          ! Minimum Distance
     946           0 :          wrk_section => mindist_section
     947           0 :          CALL colvar_create(colvar, mindist_colvar_id)
     948           0 :          CALL colvar_check_points(colvar, mindist_section)
     949           0 :          NULLIFY (colvar%mindist_param%i_dist_from, colvar%mindist_param%i_coord_from, &
     950           0 :                   colvar%mindist_param%k_coord_from, colvar%mindist_param%i_coord_to, &
     951           0 :                   colvar%mindist_param%k_coord_to)
     952           0 :          CALL section_vals_val_get(mindist_section, "ATOMS_DISTANCE", i_vals=iatms)
     953           0 :          colvar%mindist_param%n_dist_from = SIZE(iatms)
     954           0 :          ALLOCATE (colvar%mindist_param%i_dist_from(SIZE(iatms)))
     955           0 :          colvar%mindist_param%i_dist_from = iatms
     956           0 :          CALL section_vals_val_get(mindist_section, "ATOMS_FROM", n_rep_val=n_var)
     957           0 :          ndim = 0
     958           0 :          IF (n_var /= 0) THEN
     959             :             ! INDEX LIST
     960           0 :             DO k = 1, n_var
     961           0 :                CALL section_vals_val_get(mindist_section, "ATOMS_FROM", i_rep_val=k, i_vals=iatms)
     962           0 :                CALL reallocate(colvar%mindist_param%i_coord_from, 1, ndim + SIZE(iatms))
     963           0 :                colvar%mindist_param%i_coord_from(ndim + 1:ndim + SIZE(iatms)) = iatms
     964           0 :                ndim = ndim + SIZE(iatms)
     965             :             END DO
     966           0 :             colvar%mindist_param%n_coord_from = ndim
     967           0 :             colvar%mindist_param%use_kinds_from = .FALSE.
     968             :          ELSE
     969             :             !KINDS
     970           0 :             CALL section_vals_val_get(mindist_section, "KINDS_FROM", n_rep_val=n_var)
     971           0 :             CPASSERT(n_var > 0)
     972           0 :             DO k = 1, n_var
     973           0 :                CALL section_vals_val_get(mindist_section, "KINDS_FROM", i_rep_val=k, c_vals=c_kinds)
     974           0 :                CALL reallocate(colvar%mindist_param%k_coord_from, 1, ndim + SIZE(c_kinds))
     975           0 :                colvar%mindist_param%k_coord_from(ndim + 1:ndim + SIZE(c_kinds)) = c_kinds
     976           0 :                ndim = ndim + SIZE(c_kinds)
     977             :             END DO
     978           0 :             colvar%mindist_param%n_coord_from = 0
     979           0 :             colvar%mindist_param%use_kinds_from = .TRUE.
     980             :             ! Uppercase the label
     981           0 :             DO k = 1, ndim
     982           0 :                CALL uppercase(colvar%mindist_param%k_coord_from(k))
     983             :             END DO
     984             :          END IF
     985             : 
     986           0 :          CALL section_vals_val_get(mindist_section, "ATOMS_TO", n_rep_val=n_var)
     987           0 :          ndim = 0
     988           0 :          IF (n_var /= 0) THEN
     989             :             ! INDEX LIST
     990           0 :             DO k = 1, n_var
     991           0 :                CALL section_vals_val_get(mindist_section, "ATOMS_TO", i_rep_val=k, i_vals=iatms)
     992           0 :                CALL reallocate(colvar%mindist_param%i_coord_to, 1, ndim + SIZE(iatms))
     993           0 :                colvar%mindist_param%i_coord_to(ndim + 1:ndim + SIZE(iatms)) = iatms
     994           0 :                ndim = ndim + SIZE(iatms)
     995             :             END DO
     996           0 :             colvar%mindist_param%n_coord_to = ndim
     997           0 :             colvar%mindist_param%use_kinds_to = .FALSE.
     998             :          ELSE
     999             :             !KINDS
    1000           0 :             CALL section_vals_val_get(mindist_section, "KINDS_TO", n_rep_val=n_var)
    1001           0 :             CPASSERT(n_var > 0)
    1002           0 :             DO k = 1, n_var
    1003           0 :                CALL section_vals_val_get(mindist_section, "KINDS_TO", i_rep_val=k, c_vals=c_kinds)
    1004           0 :                CALL reallocate(colvar%mindist_param%k_coord_to, 1, ndim + SIZE(c_kinds))
    1005           0 :                colvar%mindist_param%k_coord_to(ndim + 1:ndim + SIZE(c_kinds)) = c_kinds
    1006           0 :                ndim = ndim + SIZE(c_kinds)
    1007             :             END DO
    1008           0 :             colvar%mindist_param%n_coord_to = 0
    1009           0 :             colvar%mindist_param%use_kinds_to = .TRUE.
    1010             :             ! Uppercase the label
    1011           0 :             DO k = 1, ndim
    1012           0 :                CALL uppercase(colvar%mindist_param%k_coord_to(k))
    1013             :             END DO
    1014             :          END IF
    1015             : 
    1016           0 :          CALL section_vals_val_get(mindist_section, "R0", r_val=colvar%mindist_param%r_cut)
    1017           0 :          CALL section_vals_val_get(mindist_section, "NN", i_val=colvar%mindist_param%p_exp)
    1018           0 :          CALL section_vals_val_get(mindist_section, "ND", i_val=colvar%mindist_param%q_exp)
    1019             : !       CALL section_vals_val_get(mindist_section,"NC",r_val=colvar%mindist_param%n_cut)
    1020           0 :          CALL section_vals_val_get(mindist_section, "LAMBDA", r_val=colvar%mindist_param%lambda)
    1021           6 :       ELSE IF (my_subsection(24)) THEN
    1022             :          ! Distance carboxylic acid and hydronium
    1023           2 :          CALL colvar_create(colvar, acid_hyd_dist_colvar_id)
    1024           2 :          NULLIFY (colvar%acid_hyd_dist_param%i_oxygens_water)
    1025           2 :          NULLIFY (colvar%acid_hyd_dist_param%i_oxygens_acid)
    1026           2 :          NULLIFY (colvar%acid_hyd_dist_param%i_hydrogens)
    1027             :          CALL read_acid_hydronium_colvars(acid_hyd_dist_section, colvar, acid_hyd_dist_colvar_id, &
    1028             :                                           colvar%acid_hyd_dist_param%n_oxygens_water, &
    1029             :                                           colvar%acid_hyd_dist_param%n_oxygens_acid, &
    1030             :                                           colvar%acid_hyd_dist_param%n_hydrogens, &
    1031             :                                           colvar%acid_hyd_dist_param%i_oxygens_water, &
    1032             :                                           colvar%acid_hyd_dist_param%i_oxygens_acid, &
    1033           2 :                                           colvar%acid_hyd_dist_param%i_hydrogens)
    1034           4 :       ELSE IF (my_subsection(25)) THEN
    1035             :          ! Number of oxygens in 1st shell of hydronium for carboxylic acid / water system
    1036           2 :          CALL colvar_create(colvar, acid_hyd_shell_colvar_id)
    1037           2 :          NULLIFY (colvar%acid_hyd_shell_param%i_oxygens_water)
    1038           2 :          NULLIFY (colvar%acid_hyd_shell_param%i_oxygens_acid)
    1039           2 :          NULLIFY (colvar%acid_hyd_shell_param%i_hydrogens)
    1040             :          CALL read_acid_hydronium_colvars(acid_hyd_shell_section, colvar, acid_hyd_shell_colvar_id, &
    1041             :                                           colvar%acid_hyd_shell_param%n_oxygens_water, &
    1042             :                                           colvar%acid_hyd_shell_param%n_oxygens_acid, &
    1043             :                                           colvar%acid_hyd_shell_param%n_hydrogens, &
    1044             :                                           colvar%acid_hyd_shell_param%i_oxygens_water, &
    1045             :                                           colvar%acid_hyd_shell_param%i_oxygens_acid, &
    1046           2 :                                           colvar%acid_hyd_shell_param%i_hydrogens)
    1047           2 :       ELSE IF (my_subsection(26)) THEN
    1048             :          ! Distance hydronium and hydroxide, autoionization of water
    1049           2 :          CALL colvar_create(colvar, hydronium_dist_colvar_id)
    1050           2 :          NULLIFY (colvar%hydronium_dist_param%i_oxygens)
    1051           2 :          NULLIFY (colvar%hydronium_dist_param%i_hydrogens)
    1052             :          CALL read_hydronium_colvars(hydronium_dist_section, colvar, hydronium_dist_colvar_id, &
    1053             :                                      colvar%hydronium_dist_param%n_oxygens, &
    1054             :                                      colvar%hydronium_dist_param%n_hydrogens, &
    1055             :                                      colvar%hydronium_dist_param%i_oxygens, &
    1056           2 :                                      colvar%hydronium_dist_param%i_hydrogens)
    1057             :       END IF
    1058         498 :       CALL colvar_setup(colvar)
    1059             : 
    1060             :       iw = cp_print_key_unit_nr(logger, colvar_section, &
    1061         498 :                                 "PRINT%PROGRAM_RUN_INFO", extension=".colvarLog")
    1062         498 :       IF (iw > 0) THEN
    1063         255 :          tag = "ATOMS: "
    1064         255 :          IF (colvar%use_points) tag = "POINTS:"
    1065             :          ! Description header
    1066         255 :          IF (colvar%type_id /= combine_colvar_id) THEN
    1067             :             WRITE (iw, '( A )') '          '// &
    1068         251 :                '----------------------------------------------------------------------'
    1069         251 :             WRITE (iw, '( A,I8)') ' COLVARS| COLVAR INPUT INDEX: ', icol
    1070             :          END IF
    1071             :          ! Colvar Description
    1072         281 :          SELECT CASE (colvar%type_id)
    1073             :          CASE (angle_colvar_id)
    1074          26 :             WRITE (iw, '( A,T57,3I8)') ' COLVARS| ANGLE          >>> '//tag, &
    1075          52 :                colvar%angle_param%i_at_angle
    1076             :          CASE (dfunct_colvar_id)
    1077           3 :             WRITE (iw, '( A,T49,4I8)') ' COLVARS| DISTANCE DIFFERENCE  >>> '//tag, &
    1078           6 :                colvar%dfunct_param%i_at_dfunct
    1079             :          CASE (plane_distance_colvar_id)
    1080          14 :             WRITE (iw, '( A,T57,3I8)') ' COLVARS| PLANE DISTANCE - PLANE  >>> '//tag, &
    1081          28 :                colvar%plane_distance_param%plane
    1082          14 :             WRITE (iw, '( A,T73,1I8)') ' COLVARS| PLANE DISTANCE - POINT  >>> '//tag, &
    1083          28 :                colvar%plane_distance_param%point
    1084             :          CASE (plane_plane_angle_colvar_id)
    1085           2 :             IF (colvar%plane_plane_angle_param%plane1%type_of_def == plane_def_atoms) THEN
    1086           2 :                WRITE (iw, '( A,T57,3I8)') ' COLVARS| PLANE-PLANE ANGLE - PLANE 1  (ATOMS) >>> '//tag, &
    1087           4 :                   colvar%plane_plane_angle_param%plane1%points
    1088             :             ELSE
    1089           0 :                WRITE (iw, '( A,T57,3F8.3)') ' COLVARS| PLANE-PLANE ANGLE - PLANE 1 (VECTOR) >>> '//tag, &
    1090           0 :                   colvar%plane_plane_angle_param%plane1%normal_vec
    1091             :             END IF
    1092             : 
    1093           2 :             IF (colvar%plane_plane_angle_param%plane2%type_of_def == plane_def_atoms) THEN
    1094           1 :                WRITE (iw, '( A,T57,3I8)') ' COLVARS| PLANE-PLANE ANGLE - PLANE 1  (ATOMS) >>> '//tag, &
    1095           2 :                   colvar%plane_plane_angle_param%plane2%points
    1096             :             ELSE
    1097           1 :                WRITE (iw, '( A,T57,3F8.3)') ' COLVARS| PLANE-PLANE ANGLE - PLANE 1 (VECTOR) >>> '//tag, &
    1098           2 :                   colvar%plane_plane_angle_param%plane2%normal_vec
    1099             :             END IF
    1100             :          CASE (torsion_colvar_id)
    1101          25 :             WRITE (iw, '( A,T49,4I8)') ' COLVARS| TORSION       >>> '//tag, &
    1102          50 :                colvar%torsion_param%i_at_tors
    1103             :          CASE (dist_colvar_id)
    1104         106 :             WRITE (iw, '( A,T65,2I8)') ' COLVARS| BOND          >>> '//tag, &
    1105         212 :                colvar%dist_param%i_at, colvar%dist_param%j_at
    1106             :          CASE (coord_colvar_id)
    1107          26 :             IF (colvar%coord_param%do_chain) THEN
    1108           2 :                WRITE (iw, '( A)') ' COLVARS| COORDINATION CHAIN FC(from->to)*FC(to->to_B)>> '
    1109             :             END IF
    1110          26 :             IF (colvar%coord_param%use_kinds_from) THEN
    1111           3 :                WRITE (iw, '( A,T71,A10)') (' COLVARS| COORDINATION  >>> FROM KINDS', &
    1112           6 :                                            ADJUSTR(colvar%coord_param%c_kinds_from(kk) (1:10)), &
    1113           9 :                                            kk=1, SIZE(colvar%coord_param%c_kinds_from))
    1114             :             ELSE
    1115          23 :                WRITE (iw, '( A,T71,I10)') (' COLVARS| COORDINATION  >>> FROM '//tag, &
    1116          46 :                                            colvar%coord_param%i_at_from(kk), &
    1117          69 :                                            kk=1, SIZE(colvar%coord_param%i_at_from))
    1118             :             END IF
    1119          26 :             IF (colvar%coord_param%use_kinds_to) THEN
    1120           3 :                WRITE (iw, '( A,T71,A10)') (' COLVARS| COORDINATION  >>>   TO KINDS', &
    1121           6 :                                            ADJUSTR(colvar%coord_param%c_kinds_to(kk) (1:10)), &
    1122           9 :                                            kk=1, SIZE(colvar%coord_param%c_kinds_to))
    1123             :             ELSE
    1124          36 :                WRITE (iw, '( A,T71,I10)') (' COLVARS| COORDINATION  >>>   TO '//tag, &
    1125          59 :                                            colvar%coord_param%i_at_to(kk), &
    1126          82 :                                            kk=1, SIZE(colvar%coord_param%i_at_to))
    1127             :             END IF
    1128          26 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| R0', colvar%coord_param%r_0
    1129          26 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| NN', colvar%coord_param%nncrd
    1130          26 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| ND', colvar%coord_param%ndcrd
    1131          26 :             IF (colvar%coord_param%do_chain) THEN
    1132           2 :                IF (colvar%coord_param%use_kinds_to_b) THEN
    1133           1 :                   WRITE (iw, '( A,T71,A10)') (' COLVARS| COORDINATION  >>>   TO KINDS B', &
    1134           2 :                                               ADJUSTR(colvar%coord_param%c_kinds_to_b(kk) (1:10)), &
    1135           3 :                                               kk=1, SIZE(colvar%coord_param%c_kinds_to_b))
    1136             :                ELSE
    1137           1 :                   WRITE (iw, '( A,T71,I10)') (' COLVARS| COORDINATION  >>>   TO '//tag//' B', &
    1138           2 :                                               colvar%coord_param%i_at_to_b(kk), &
    1139           3 :                                               kk=1, SIZE(colvar%coord_param%i_at_to_b))
    1140             :                END IF
    1141           2 :                WRITE (iw, '( A,T71,F10.5)') ' COLVARS| R0 B', colvar%coord_param%r_0_b
    1142           2 :                WRITE (iw, '( A,T71,I10)') ' COLVARS| NN B', colvar%coord_param%nncrd_b
    1143           2 :                WRITE (iw, '( A,T71,I10)') ' COLVARS| ND B', colvar%coord_param%ndcrd_b
    1144             :             END IF
    1145             :          CASE (population_colvar_id)
    1146           4 :             IF (colvar%population_param%use_kinds_from) THEN
    1147           0 :                WRITE (iw, '( A,T71,A10)') (' COLVARS| POPULATION based on coordination >>> FROM KINDS', &
    1148           0 :                                            ADJUSTR(colvar%population_param%c_kinds_from(kk) (1:10)), &
    1149           0 :                                            kk=1, SIZE(colvar%population_param%c_kinds_from))
    1150             :             ELSE
    1151           4 :                WRITE (iw, '( A,T71,I10)') (' COLVARS| POPULATION based on coordination >>> FROM '//tag, &
    1152           8 :                                            colvar%population_param%i_at_from(kk), &
    1153          12 :                                            kk=1, SIZE(colvar%population_param%i_at_from))
    1154             :             END IF
    1155           4 :             IF (colvar%population_param%use_kinds_to) THEN
    1156           4 :                WRITE (iw, '( A,T71,A10)') (' COLVARS| POPULATION based on coordination >>>   TO KINDS', &
    1157           8 :                                            ADJUSTR(colvar%population_param%c_kinds_to(kk) (1:10)), &
    1158          12 :                                            kk=1, SIZE(colvar%population_param%c_kinds_to))
    1159             :             ELSE
    1160           0 :                WRITE (iw, '( A,T71,I10)') (' COLVARS| POPULATION based on coordination   >>>   TO '//tag, &
    1161           0 :                                            colvar%population_param%i_at_to(kk), &
    1162           0 :                                            kk=1, SIZE(colvar%population_param%i_at_to))
    1163             :             END IF
    1164           4 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| R0', colvar%population_param%r_0
    1165           4 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| NN', colvar%population_param%nncrd
    1166           4 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| ND', colvar%population_param%ndcrd
    1167           4 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| N0', colvar%population_param%n0
    1168           4 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| SIGMA', colvar%population_param%sigma
    1169             :          CASE (gyration_colvar_id)
    1170           1 :             IF (colvar%gyration_param%use_kinds) THEN
    1171           1 :                WRITE (iw, '( A,T71,A10)') (' COLVARS| Gyration Radius >>> KINDS', &
    1172           2 :                                            ADJUSTR(colvar%gyration_param%c_kinds(kk) (1:10)), &
    1173           3 :                                            kk=1, SIZE(colvar%gyration_param%c_kinds))
    1174             :             ELSE
    1175           0 :                WRITE (iw, '( A,T71,I10)') (' COLVARS| Gyration Radius >>> ATOMS '//tag, &
    1176           0 :                                            colvar%gyration_param%i_at(kk), &
    1177           0 :                                            kk=1, SIZE(colvar%gyration_param%i_at))
    1178             :             END IF
    1179             :          CASE (rotation_colvar_id)
    1180           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| BOND_ROTATION   - POINT 1 LINE 1  >>> '//tag, &
    1181           2 :                colvar%rotation_param%i_at1_bond1
    1182           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| BOND_ROTATION   - POINT 2 LINE 1  >>> '//tag, &
    1183           2 :                colvar%rotation_param%i_at2_bond1
    1184           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| BOND_ROTATION   - POINT 1 LINE 2  >>> '//tag, &
    1185           2 :                colvar%rotation_param%i_at1_bond2
    1186           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| BOND_ROTATION   - POINT 2 LINE 2  >>> '//tag, &
    1187           2 :                colvar%rotation_param%i_at2_bond2
    1188             :          CASE (qparm_colvar_id)
    1189         108 :             WRITE (iw, '( A,T71,I10)') (' COLVARS| Q-PARM  >>> FROM '//tag, &
    1190         109 :                                         colvar%qparm_param%i_at_from(kk), &
    1191         110 :                                         kk=1, SIZE(colvar%qparm_param%i_at_from))
    1192         108 :             WRITE (iw, '( A,T71,I10)') (' COLVARS| Q-PARM  >>>   TO '//tag, &
    1193         109 :                                         colvar%qparm_param%i_at_to(kk), &
    1194         110 :                                         kk=1, SIZE(colvar%qparm_param%i_at_to))
    1195           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| RCUT', colvar%qparm_param%rcut
    1196           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| RSTART', colvar%qparm_param%rstart
    1197           1 :             WRITE (iw, '( A,T71,L10)') ' COLVARS| INCLUDE IMAGES', colvar%qparm_param%include_images
    1198             :             !WRITE (iw, '( A,T71,F10.5)') ' COLVARS| ALPHA', colvar%qparm_param%alpha
    1199           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| L', colvar%qparm_param%l
    1200             :          CASE (combine_colvar_id)
    1201             :             WRITE (iw, '( A)') ' COLVARS| COMBINING FUNCTION : '// &
    1202           4 :                TRIM(colvar%combine_cvs_param%function)
    1203           4 :             WRITE (iw, '( A)', ADVANCE="NO") ' COLVARS| VARIABLES : '
    1204          12 :             DO i = 1, SIZE(colvar%combine_cvs_param%variables)
    1205             :                WRITE (iw, '( A)', ADVANCE="NO") &
    1206          12 :                   TRIM(colvar%combine_cvs_param%variables(i))//" "
    1207             :             END DO
    1208           4 :             WRITE (iw, '(/)')
    1209           4 :             WRITE (iw, '( A)') ' COLVARS| DEFINED PARAMETERS [label]  [value]:'
    1210           6 :             DO i = 1, SIZE(colvar%combine_cvs_param%c_parameters)
    1211           2 :                WRITE (iw, '( A,A7,F9.3)') '                            ', &
    1212           8 :                   TRIM(colvar%combine_cvs_param%c_parameters(i)), colvar%combine_cvs_param%v_parameters(i)
    1213             :             END DO
    1214           4 :             WRITE (iw, '( A,T71,G10.5)') ' COLVARS| ERROR ON DERIVATIVE EVALUATION', &
    1215           8 :                colvar%combine_cvs_param%lerr
    1216           4 :             WRITE (iw, '( A,T71,G10.5)') ' COLVARS| DX', &
    1217           8 :                colvar%combine_cvs_param%dx
    1218             :          CASE (reaction_path_colvar_id)
    1219           5 :             CPWARN("Description header for REACTION_PATH COLVAR missing!")
    1220             :          CASE (distance_from_path_colvar_id)
    1221           4 :             CPWARN("Description header for REACTION_PATH COLVAR missing!")
    1222             :          CASE (hydronium_shell_colvar_id)
    1223           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| POH', colvar%hydronium_shell_param%poh
    1224           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QOH', colvar%hydronium_shell_param%qoh
    1225           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| POO', colvar%hydronium_shell_param%poo
    1226           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QOO', colvar%hydronium_shell_param%qoo
    1227           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| ROO', colvar%hydronium_shell_param%roo
    1228           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| ROH', colvar%hydronium_shell_param%roh
    1229           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| NH', colvar%hydronium_shell_param%nh
    1230           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| LAMBDA', colvar%hydronium_shell_param%lambda
    1231             :          CASE (hydronium_dist_colvar_id)
    1232           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| POH', colvar%hydronium_dist_param%poh
    1233           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QOH', colvar%hydronium_dist_param%qoh
    1234           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| ROH', colvar%hydronium_dist_param%roh
    1235           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| PM', colvar%hydronium_dist_param%pm
    1236           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QM', colvar%hydronium_dist_param%qm
    1237           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| NH', colvar%hydronium_dist_param%nh
    1238           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| PF', colvar%hydronium_dist_param%pf
    1239           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QF', colvar%hydronium_dist_param%qf
    1240           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| NN', colvar%hydronium_dist_param%nn
    1241             :          CASE (acid_hyd_dist_colvar_id)
    1242           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| PAOH', colvar%acid_hyd_dist_param%paoh
    1243           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QAOH', colvar%acid_hyd_dist_param%qaoh
    1244           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| PWOH', colvar%acid_hyd_dist_param%pwoh
    1245           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QWOH', colvar%acid_hyd_dist_param%qwoh
    1246           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| PCUT', colvar%acid_hyd_dist_param%pcut
    1247           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QCUT', colvar%acid_hyd_dist_param%qcut
    1248           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| RAOH', colvar%acid_hyd_dist_param%raoh
    1249           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| RWOH', colvar%acid_hyd_dist_param%rwoh
    1250           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| NC', colvar%acid_hyd_dist_param%nc
    1251           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| LAMBDA', colvar%acid_hyd_dist_param%lambda
    1252             :          CASE (acid_hyd_shell_colvar_id)
    1253           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| PAOH', colvar%acid_hyd_shell_param%paoh
    1254           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QAOH', colvar%acid_hyd_shell_param%qaoh
    1255           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| PWOH', colvar%acid_hyd_shell_param%pwoh
    1256           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QWOH', colvar%acid_hyd_shell_param%qwoh
    1257           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| POO', colvar%acid_hyd_shell_param%poo
    1258           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QOO', colvar%acid_hyd_shell_param%qoo
    1259           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| PM', colvar%acid_hyd_shell_param%pm
    1260           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QM', colvar%acid_hyd_shell_param%qm
    1261           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| PCUT', colvar%acid_hyd_shell_param%pcut
    1262           1 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| QCUT', colvar%acid_hyd_shell_param%qcut
    1263           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| RAOH', colvar%acid_hyd_shell_param%raoh
    1264           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| RWOH', colvar%acid_hyd_shell_param%rwoh
    1265           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| ROO', colvar%acid_hyd_shell_param%roo
    1266           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| NH', colvar%acid_hyd_shell_param%nh
    1267           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| NC', colvar%acid_hyd_shell_param%nc
    1268           1 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| LAMBDA', colvar%acid_hyd_shell_param%lambda
    1269             :          CASE (rmsd_colvar_id)
    1270           2 :             CPWARN("Description header for RMSD COLVAR missing!")
    1271             :          CASE (xyz_diag_colvar_id)
    1272           3 :             NULLIFY (section, keyword, enum)
    1273           3 :             CALL create_colvar_xyz_d_section(section)
    1274           3 :             keyword => section_get_keyword(section, "COMPONENT")
    1275           3 :             CALL keyword_get(keyword, enum=enum)
    1276           3 :             tag_comp = enum_i2c(enum, colvar%xyz_diag_param%component)
    1277           3 :             CALL section_release(section)
    1278             : 
    1279             :             WRITE (iw, '( A,T57,3I8)') ' COLVARS| POSITION ('//TRIM(tag_comp) &
    1280           3 :                //')  >>> '//tag, colvar%xyz_diag_param%i_atom
    1281             :          CASE (xyz_outerdiag_colvar_id)
    1282           3 :             NULLIFY (section, keyword, enum)
    1283           3 :             CALL create_colvar_xyz_od_section(section)
    1284           3 :             keyword => section_get_keyword(section, "COMPONENT_A")
    1285           3 :             CALL keyword_get(keyword, enum=enum)
    1286           3 :             tag_comp1 = enum_i2c(enum, colvar%xyz_outerdiag_param%components(1))
    1287           3 :             keyword => section_get_keyword(section, "COMPONENT_B")
    1288           3 :             CALL keyword_get(keyword, enum=enum)
    1289           3 :             tag_comp2 = enum_i2c(enum, colvar%xyz_outerdiag_param%components(2))
    1290           3 :             CALL section_release(section)
    1291             : 
    1292             :             WRITE (iw, '( A,T57,3I8)') ' COLVARS| CROSS TERM POSITION ('//TRIM(tag_comp1) &
    1293           3 :                //" * "//TRIM(tag_comp2)//')  >>> '//tag, colvar%xyz_outerdiag_param%i_atoms
    1294             :          CASE (u_colvar_id)
    1295           4 :             WRITE (iw, '( A,T77,A4)') ' COLVARS| ENERGY          >>> '//tag, 'all!'
    1296             :          CASE (Wc_colvar_id)
    1297           0 :             WRITE (iw, '( A,T57,F16.8)') ' COLVARS| Wc          >>> RCUT: ', &
    1298           0 :                colvar%Wc%rcut
    1299           0 :             WRITE (iw, '( A,T57,3I8)') ' COLVARS| Wc          >>> '//tag, &
    1300           0 :                colvar%Wc%ids
    1301             :          CASE (HBP_colvar_id)
    1302           1 :             WRITE (iw, '( A,T57,I8)') ' COLVARS| HBP          >>> NPOINTS', &
    1303           2 :                colvar%HBP%nPoints
    1304           1 :             WRITE (iw, '( A,T57,F16.8)') ' COLVARS| HBP          >>> RCUT', &
    1305           2 :                colvar%HBP%rcut
    1306           1 :             WRITE (iw, '( A,T57,F16.8)') ' COLVARS| HBP          >>> RCUT', &
    1307           2 :                colvar%HBP%shift
    1308           2 :             DO i = 1, colvar%HBP%nPoints
    1309           1 :                WRITE (iw, '( A,T57,3I8)') ' COLVARS| HBP          >>> '//tag, &
    1310           3 :                   colvar%HBP%ids(i, :)
    1311             :             END DO
    1312             :          CASE (ring_puckering_colvar_id)
    1313          16 :             WRITE (iw, '( A,T57,I8)') ' COLVARS| Ring Puckering      >>> ring size', &
    1314          32 :                colvar%ring_puckering_param%nring
    1315          16 :             IF (colvar%ring_puckering_param%iq == 0) THEN
    1316           4 :                WRITE (iw, '( A,T40,A)') ' COLVARS| Ring Puckering      >>> coordinate', &
    1317           8 :                   ' Total Puckering Amplitude'
    1318          12 :             ELSEIF (colvar%ring_puckering_param%iq > 0) THEN
    1319           8 :                WRITE (iw, '( A,T35,A,T57,I8)') ' COLVARS| Ring Puckering      >>> coordinate', &
    1320           8 :                   ' Puckering Amplitude', &
    1321          16 :                   colvar%ring_puckering_param%iq
    1322             :             ELSE
    1323           4 :                WRITE (iw, '( A,T35,A,T57,I8)') ' COLVARS| Ring Puckering      >>> coordinate', &
    1324           4 :                   ' Puckering Angle', &
    1325           8 :                   colvar%ring_puckering_param%iq
    1326             :             END IF
    1327             :          CASE (mindist_colvar_id)
    1328           0 :             WRITE (iw, '( A)') ' COLVARS| CONDITIONED DISTANCE>> '
    1329           0 :             WRITE (iw, '( A,T71,I10)') (' COLVARS| COND.DISTANCE  >>> DISTANCE FROM '//tag, &
    1330           0 :                                         colvar%mindist_param%i_dist_from(kk), &
    1331           0 :                                         kk=1, SIZE(colvar%mindist_param%i_dist_from))
    1332           0 :             IF (colvar%mindist_param%use_kinds_from) THEN
    1333           0 :                WRITE (iw, '( A,T71,A10)') (' COLVARS| COND.DIST.  >>> COORDINATION FROM KINDS ', &
    1334           0 :                                            ADJUSTR(colvar%mindist_param%k_coord_from(kk) (1:10)), &
    1335           0 :                                            kk=1, SIZE(colvar%mindist_param%k_coord_from))
    1336             :             ELSE
    1337           0 :                WRITE (iw, '( A,T71,I10)') (' COLVARS| COND.DIST.  >>> COORDINATION FROM '//tag, &
    1338           0 :                                            colvar%mindist_param%i_coord_from(kk), &
    1339           0 :                                            kk=1, SIZE(colvar%mindist_param%i_coord_from))
    1340             :             END IF
    1341           0 :             IF (colvar%mindist_param%use_kinds_to) THEN
    1342           0 :                WRITE (iw, '( A,T71,A10)') (' COLVARS| COND.DIST.  >>> COORDINATION TO KINDS ', &
    1343           0 :                                            ADJUSTR(colvar%mindist_param%k_coord_to(kk) (1:10)), &
    1344           0 :                                            kk=1, SIZE(colvar%mindist_param%k_coord_to))
    1345             :             ELSE
    1346           0 :                WRITE (iw, '( A,T71,I10)') (' COLVARS| COND.DIST.  >>> COORDINATION TO '//tag, &
    1347           0 :                                            colvar%mindist_param%i_coord_to(kk), &
    1348           0 :                                            kk=1, SIZE(colvar%mindist_param%i_coord_to))
    1349             :             END IF
    1350           0 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| R0', colvar%mindist_param%r_cut
    1351           0 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| NN', colvar%mindist_param%p_exp
    1352           0 :             WRITE (iw, '( A,T71,I10)') ' COLVARS| ND', colvar%mindist_param%q_exp
    1353         255 :             WRITE (iw, '( A,T71,F10.5)') ' COLVARS| LAMBDA', colvar%mindist_param%lambda
    1354             : 
    1355             :          END SELECT
    1356         255 :          IF (colvar%use_points) THEN
    1357          13 :             WRITE (iw, '( A)') ' COLVARS| INFORMATION ON DEFINED GEOMETRICAL POINTS'
    1358          51 :             DO kk = 1, SIZE(colvar%points)
    1359          38 :                point_section => section_vals_get_subs_vals(wrk_section, "POINT")
    1360          38 :                CALL section_vals_val_get(point_section, "TYPE", i_rep_section=kk, c_val=tmpStr)
    1361          38 :                tmpStr2 = cp_to_string(kk)
    1362          38 :                WRITE (iw, '( A)') ' COLVARS|  POINT Nr.'//TRIM(tmpStr2)//' OF TYPE: '//TRIM(tmpStr)
    1363          51 :                IF (ASSOCIATED(colvar%points(kk)%atoms)) THEN
    1364          37 :                   WRITE (iw, '( A)') ' COLVARS|   ATOMS BUILDING THE GEOMETRICAL POINT'
    1365          86 :                   WRITE (iw, '( A, I10)') (' COLVARS|   ATOM:', colvar%points(kk)%atoms(k), k=1, SIZE(colvar%points(kk)%atoms))
    1366             :                ELSE
    1367           4 :                   WRITE (iw, '( A,4X,3F12.6)') ' COLVARS|   XYZ POSITION OF FIXED POINT:', colvar%points(kk)%r
    1368             :                END IF
    1369             :             END DO
    1370             :          END IF
    1371             :          ! Close the description layer
    1372         255 :          IF (colvar%type_id /= combine_colvar_id) THEN
    1373             :             WRITE (iw, '( A )') '          '// &
    1374         251 :                '----------------------------------------------------------------------'
    1375             :          ELSE
    1376             :             WRITE (iw, '( A )') '          '// &
    1377           4 :                '**********************************************************************'
    1378             :          END IF
    1379             :       END IF
    1380             :       CALL cp_print_key_finished_output(iw, logger, colvar_section, &
    1381         498 :                                         "PRINT%PROGRAM_RUN_INFO")
    1382         498 :       CALL timestop(handle)
    1383         498 :    END SUBROUTINE colvar_read
    1384             : 
    1385             : ! **************************************************************************************************
    1386             : !> \brief read collective variables for the autoionization of water
    1387             : !> \param section ...
    1388             : !> \param colvar collective variable
    1389             : !> \param colvar_id  ...
    1390             : !> \param n_oxygens number of oxygens
    1391             : !> \param n_hydrogens number of hydrogens
    1392             : !> \param i_oxygens list of oxygens
    1393             : !> \param i_hydrogens list of hydrogens
    1394             : !> \author Dorothea Golze
    1395             : ! **************************************************************************************************
    1396           8 :    SUBROUTINE read_hydronium_colvars(section, colvar, colvar_id, n_oxygens, n_hydrogens, &
    1397             :                                      i_oxygens, i_hydrogens)
    1398             :       TYPE(section_vals_type), POINTER                   :: section
    1399             :       TYPE(colvar_type), POINTER                         :: colvar
    1400             :       INTEGER, INTENT(IN)                                :: colvar_id
    1401             :       INTEGER, INTENT(OUT)                               :: n_oxygens, n_hydrogens
    1402             :       INTEGER, DIMENSION(:), POINTER                     :: i_oxygens, i_hydrogens
    1403             : 
    1404             :       INTEGER                                            :: k, n_var, ndim
    1405           4 :       INTEGER, DIMENSION(:), POINTER                     :: iatms
    1406             : 
    1407           4 :       NULLIFY (iatms)
    1408             : 
    1409           4 :       CALL section_vals_val_get(section, "OXYGENS", n_rep_val=n_var)
    1410           4 :       ndim = 0
    1411           8 :       DO k = 1, n_var
    1412           4 :          CALL section_vals_val_get(section, "OXYGENS", i_rep_val=k, i_vals=iatms)
    1413           4 :          CALL reallocate(i_oxygens, 1, ndim + SIZE(iatms))
    1414          40 :          i_oxygens(ndim + 1:ndim + SIZE(iatms)) = iatms
    1415           8 :          ndim = ndim + SIZE(iatms)
    1416             :       END DO
    1417           4 :       n_oxygens = ndim
    1418             : 
    1419           4 :       CALL section_vals_val_get(section, "HYDROGENS", n_rep_val=n_var)
    1420           4 :       ndim = 0
    1421           8 :       DO k = 1, n_var
    1422           4 :          CALL section_vals_val_get(section, "HYDROGENS", i_rep_val=k, i_vals=iatms)
    1423           4 :          CALL reallocate(i_hydrogens, 1, ndim + SIZE(iatms))
    1424          80 :          i_hydrogens(ndim + 1:ndim + SIZE(iatms)) = iatms
    1425           8 :          ndim = ndim + SIZE(iatms)
    1426             :       END DO
    1427           4 :       n_hydrogens = ndim
    1428             : 
    1429           6 :       SELECT CASE (colvar_id)
    1430             :       CASE (hydronium_shell_colvar_id)
    1431           2 :          CALL section_vals_val_get(section, "ROO", r_val=colvar%hydronium_shell_param%roo)
    1432           2 :          CALL section_vals_val_get(section, "ROH", r_val=colvar%hydronium_shell_param%roh)
    1433           2 :          CALL section_vals_val_get(section, "pOH", i_val=colvar%hydronium_shell_param%poh)
    1434           2 :          CALL section_vals_val_get(section, "qOH", i_val=colvar%hydronium_shell_param%qoh)
    1435           2 :          CALL section_vals_val_get(section, "pOO", i_val=colvar%hydronium_shell_param%poo)
    1436           2 :          CALL section_vals_val_get(section, "qOO", i_val=colvar%hydronium_shell_param%qoo)
    1437           2 :          CALL section_vals_val_get(section, "pM", i_val=colvar%hydronium_shell_param%pm)
    1438           2 :          CALL section_vals_val_get(section, "qM", i_val=colvar%hydronium_shell_param%qm)
    1439           2 :          CALL section_vals_val_get(section, "NH", r_val=colvar%hydronium_shell_param%nh)
    1440           2 :          CALL section_vals_val_get(section, "LAMBDA", r_val=colvar%hydronium_shell_param%lambda)
    1441             :       CASE (hydronium_dist_colvar_id)
    1442           2 :          CALL section_vals_val_get(section, "ROH", r_val=colvar%hydronium_dist_param%roh)
    1443           2 :          CALL section_vals_val_get(section, "pOH", i_val=colvar%hydronium_dist_param%poh)
    1444           2 :          CALL section_vals_val_get(section, "qOH", i_val=colvar%hydronium_dist_param%qoh)
    1445           2 :          CALL section_vals_val_get(section, "pF", i_val=colvar%hydronium_dist_param%pf)
    1446           2 :          CALL section_vals_val_get(section, "qF", i_val=colvar%hydronium_dist_param%qf)
    1447           2 :          CALL section_vals_val_get(section, "pM", i_val=colvar%hydronium_dist_param%pm)
    1448           2 :          CALL section_vals_val_get(section, "qM", i_val=colvar%hydronium_dist_param%qm)
    1449           2 :          CALL section_vals_val_get(section, "NH", r_val=colvar%hydronium_dist_param%nh)
    1450           2 :          CALL section_vals_val_get(section, "NN", r_val=colvar%hydronium_dist_param%nn)
    1451           6 :          CALL section_vals_val_get(section, "LAMBDA", r_val=colvar%hydronium_dist_param%lambda)
    1452             :       END SELECT
    1453             : 
    1454           4 :    END SUBROUTINE read_hydronium_colvars
    1455             : 
    1456             : ! **************************************************************************************************
    1457             : !> \brief read collective variables for the dissociation of a carboxylic acid
    1458             : !>        in water
    1459             : !> \param section ...
    1460             : !> \param colvar collective variable
    1461             : !> \param colvar_id  ...
    1462             : !> \param n_oxygens_water number of oxygens of water molecules
    1463             : !> \param n_oxygens_acid number of oxgyens of carboxyl groups
    1464             : !> \param n_hydrogens number of hydrogens (water and carboxyl group)
    1465             : !> \param i_oxygens_water list of oxygens of water molecules
    1466             : !> \param i_oxygens_acid list of oxygens of carboxyl group
    1467             : !> \param i_hydrogens list of hydrogens (water and carboxyl group)
    1468             : !> \author Dorothea Golze
    1469             : ! **************************************************************************************************
    1470          12 :    SUBROUTINE read_acid_hydronium_colvars(section, colvar, colvar_id, n_oxygens_water, &
    1471             :                                           n_oxygens_acid, n_hydrogens, i_oxygens_water, &
    1472             :                                           i_oxygens_acid, i_hydrogens)
    1473             :       TYPE(section_vals_type), POINTER                   :: section
    1474             :       TYPE(colvar_type), POINTER                         :: colvar
    1475             :       INTEGER, INTENT(IN)                                :: colvar_id
    1476             :       INTEGER, INTENT(OUT)                               :: n_oxygens_water, n_oxygens_acid, &
    1477             :                                                             n_hydrogens
    1478             :       INTEGER, DIMENSION(:), POINTER                     :: i_oxygens_water, i_oxygens_acid, &
    1479             :                                                             i_hydrogens
    1480             : 
    1481             :       INTEGER                                            :: k, n_var, ndim
    1482           4 :       INTEGER, DIMENSION(:), POINTER                     :: iatms
    1483             : 
    1484           4 :       NULLIFY (iatms)
    1485             : 
    1486           4 :       CALL section_vals_val_get(section, "OXYGENS_WATER", n_rep_val=n_var)
    1487           4 :       ndim = 0
    1488           8 :       DO k = 1, n_var
    1489           4 :          CALL section_vals_val_get(section, "OXYGENS_WATER", i_rep_val=k, i_vals=iatms)
    1490           4 :          CALL reallocate(i_oxygens_water, 1, ndim + SIZE(iatms))
    1491          24 :          i_oxygens_water(ndim + 1:ndim + SIZE(iatms)) = iatms
    1492           8 :          ndim = ndim + SIZE(iatms)
    1493             :       END DO
    1494           4 :       n_oxygens_water = ndim
    1495             : 
    1496           4 :       CALL section_vals_val_get(section, "OXYGENS_ACID", n_rep_val=n_var)
    1497           4 :       ndim = 0
    1498           8 :       DO k = 1, n_var
    1499           4 :          CALL section_vals_val_get(section, "OXYGENS_ACID", i_rep_val=k, i_vals=iatms)
    1500           4 :          CALL reallocate(i_oxygens_acid, 1, ndim + SIZE(iatms))
    1501          24 :          i_oxygens_acid(ndim + 1:ndim + SIZE(iatms)) = iatms
    1502           8 :          ndim = ndim + SIZE(iatms)
    1503             :       END DO
    1504           4 :       n_oxygens_acid = ndim
    1505             : 
    1506           4 :       CALL section_vals_val_get(section, "HYDROGENS", n_rep_val=n_var)
    1507           4 :       ndim = 0
    1508           8 :       DO k = 1, n_var
    1509           4 :          CALL section_vals_val_get(section, "HYDROGENS", i_rep_val=k, i_vals=iatms)
    1510           4 :          CALL reallocate(i_hydrogens, 1, ndim + SIZE(iatms))
    1511          48 :          i_hydrogens(ndim + 1:ndim + SIZE(iatms)) = iatms
    1512           8 :          ndim = ndim + SIZE(iatms)
    1513             :       END DO
    1514           4 :       n_hydrogens = ndim
    1515             : 
    1516           6 :       SELECT CASE (colvar_id)
    1517             :       CASE (acid_hyd_dist_colvar_id)
    1518           2 :          CALL section_vals_val_get(section, "pWOH", i_val=colvar%acid_hyd_dist_param%pwoh)
    1519           2 :          CALL section_vals_val_get(section, "qWOH", i_val=colvar%acid_hyd_dist_param%qwoh)
    1520           2 :          CALL section_vals_val_get(section, "pAOH", i_val=colvar%acid_hyd_dist_param%paoh)
    1521           2 :          CALL section_vals_val_get(section, "qAOH", i_val=colvar%acid_hyd_dist_param%qaoh)
    1522           2 :          CALL section_vals_val_get(section, "pCUT", i_val=colvar%acid_hyd_dist_param%pcut)
    1523           2 :          CALL section_vals_val_get(section, "qCUT", i_val=colvar%acid_hyd_dist_param%qcut)
    1524           2 :          CALL section_vals_val_get(section, "RWOH", r_val=colvar%acid_hyd_dist_param%rwoh)
    1525           2 :          CALL section_vals_val_get(section, "RAOH", r_val=colvar%acid_hyd_dist_param%raoh)
    1526           2 :          CALL section_vals_val_get(section, "NC", r_val=colvar%acid_hyd_dist_param%nc)
    1527           2 :          CALL section_vals_val_get(section, "LAMBDA", r_val=colvar%acid_hyd_dist_param%lambda)
    1528             :       CASE (acid_hyd_shell_colvar_id)
    1529           2 :          CALL section_vals_val_get(section, "pWOH", i_val=colvar%acid_hyd_shell_param%pwoh)
    1530           2 :          CALL section_vals_val_get(section, "qWOH", i_val=colvar%acid_hyd_shell_param%qwoh)
    1531           2 :          CALL section_vals_val_get(section, "pAOH", i_val=colvar%acid_hyd_shell_param%paoh)
    1532           2 :          CALL section_vals_val_get(section, "qAOH", i_val=colvar%acid_hyd_shell_param%qaoh)
    1533           2 :          CALL section_vals_val_get(section, "pOO", i_val=colvar%acid_hyd_shell_param%poo)
    1534           2 :          CALL section_vals_val_get(section, "qOO", i_val=colvar%acid_hyd_shell_param%qoo)
    1535           2 :          CALL section_vals_val_get(section, "pM", i_val=colvar%acid_hyd_shell_param%pm)
    1536           2 :          CALL section_vals_val_get(section, "qM", i_val=colvar%acid_hyd_shell_param%qm)
    1537           2 :          CALL section_vals_val_get(section, "pCUT", i_val=colvar%acid_hyd_shell_param%pcut)
    1538           2 :          CALL section_vals_val_get(section, "qCUT", i_val=colvar%acid_hyd_shell_param%qcut)
    1539           2 :          CALL section_vals_val_get(section, "RWOH", r_val=colvar%acid_hyd_shell_param%rwoh)
    1540           2 :          CALL section_vals_val_get(section, "RAOH", r_val=colvar%acid_hyd_shell_param%raoh)
    1541           2 :          CALL section_vals_val_get(section, "ROO", r_val=colvar%acid_hyd_shell_param%roo)
    1542           2 :          CALL section_vals_val_get(section, "NC", r_val=colvar%acid_hyd_shell_param%nc)
    1543           2 :          CALL section_vals_val_get(section, "NH", r_val=colvar%acid_hyd_shell_param%nh)
    1544           6 :          CALL section_vals_val_get(section, "LAMBDA", r_val=colvar%acid_hyd_shell_param%lambda)
    1545             :       END SELECT
    1546             : 
    1547           4 :    END SUBROUTINE read_acid_hydronium_colvars
    1548             : 
    1549             : ! **************************************************************************************************
    1550             : !> \brief Check and setup about the use of geometrical points instead of atoms
    1551             : !> \param colvar the colvat to initialize
    1552             : !> \param section ...
    1553             : !> \author Teodoro Laino, [teo] 03.2007
    1554             : ! **************************************************************************************************
    1555         844 :    SUBROUTINE colvar_check_points(colvar, section)
    1556             :       TYPE(colvar_type), POINTER                         :: colvar
    1557             :       TYPE(section_vals_type), POINTER                   :: section
    1558             : 
    1559             :       INTEGER                                            :: i, irep, natoms, npoints, nrep, nweights
    1560         422 :       INTEGER, DIMENSION(:), POINTER                     :: atoms
    1561             :       LOGICAL                                            :: explicit
    1562         422 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: r, weights
    1563             :       TYPE(section_vals_type), POINTER                   :: point_sections
    1564             : 
    1565         422 :       NULLIFY (point_sections)
    1566         422 :       NULLIFY (atoms)
    1567         422 :       NULLIFY (weights)
    1568           0 :       CPASSERT(ASSOCIATED(colvar))
    1569         422 :       point_sections => section_vals_get_subs_vals(section, "POINT")
    1570         422 :       CALL section_vals_get(point_sections, explicit=explicit)
    1571         422 :       IF (explicit) THEN
    1572          26 :          colvar%use_points = .TRUE.
    1573          26 :          CALL section_vals_get(point_sections, n_repetition=npoints)
    1574         232 :          ALLOCATE (colvar%points(npoints))
    1575             :          ! Read points definition
    1576         128 :          DO i = 1, npoints
    1577          76 :             natoms = 0
    1578          76 :             nweights = 0
    1579          76 :             NULLIFY (colvar%points(i)%atoms)
    1580          76 :             NULLIFY (colvar%points(i)%weights)
    1581          76 :             CALL section_vals_val_get(point_sections, "TYPE", i_rep_section=i, i_val=colvar%points(i)%type_id)
    1582          26 :             SELECT CASE (colvar%points(i)%type_id)
    1583             :             CASE (do_clv_geo_center)
    1584             :                ! Define a point through a list of atoms..
    1585          74 :                CALL section_vals_val_get(point_sections, "ATOMS", i_rep_section=i, n_rep_val=nrep, i_vals=atoms)
    1586         148 :                DO irep = 1, nrep
    1587          74 :                   CALL section_vals_val_get(point_sections, "ATOMS", i_rep_section=i, i_rep_val=irep, i_vals=atoms)
    1588         148 :                   natoms = natoms + SIZE(atoms)
    1589             :                END DO
    1590         222 :                ALLOCATE (colvar%points(i)%atoms(natoms))
    1591          74 :                natoms = 0
    1592         148 :                DO irep = 1, nrep
    1593          74 :                   CALL section_vals_val_get(point_sections, "ATOMS", i_rep_section=i, i_rep_val=irep, i_vals=atoms)
    1594         344 :                   colvar%points(i)%atoms(natoms + 1:) = atoms(:)
    1595         148 :                   natoms = natoms + SIZE(atoms)
    1596             :                END DO
    1597             :                ! Define weights of the list
    1598         222 :                ALLOCATE (colvar%points(i)%weights(natoms))
    1599         172 :                colvar%points(i)%weights = 1.0_dp/REAL(natoms, KIND=dp)
    1600          74 :                CALL section_vals_val_get(point_sections, "WEIGHTS", i_rep_section=i, n_rep_val=nrep)
    1601         148 :                IF (nrep /= 0) THEN
    1602           8 :                   DO irep = 1, nrep
    1603             :                      CALL section_vals_val_get(point_sections, "WEIGHTS", i_rep_section=i, i_rep_val=irep, &
    1604           4 :                                                r_vals=weights)
    1605          32 :                      colvar%points(i)%weights(nweights + 1:) = weights(:)
    1606           8 :                      nweights = nweights + SIZE(weights)
    1607             :                   END DO
    1608           4 :                   CPASSERT(natoms == nweights)
    1609             :                END IF
    1610             :             CASE (do_clv_fix_point)
    1611             :                ! Define the point as a fixed point in space..
    1612           2 :                CALL section_vals_val_get(point_sections, "XYZ", i_rep_section=i, r_vals=r)
    1613          92 :                colvar%points(i)%r = r
    1614             :             END SELECT
    1615             :          END DO
    1616             :       END IF
    1617         422 :    END SUBROUTINE colvar_check_points
    1618             : 
    1619             : ! **************************************************************************************************
    1620             : !> \brief evaluates the derivatives (dsdr) given and due to the given colvar
    1621             : !>      variables in a molecular environment
    1622             : !> \param colvar the collective variable to evaluate
    1623             : !> \param cell ...
    1624             : !> \param particles ...
    1625             : !> \param pos ...
    1626             : !> \param fixd_list ...
    1627             : !> \author Teodoro Laino
    1628             : ! **************************************************************************************************
    1629      389699 :    SUBROUTINE colvar_eval_mol_f(colvar, cell, particles, pos, fixd_list)
    1630             :       TYPE(colvar_type), POINTER                         :: colvar
    1631             :       TYPE(cell_type), POINTER                           :: cell
    1632             :       TYPE(particle_type), DIMENSION(:), POINTER         :: particles
    1633             :       REAL(kind=dp), DIMENSION(:, :), INTENT(IN), &
    1634             :          OPTIONAL                                        :: pos
    1635             :       TYPE(fixd_constraint_type), DIMENSION(:), &
    1636             :          OPTIONAL, POINTER                               :: fixd_list
    1637             : 
    1638             :       INTEGER                                            :: i, j
    1639             :       LOGICAL                                            :: colvar_ok
    1640             : 
    1641      389699 :       colvar_ok = ASSOCIATED(colvar)
    1642      389699 :       CPASSERT(colvar_ok)
    1643             : 
    1644      389699 :       IF (PRESENT(pos)) THEN
    1645     1099443 :          DO i = 1, SIZE(colvar%i_atom)
    1646      735140 :             j = colvar%i_atom(i)
    1647     3304863 :             particles(j)%r = pos(:, j)
    1648             :          END DO
    1649             :       END IF
    1650             :       ! Initialize the content of the derivative
    1651     3568091 :       colvar%dsdr = 0.0_dp
    1652      768402 :       SELECT CASE (colvar%type_id)
    1653             :       CASE (dist_colvar_id)
    1654      378703 :          CALL dist_colvar(colvar, cell, particles=particles)
    1655             :       CASE (coord_colvar_id)
    1656          42 :          CALL coord_colvar(colvar, cell, particles=particles)
    1657             :       CASE (population_colvar_id)
    1658           0 :          CALL population_colvar(colvar, cell, particles=particles)
    1659             :       CASE (gyration_colvar_id)
    1660           0 :          CALL gyration_radius_colvar(colvar, cell, particles=particles)
    1661             :       CASE (torsion_colvar_id)
    1662        2076 :          CALL torsion_colvar(colvar, cell, particles=particles)
    1663             :       CASE (angle_colvar_id)
    1664        5393 :          CALL angle_colvar(colvar, cell, particles=particles)
    1665             :       CASE (dfunct_colvar_id)
    1666         632 :          CALL dfunct_colvar(colvar, cell, particles=particles)
    1667             :       CASE (plane_distance_colvar_id)
    1668           0 :          CALL plane_distance_colvar(colvar, cell, particles=particles)
    1669             :       CASE (plane_plane_angle_colvar_id)
    1670        1604 :          CALL plane_plane_angle_colvar(colvar, cell, particles=particles)
    1671             :       CASE (rotation_colvar_id)
    1672           0 :          CALL rotation_colvar(colvar, cell, particles=particles)
    1673             :       CASE (qparm_colvar_id)
    1674           0 :          CALL qparm_colvar(colvar, cell, particles=particles)
    1675             :       CASE (hydronium_shell_colvar_id)
    1676           0 :          CALL hydronium_shell_colvar(colvar, cell, particles=particles)
    1677             :       CASE (hydronium_dist_colvar_id)
    1678           0 :          CALL hydronium_dist_colvar(colvar, cell, particles=particles)
    1679             :       CASE (acid_hyd_dist_colvar_id)
    1680           0 :          CALL acid_hyd_dist_colvar(colvar, cell, particles=particles)
    1681             :       CASE (acid_hyd_shell_colvar_id)
    1682           0 :          CALL acid_hyd_shell_colvar(colvar, cell, particles=particles)
    1683             :       CASE (rmsd_colvar_id)
    1684           0 :          CALL rmsd_colvar(colvar, particles=particles)
    1685             :       CASE (reaction_path_colvar_id)
    1686           8 :          CALL reaction_path_colvar(colvar, cell, particles=particles)
    1687             :       CASE (distance_from_path_colvar_id)
    1688           0 :          CALL distance_from_path_colvar(colvar, cell, particles=particles)
    1689             :       CASE (combine_colvar_id)
    1690          23 :          CALL combine_colvar(colvar, cell, particles=particles)
    1691             :       CASE (xyz_diag_colvar_id)
    1692         609 :          CALL xyz_diag_colvar(colvar, cell, particles=particles)
    1693             :       CASE (xyz_outerdiag_colvar_id)
    1694         609 :          CALL xyz_outerdiag_colvar(colvar, cell, particles=particles)
    1695             :       CASE (ring_puckering_colvar_id)
    1696           0 :          CALL ring_puckering_colvar(colvar, cell, particles=particles)
    1697             :       CASE (mindist_colvar_id)
    1698           0 :          CALL mindist_colvar(colvar, cell, particles=particles)
    1699             :       CASE (u_colvar_id)
    1700           0 :          CPABORT("need force_env!")
    1701             :       CASE (Wc_colvar_id)
    1702             :          !!! FIXME this is rubbish at the moment as we have no force to be computed on this
    1703           0 :          CALL Wc_colvar(colvar, cell, particles=particles)
    1704             :       CASE (HBP_colvar_id)
    1705             :          !!! FIXME this is rubbish at the moment as we have no force to be computed on this
    1706           0 :          CALL HBP_colvar(colvar, cell, particles=particles)
    1707             :       CASE DEFAULT
    1708      389699 :          CPABORT("")
    1709             :       END SELECT
    1710             :       ! Check for fixed atom constraints
    1711      389699 :       IF (PRESENT(fixd_list)) CALL check_fixed_atom_cns_colv(fixd_list, colvar)
    1712             : 
    1713      389699 :    END SUBROUTINE colvar_eval_mol_f
    1714             : 
    1715             : ! **************************************************************************************************
    1716             : !> \brief evaluates the derivatives (dsdr) given and due to the given colvar
    1717             : !> \param icolvar the collective variable to evaluate
    1718             : !> \param force_env ...
    1719             : !> \author Alessandro Laio and fawzi
    1720             : !> \note
    1721             : !>      The torsion that generally is defined without the continuity problem
    1722             : !>      here (for free energy calculations) is defined only for (-pi,pi]
    1723             : ! **************************************************************************************************
    1724       14600 :    SUBROUTINE colvar_eval_glob_f(icolvar, force_env)
    1725             :       INTEGER                                            :: icolvar
    1726             :       TYPE(force_env_type), POINTER                      :: force_env
    1727             : 
    1728             :       LOGICAL                                            :: colvar_ok
    1729             :       TYPE(cell_type), POINTER                           :: cell
    1730             :       TYPE(colvar_type), POINTER                         :: colvar
    1731             :       TYPE(cp_subsys_type), POINTER                      :: subsys
    1732             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1733             : 
    1734       14600 :       NULLIFY (subsys, cell, colvar, qs_env)
    1735       14600 :       CALL force_env_get(force_env, subsys=subsys, cell=cell, qs_env=qs_env)
    1736       14600 :       colvar_ok = ASSOCIATED(subsys%colvar_p)
    1737       14600 :       CPASSERT(colvar_ok)
    1738             : 
    1739       14600 :       colvar => subsys%colvar_p(icolvar)%colvar
    1740             :       ! Initialize the content of the derivative
    1741      200688 :       colvar%dsdr = 0.0_dp
    1742       26178 :       SELECT CASE (colvar%type_id)
    1743             :       CASE (dist_colvar_id)
    1744       11578 :          CALL dist_colvar(colvar, cell, subsys=subsys)
    1745             :       CASE (coord_colvar_id)
    1746         472 :          CALL coord_colvar(colvar, cell, subsys=subsys)
    1747             :       CASE (population_colvar_id)
    1748         144 :          CALL population_colvar(colvar, cell, subsys=subsys)
    1749             :       CASE (gyration_colvar_id)
    1750           8 :          CALL gyration_radius_colvar(colvar, cell, subsys=subsys)
    1751             :       CASE (torsion_colvar_id)
    1752           0 :          CALL torsion_colvar(colvar, cell, subsys=subsys, no_riemann_sheet_op=.TRUE.)
    1753             :       CASE (angle_colvar_id)
    1754         102 :          CALL angle_colvar(colvar, cell, subsys=subsys)
    1755             :       CASE (dfunct_colvar_id)
    1756           0 :          CALL dfunct_colvar(colvar, cell, subsys=subsys)
    1757             :       CASE (plane_distance_colvar_id)
    1758        1358 :          CALL plane_distance_colvar(colvar, cell, subsys=subsys)
    1759             :       CASE (plane_plane_angle_colvar_id)
    1760           0 :          CALL plane_plane_angle_colvar(colvar, cell, subsys=subsys)
    1761             :       CASE (rotation_colvar_id)
    1762           8 :          CALL rotation_colvar(colvar, cell, subsys=subsys)
    1763             :       CASE (qparm_colvar_id)
    1764          42 :          CALL qparm_colvar(colvar, cell, subsys=subsys)
    1765             :       CASE (hydronium_shell_colvar_id)
    1766          12 :          CALL hydronium_shell_colvar(colvar, cell, subsys=subsys)
    1767             :       CASE (hydronium_dist_colvar_id)
    1768          12 :          CALL hydronium_dist_colvar(colvar, cell, subsys=subsys)
    1769             :       CASE (acid_hyd_dist_colvar_id)
    1770           8 :          CALL acid_hyd_dist_colvar(colvar, cell, subsys=subsys)
    1771             :       CASE (acid_hyd_shell_colvar_id)
    1772           8 :          CALL acid_hyd_shell_colvar(colvar, cell, subsys=subsys)
    1773             :       CASE (rmsd_colvar_id)
    1774          24 :          CALL rmsd_colvar(colvar, subsys=subsys)
    1775             :       CASE (reaction_path_colvar_id)
    1776         248 :          CALL reaction_path_colvar(colvar, cell, subsys=subsys)
    1777             :       CASE (distance_from_path_colvar_id)
    1778         248 :          CALL distance_from_path_colvar(colvar, cell, subsys=subsys)
    1779             :       CASE (combine_colvar_id)
    1780          66 :          CALL combine_colvar(colvar, cell, subsys=subsys)
    1781             :       CASE (xyz_diag_colvar_id)
    1782           0 :          CALL xyz_diag_colvar(colvar, cell, subsys=subsys)
    1783             :       CASE (xyz_outerdiag_colvar_id)
    1784           0 :          CALL xyz_outerdiag_colvar(colvar, cell, subsys=subsys)
    1785             :       CASE (u_colvar_id)
    1786          32 :          CALL u_colvar(colvar, force_env=force_env)
    1787             :       CASE (Wc_colvar_id)
    1788           0 :          CALL Wc_colvar(colvar, cell, subsys=subsys, qs_env=qs_env)
    1789             :       CASE (HBP_colvar_id)
    1790          10 :          CALL HBP_colvar(colvar, cell, subsys=subsys, qs_env=qs_env)
    1791             :       CASE (ring_puckering_colvar_id)
    1792         220 :          CALL ring_puckering_colvar(colvar, cell, subsys=subsys)
    1793             :       CASE (mindist_colvar_id)
    1794           0 :          CALL mindist_colvar(colvar, cell, subsys=subsys)
    1795             :       CASE DEFAULT
    1796       14600 :          CPABORT("")
    1797             :       END SELECT
    1798             :       ! Check for fixed atom constraints
    1799       14600 :       CALL check_fixed_atom_cns_colv(subsys%gci%fixd_list, colvar)
    1800       14600 :    END SUBROUTINE colvar_eval_glob_f
    1801             : 
    1802             : ! **************************************************************************************************
    1803             : !> \brief evaluates the derivatives (dsdr) given and due to the given colvar
    1804             : !>        for the specification of a recursive colvar type
    1805             : !> \param colvar the collective variable to evaluate
    1806             : !> \param cell ...
    1807             : !> \param particles ...
    1808             : !> \author sfchiff
    1809             : ! **************************************************************************************************
    1810         370 :    SUBROUTINE colvar_recursive_eval(colvar, cell, particles)
    1811             :       TYPE(colvar_type), POINTER                         :: colvar
    1812             :       TYPE(cell_type), POINTER                           :: cell
    1813             :       TYPE(particle_type), DIMENSION(:), POINTER         :: particles
    1814             : 
    1815             : ! Initialize the content of the derivative
    1816             : 
    1817        5442 :       colvar%dsdr = 0.0_dp
    1818         608 :       SELECT CASE (colvar%type_id)
    1819             :       CASE (dist_colvar_id)
    1820         238 :          CALL dist_colvar(colvar, cell, particles=particles)
    1821             :       CASE (coord_colvar_id)
    1822           0 :          CALL coord_colvar(colvar, cell, particles=particles)
    1823             :       CASE (torsion_colvar_id)
    1824           0 :          CALL torsion_colvar(colvar, cell, particles=particles)
    1825             :       CASE (angle_colvar_id)
    1826           0 :          CALL angle_colvar(colvar, cell, particles=particles)
    1827             :       CASE (dfunct_colvar_id)
    1828           0 :          CALL dfunct_colvar(colvar, cell, particles=particles)
    1829             :       CASE (plane_distance_colvar_id)
    1830           0 :          CALL plane_distance_colvar(colvar, cell, particles=particles)
    1831             :       CASE (plane_plane_angle_colvar_id)
    1832           0 :          CALL plane_plane_angle_colvar(colvar, cell, particles=particles)
    1833             :       CASE (rotation_colvar_id)
    1834           0 :          CALL rotation_colvar(colvar, cell, particles=particles)
    1835             :       CASE (qparm_colvar_id)
    1836           0 :          CALL qparm_colvar(colvar, cell, particles=particles)
    1837             :       CASE (hydronium_shell_colvar_id)
    1838           0 :          CALL hydronium_shell_colvar(colvar, cell, particles=particles)
    1839             :       CASE (hydronium_dist_colvar_id)
    1840           0 :          CALL hydronium_dist_colvar(colvar, cell, particles=particles)
    1841             :       CASE (acid_hyd_dist_colvar_id)
    1842           0 :          CALL acid_hyd_dist_colvar(colvar, cell, particles=particles)
    1843             :       CASE (acid_hyd_shell_colvar_id)
    1844           0 :          CALL acid_hyd_shell_colvar(colvar, cell, particles=particles)
    1845             :       CASE (rmsd_colvar_id)
    1846           0 :          CALL rmsd_colvar(colvar, particles=particles)
    1847             :       CASE (reaction_path_colvar_id)
    1848           0 :          CALL reaction_path_colvar(colvar, cell, particles=particles)
    1849             :       CASE (distance_from_path_colvar_id)
    1850           0 :          CALL distance_from_path_colvar(colvar, cell, particles=particles)
    1851             :       CASE (combine_colvar_id)
    1852           0 :          CALL combine_colvar(colvar, cell, particles=particles)
    1853             :       CASE (xyz_diag_colvar_id)
    1854           0 :          CALL xyz_diag_colvar(colvar, cell, particles=particles)
    1855             :       CASE (xyz_outerdiag_colvar_id)
    1856           0 :          CALL xyz_outerdiag_colvar(colvar, cell, particles=particles)
    1857             :       CASE (ring_puckering_colvar_id)
    1858         132 :          CALL ring_puckering_colvar(colvar, cell, particles=particles)
    1859             :       CASE (mindist_colvar_id)
    1860           0 :          CALL mindist_colvar(colvar, cell, particles=particles)
    1861             :       CASE (u_colvar_id)
    1862           0 :          CPABORT("need force_env!")
    1863             :       CASE (Wc_colvar_id)
    1864           0 :          CALL Wc_colvar(colvar, cell, particles=particles)
    1865             :       CASE (HBP_colvar_id)
    1866           0 :          CALL HBP_colvar(colvar, cell, particles=particles)
    1867             :       CASE DEFAULT
    1868         370 :          CPABORT("")
    1869             :       END SELECT
    1870         370 :    END SUBROUTINE colvar_recursive_eval
    1871             : 
    1872             : ! **************************************************************************************************
    1873             : !> \brief Get coordinates of atoms or of geometrical points
    1874             : !> \param colvar ...
    1875             : !> \param i ...
    1876             : !> \param ri ...
    1877             : !> \param my_particles ...
    1878             : !> \author Teodoro Laino 03.2007 [created]
    1879             : ! **************************************************************************************************
    1880     7200068 :    SUBROUTINE get_coordinates(colvar, i, ri, my_particles)
    1881             :       TYPE(colvar_type), POINTER                         :: colvar
    1882             :       INTEGER, INTENT(IN)                                :: i
    1883             :       REAL(KIND=dp), DIMENSION(3), INTENT(OUT)           :: ri
    1884             :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    1885             : 
    1886     7200068 :       IF (colvar%use_points) THEN
    1887        8644 :          CALL eval_point_pos(colvar%points(i), my_particles, ri)
    1888             :       ELSE
    1889    28765696 :          ri(:) = my_particles(i)%r(:)
    1890             :       END IF
    1891             : 
    1892     7200068 :    END SUBROUTINE get_coordinates
    1893             : 
    1894             : ! **************************************************************************************************
    1895             : !> \brief Get masses of atoms or of geometrical points
    1896             : !> \param colvar ...
    1897             : !> \param i ...
    1898             : !> \param mi ...
    1899             : !> \param my_particles ...
    1900             : !> \author Teodoro Laino 03.2007 [created]
    1901             : ! **************************************************************************************************
    1902         208 :    SUBROUTINE get_mass(colvar, i, mi, my_particles)
    1903             :       TYPE(colvar_type), POINTER                         :: colvar
    1904             :       INTEGER, INTENT(IN)                                :: i
    1905             :       REAL(KIND=dp), INTENT(OUT)                         :: mi
    1906             :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    1907             : 
    1908         208 :       IF (colvar%use_points) THEN
    1909           0 :          CALL eval_point_mass(colvar%points(i), my_particles, mi)
    1910             :       ELSE
    1911         208 :          mi = my_particles(i)%atomic_kind%mass
    1912             :       END IF
    1913             : 
    1914         208 :    END SUBROUTINE get_mass
    1915             : 
    1916             : ! **************************************************************************************************
    1917             : !> \brief Transfer derivatives to ds/dr
    1918             : !> \param colvar ...
    1919             : !> \param i ...
    1920             : !> \param fi ...
    1921             : !> \author Teodoro Laino 03.2007 [created]
    1922             : ! **************************************************************************************************
    1923      836954 :    SUBROUTINE put_derivative(colvar, i, fi)
    1924             :       TYPE(colvar_type), POINTER                         :: colvar
    1925             :       INTEGER, INTENT(IN)                                :: i
    1926             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: fi
    1927             : 
    1928      836954 :       IF (colvar%use_points) THEN
    1929        8664 :          CALL eval_point_der(colvar%points, i, colvar%dsdr, fi)
    1930             :       ELSE
    1931     3313160 :          colvar%dsdr(:, i) = colvar%dsdr(:, i) + fi
    1932             :       END IF
    1933             : 
    1934      836954 :    END SUBROUTINE put_derivative
    1935             : 
    1936             : ! **************************************************************************************************
    1937             : !> \brief  evaluates the force due to the position colvar
    1938             : !> \param colvar ...
    1939             : !> \param cell ...
    1940             : !> \param subsys ...
    1941             : !> \param particles ...
    1942             : !> \author Teodoro Laino 02.2010 [created]
    1943             : ! **************************************************************************************************
    1944         609 :    SUBROUTINE xyz_diag_colvar(colvar, cell, subsys, particles)
    1945             :       TYPE(colvar_type), POINTER                         :: colvar
    1946             :       TYPE(cell_type), POINTER                           :: cell
    1947             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    1948             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    1949             :          POINTER                                         :: particles
    1950             : 
    1951             :       INTEGER                                            :: i
    1952             :       REAL(dp)                                           :: fi(3), r, r0(3), ss(3), xi(3), xpi(3)
    1953             :       TYPE(particle_list_type), POINTER                  :: particles_i
    1954         609 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    1955             : 
    1956         609 :       NULLIFY (particles_i)
    1957             : 
    1958           0 :       CPASSERT(colvar%type_id == xyz_diag_colvar_id)
    1959         609 :       IF (PRESENT(particles)) THEN
    1960         609 :          my_particles => particles
    1961             :       ELSE
    1962           0 :          CPASSERT(PRESENT(subsys))
    1963           0 :          CALL cp_subsys_get(subsys, particles=particles_i)
    1964           0 :          my_particles => particles_i%els
    1965             :       END IF
    1966         609 :       i = colvar%xyz_diag_param%i_atom
    1967             :       ! Atom coordinates
    1968         609 :       CALL get_coordinates(colvar, i, xpi, my_particles)
    1969             :       ! Use the current coordinates as initial coordinates, if no initialization
    1970             :       ! was performed yet
    1971         609 :       IF (.NOT. colvar%xyz_diag_param%use_absolute_position) THEN
    1972         627 :          IF (ALL(colvar%xyz_diag_param%r0 == HUGE(0.0_dp))) THEN
    1973          24 :             colvar%xyz_diag_param%r0 = xpi
    1974             :          END IF
    1975        2436 :          r0 = colvar%xyz_diag_param%r0
    1976             :       ELSE
    1977           0 :          r0 = 0.0_dp
    1978             :       END IF
    1979             : 
    1980         609 :       IF (colvar%xyz_diag_param%use_pbc) THEN
    1981        9744 :          ss = MATMUL(cell%h_inv, xpi - r0)
    1982        2436 :          ss = ss - NINT(ss)
    1983        7917 :          xi = MATMUL(cell%hmat, ss)
    1984             :       ELSE
    1985           0 :          xi = xpi - r0
    1986             :       END IF
    1987             : 
    1988         609 :       IF (.NOT. colvar%xyz_diag_param%use_absolute_position) THEN
    1989         609 :          SELECT CASE (colvar%xyz_diag_param%component)
    1990             :          CASE (do_clv_x)
    1991           0 :             xi(2) = 0.0_dp
    1992           0 :             xi(3) = 0.0_dp
    1993             :          CASE (do_clv_y)
    1994           0 :             xi(1) = 0.0_dp
    1995           0 :             xi(3) = 0.0_dp
    1996             :          CASE (do_clv_z)
    1997           0 :             xi(1) = 0.0_dp
    1998           0 :             xi(2) = 0.0_dp
    1999             :          CASE (do_clv_xy)
    2000           0 :             xi(3) = 0.0_dp
    2001             :          CASE (do_clv_xz)
    2002           0 :             xi(2) = 0.0_dp
    2003             :          CASE (do_clv_yz)
    2004         609 :             xi(1) = 0.0_dp
    2005             :          CASE DEFAULT
    2006             :             ! do_clv_xyz
    2007             :          END SELECT
    2008             : 
    2009         609 :          r = xi(1)**2 + xi(2)**2 + xi(3)**2
    2010        2436 :          fi(:) = 2.0_dp*xi
    2011             :       ELSE
    2012           0 :          SELECT CASE (colvar%xyz_diag_param%component)
    2013             :          CASE (do_clv_x)
    2014           0 :             r = xi(1)
    2015           0 :             xi(1) = 1.0_dp
    2016           0 :             xi(2) = 0.0_dp
    2017           0 :             xi(3) = 0.0_dp
    2018             :          CASE (do_clv_y)
    2019           0 :             r = xi(2)
    2020           0 :             xi(1) = 0.0_dp
    2021           0 :             xi(2) = 1.0_dp
    2022           0 :             xi(3) = 0.0_dp
    2023             :          CASE (do_clv_z)
    2024           0 :             r = xi(3)
    2025           0 :             xi(1) = 0.0_dp
    2026           0 :             xi(2) = 0.0_dp
    2027           0 :             xi(3) = 1.0_dp
    2028             :          CASE DEFAULT
    2029             :             !Not implemented for anything which is not a single component.
    2030           0 :             CPABORT("")
    2031             :          END SELECT
    2032           0 :          fi(:) = xi
    2033             :       END IF
    2034             : 
    2035         609 :       colvar%ss = r
    2036         609 :       CALL put_derivative(colvar, 1, fi)
    2037             : 
    2038         609 :    END SUBROUTINE xyz_diag_colvar
    2039             : 
    2040             : ! **************************************************************************************************
    2041             : !> \brief  evaluates the force due to the position colvar
    2042             : !> \param colvar ...
    2043             : !> \param cell ...
    2044             : !> \param subsys ...
    2045             : !> \param particles ...
    2046             : !> \author Teodoro Laino 02.2010 [created]
    2047             : ! **************************************************************************************************
    2048         609 :    SUBROUTINE xyz_outerdiag_colvar(colvar, cell, subsys, particles)
    2049             :       TYPE(colvar_type), POINTER                         :: colvar
    2050             :       TYPE(cell_type), POINTER                           :: cell
    2051             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    2052             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    2053             :          POINTER                                         :: particles
    2054             : 
    2055             :       INTEGER                                            :: i, k, l
    2056             :       REAL(dp)                                           :: fi(3, 2), r, r0(3), ss(3), xi(3, 2), &
    2057             :                                                             xpi(3)
    2058             :       TYPE(particle_list_type), POINTER                  :: particles_i
    2059         609 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    2060             : 
    2061         609 :       NULLIFY (particles_i)
    2062             : 
    2063           0 :       CPASSERT(colvar%type_id == xyz_outerdiag_colvar_id)
    2064         609 :       IF (PRESENT(particles)) THEN
    2065         609 :          my_particles => particles
    2066             :       ELSE
    2067           0 :          CPASSERT(PRESENT(subsys))
    2068           0 :          CALL cp_subsys_get(subsys, particles=particles_i)
    2069           0 :          my_particles => particles_i%els
    2070             :       END IF
    2071        1827 :       DO k = 1, 2
    2072        1218 :          i = colvar%xyz_outerdiag_param%i_atoms(k)
    2073             :          ! Atom coordinates
    2074        1218 :          CALL get_coordinates(colvar, i, xpi, my_particles)
    2075        4872 :          r0 = colvar%xyz_outerdiag_param%r0(:, k)
    2076        1254 :          IF (ALL(colvar%xyz_outerdiag_param%r0(:, k) == HUGE(0.0_dp))) r0 = xpi
    2077             : 
    2078        1218 :          IF (colvar%xyz_outerdiag_param%use_pbc) THEN
    2079       19488 :             ss = MATMUL(cell%h_inv, xpi - r0)
    2080        4872 :             ss = ss - NINT(ss)
    2081       19488 :             xi(:, k) = MATMUL(cell%hmat, ss)
    2082             :          ELSE
    2083           0 :             xi(:, k) = xpi - r0
    2084             :          END IF
    2085             : 
    2086         609 :          SELECT CASE (colvar%xyz_outerdiag_param%components(k))
    2087             :          CASE (do_clv_x)
    2088         609 :             xi(2, k) = 0.0_dp
    2089         609 :             xi(3, k) = 0.0_dp
    2090             :          CASE (do_clv_y)
    2091         406 :             xi(1, k) = 0.0_dp
    2092         406 :             xi(3, k) = 0.0_dp
    2093             :          CASE (do_clv_z)
    2094         203 :             xi(1, k) = 0.0_dp
    2095         203 :             xi(2, k) = 0.0_dp
    2096             :          CASE (do_clv_xy)
    2097           0 :             xi(3, k) = 0.0_dp
    2098             :          CASE (do_clv_xz)
    2099           0 :             xi(2, k) = 0.0_dp
    2100             :          CASE (do_clv_yz)
    2101        1218 :             xi(1, k) = 0.0_dp
    2102             :          CASE DEFAULT
    2103             :             ! do_clv_xyz
    2104             :          END SELECT
    2105             :       END DO
    2106             : 
    2107         609 :       r = 0.0_dp
    2108         609 :       fi = 0.0_dp
    2109        2436 :       DO i = 1, 3
    2110        7308 :          DO l = 1, 3
    2111        5481 :             IF (xi(l, 1) /= 0.0_dp) fi(l, 1) = fi(l, 1) + xi(i, 2)
    2112        7308 :             r = r + xi(l, 1)*xi(i, 2)
    2113             :          END DO
    2114        4227 :          IF (xi(i, 2) /= 0.0_dp) fi(i, 2) = SUM(xi(:, 1))
    2115             :       END DO
    2116             : 
    2117         609 :       colvar%ss = r
    2118         609 :       CALL put_derivative(colvar, 1, fi(:, 1))
    2119         609 :       CALL put_derivative(colvar, 2, fi(:, 2))
    2120             : 
    2121         609 :    END SUBROUTINE xyz_outerdiag_colvar
    2122             : 
    2123             : ! **************************************************************************************************
    2124             : !> \brief evaluates the force due (and on) the energy as collective variable
    2125             : !> \param colvar ...
    2126             : !> \param force_env ...
    2127             : !> \par History Modified to allow functions of energy in a mixed_env environment
    2128             : !>              Teodoro Laino [tlaino] - 02.2011
    2129             : !> \author Sebastiano Caravati
    2130             : ! **************************************************************************************************
    2131          32 :    SUBROUTINE u_colvar(colvar, force_env)
    2132             :       TYPE(colvar_type), POINTER                         :: colvar
    2133             :       TYPE(force_env_type), OPTIONAL, POINTER            :: force_env
    2134             : 
    2135             :       CHARACTER(LEN=default_path_length)                 :: coupling_function
    2136             :       CHARACTER(LEN=default_string_length)               :: def_error, this_error
    2137             :       CHARACTER(LEN=default_string_length), &
    2138          32 :          DIMENSION(:), POINTER                           :: parameters
    2139             :       INTEGER                                            :: iatom, iforce_eval, iparticle, &
    2140             :                                                             jparticle, natom, natom_iforce, &
    2141             :                                                             nforce_eval
    2142          32 :       INTEGER, DIMENSION(:), POINTER                     :: glob_natoms, map_index
    2143             :       REAL(dp)                                           :: dedf, dx, err, fi(3), lerr, &
    2144             :                                                             potential_energy
    2145          32 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: values
    2146          32 :       TYPE(cp_subsys_p_type), DIMENSION(:), POINTER      :: subsystems
    2147             :       TYPE(cp_subsys_type), POINTER                      :: subsys_main
    2148          32 :       TYPE(mixed_force_type), DIMENSION(:), POINTER      :: global_forces
    2149          32 :       TYPE(particle_list_p_type), DIMENSION(:), POINTER  :: particles
    2150             :       TYPE(particle_list_type), POINTER                  :: particles_main
    2151             :       TYPE(section_vals_type), POINTER                   :: force_env_section, mapping_section, &
    2152             :                                                             wrk_section
    2153             : 
    2154          32 :       IF (PRESENT(force_env)) THEN
    2155          32 :          NULLIFY (particles_main, subsys_main)
    2156          32 :          CALL force_env_get(force_env=force_env, subsys=subsys_main)
    2157          32 :          CALL cp_subsys_get(subsys=subsys_main, particles=particles_main)
    2158          32 :          natom = SIZE(particles_main%els)
    2159          32 :          colvar%n_atom_s = natom
    2160          32 :          colvar%u_param%natom = natom
    2161          32 :          CALL reallocate(colvar%i_atom, 1, natom)
    2162          32 :          CALL reallocate(colvar%dsdr, 1, 3, 1, natom)
    2163         164 :          DO iatom = 1, natom
    2164         164 :             colvar%i_atom(iatom) = iatom
    2165             :          END DO
    2166             : 
    2167          32 :          IF (.NOT. ASSOCIATED(colvar%u_param%mixed_energy_section)) THEN
    2168          12 :             CALL force_env_get(force_env, potential_energy=potential_energy)
    2169          12 :             colvar%ss = potential_energy
    2170             : 
    2171          84 :             DO iatom = 1, natom
    2172             :                ! store derivative
    2173         288 :                fi(:) = -particles_main%els(iatom)%f
    2174          84 :                CALL put_derivative(colvar, iatom, fi)
    2175             :             END DO
    2176             :          ELSE
    2177          20 :             IF (force_env%in_use /= use_mixed_force) &
    2178             :                CALL cp_abort(__LOCATION__, &
    2179             :                              'ASSERTION (cond) failed at line '//cp_to_string(__LINE__)// &
    2180             :                              ' A combination of mixed force_eval energies has been requested as '// &
    2181           0 :                              ' collective variable, but the MIXED env is not in use! Aborting.')
    2182          20 :             CALL force_env_get(force_env, force_env_section=force_env_section)
    2183          20 :             mapping_section => section_vals_get_subs_vals(force_env_section, "MIXED%MAPPING")
    2184          20 :             NULLIFY (values, parameters, subsystems, particles, global_forces, map_index, glob_natoms)
    2185          20 :             nforce_eval = SIZE(force_env%sub_force_env)
    2186          60 :             ALLOCATE (glob_natoms(nforce_eval))
    2187         100 :             ALLOCATE (subsystems(nforce_eval))
    2188          80 :             ALLOCATE (particles(nforce_eval))
    2189             :             ! Local Info to sync
    2190         100 :             ALLOCATE (global_forces(nforce_eval))
    2191             : 
    2192          60 :             glob_natoms = 0
    2193          60 :             DO iforce_eval = 1, nforce_eval
    2194          40 :                NULLIFY (subsystems(iforce_eval)%subsys, particles(iforce_eval)%list)
    2195          40 :                IF (.NOT. ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) CYCLE
    2196             :                ! Get all available subsys
    2197             :                CALL force_env_get(force_env=force_env%sub_force_env(iforce_eval)%force_env, &
    2198          20 :                                   subsys=subsystems(iforce_eval)%subsys)
    2199             :                ! Get available particles
    2200             :                CALL cp_subsys_get(subsys=subsystems(iforce_eval)%subsys, &
    2201          20 :                                   particles=particles(iforce_eval)%list)
    2202             : 
    2203             :                ! Get Mapping index array
    2204          20 :                natom_iforce = SIZE(particles(iforce_eval)%list%els)
    2205             : 
    2206             :                ! Only the rank 0 process collect info for each computation
    2207          40 :                IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
    2208          40 :                   glob_natoms(iforce_eval) = natom_iforce
    2209             :                END IF
    2210             :             END DO
    2211             : 
    2212             :             ! Handling Parallel execution
    2213          20 :             CALL force_env%para_env%sync()
    2214         100 :             CALL force_env%para_env%sum(glob_natoms)
    2215             : 
    2216             :             ! Transfer forces
    2217          60 :             DO iforce_eval = 1, nforce_eval
    2218         120 :                ALLOCATE (global_forces(iforce_eval)%forces(3, glob_natoms(iforce_eval)))
    2219         520 :                global_forces(iforce_eval)%forces = 0.0_dp
    2220          40 :                IF (ASSOCIATED(force_env%sub_force_env(iforce_eval)%force_env)) THEN
    2221          20 :                   IF (force_env%sub_force_env(iforce_eval)%force_env%para_env%is_source()) THEN
    2222             :                      ! Forces
    2223          80 :                      DO iparticle = 1, glob_natoms(iforce_eval)
    2224             :                         global_forces(iforce_eval)%forces(:, iparticle) = &
    2225         440 :                            particles(iforce_eval)%list%els(iparticle)%f
    2226             :                      END DO
    2227             :                   END IF
    2228             :                END IF
    2229        1020 :                CALL force_env%para_env%sum(global_forces(iforce_eval)%forces)
    2230             :             END DO
    2231             : 
    2232          20 :             wrk_section => colvar%u_param%mixed_energy_section
    2233             :             ! Support any number of force_eval sections
    2234             :             CALL get_generic_info(wrk_section, "ENERGY_FUNCTION", coupling_function, parameters, &
    2235          20 :                                   values, force_env%mixed_env%energies)
    2236          20 :             CALL initf(1)
    2237          20 :             CALL parsef(1, TRIM(coupling_function), parameters)
    2238             :             ! Store the value of the COLVAR
    2239          20 :             colvar%ss = evalf(1, values)
    2240          20 :             CPASSERT(EvalErrType <= 0)
    2241             : 
    2242          60 :             DO iforce_eval = 1, nforce_eval
    2243          40 :                CALL section_vals_val_get(wrk_section, "DX", r_val=dx)
    2244          40 :                CALL section_vals_val_get(wrk_section, "ERROR_LIMIT", r_val=lerr)
    2245          40 :                dedf = evalfd(1, iforce_eval, values, dx, err)
    2246          40 :                IF (ABS(err) > lerr) THEN
    2247           0 :                   WRITE (this_error, "(A,G12.6,A)") "(", err, ")"
    2248           0 :                   WRITE (def_error, "(A,G12.6,A)") "(", lerr, ")"
    2249           0 :                   CALL compress(this_error, .TRUE.)
    2250           0 :                   CALL compress(def_error, .TRUE.)
    2251             :                   CALL cp_warn(__LOCATION__, &
    2252             :                                'ASSERTION (cond) failed at line '//cp_to_string(__LINE__)// &
    2253             :                                ' Error '//TRIM(this_error)//' in computing numerical derivatives larger then'// &
    2254           0 :                                TRIM(def_error)//' .')
    2255             :                END IF
    2256             :                ! General Mapping of forces...
    2257             :                ! First: Get Mapping index array
    2258             :                CALL get_subsys_map_index(mapping_section, glob_natoms(iforce_eval), iforce_eval, &
    2259          40 :                                          nforce_eval, map_index)
    2260             : 
    2261             :                ! Second: store derivatives
    2262         160 :                DO iparticle = 1, glob_natoms(iforce_eval)
    2263         120 :                   jparticle = map_index(iparticle)
    2264         480 :                   fi = -dedf*global_forces(iforce_eval)%forces(:, iparticle)
    2265         160 :                   CALL put_derivative(colvar, jparticle, fi)
    2266             :                END DO
    2267             :                ! Deallocate map_index array
    2268         100 :                IF (ASSOCIATED(map_index)) THEN
    2269          40 :                   DEALLOCATE (map_index)
    2270             :                END IF
    2271             :             END DO
    2272          20 :             CALL finalizef()
    2273          60 :             DO iforce_eval = 1, nforce_eval
    2274          60 :                DEALLOCATE (global_forces(iforce_eval)%forces)
    2275             :             END DO
    2276          20 :             DEALLOCATE (glob_natoms)
    2277          20 :             DEALLOCATE (values)
    2278          20 :             DEALLOCATE (parameters)
    2279          20 :             DEALLOCATE (global_forces)
    2280          20 :             DEALLOCATE (subsystems)
    2281          20 :             DEALLOCATE (particles)
    2282             :          END IF
    2283             :       ELSE
    2284           0 :          CPABORT("need force_env!")
    2285             :       END IF
    2286          32 :    END SUBROUTINE u_colvar
    2287             : 
    2288             : ! **************************************************************************************************
    2289             : !> \brief evaluates the force due (and on) the distance from the plane collective variable
    2290             : !> \param colvar ...
    2291             : !> \param cell ...
    2292             : !> \param subsys ...
    2293             : !> \param particles ...
    2294             : !> \author Teodoro Laino 02.2006 [created]
    2295             : ! **************************************************************************************************
    2296        1358 :    SUBROUTINE plane_distance_colvar(colvar, cell, subsys, particles)
    2297             : 
    2298             :       TYPE(colvar_type), POINTER                         :: colvar
    2299             :       TYPE(cell_type), POINTER                           :: cell
    2300             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    2301             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    2302             :          POINTER                                         :: particles
    2303             : 
    2304             :       INTEGER                                            :: i, j, k, l
    2305             :       REAL(dp) :: a, b, dsdxpn(3), dxpndxi(3, 3), dxpndxj(3, 3), dxpndxk(3, 3), fi(3), fj(3), &
    2306             :          fk(3), fl(3), r12, ri(3), rj(3), rk(3), rl(3), ss(3), xpij(3), xpkj(3), xpl(3), xpn(3)
    2307             :       TYPE(particle_list_type), POINTER                  :: particles_i
    2308        1358 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    2309             : 
    2310        1358 :       NULLIFY (particles_i)
    2311             : 
    2312           0 :       CPASSERT(colvar%type_id == plane_distance_colvar_id)
    2313        1358 :       IF (PRESENT(particles)) THEN
    2314           0 :          my_particles => particles
    2315             :       ELSE
    2316        1358 :          CPASSERT(PRESENT(subsys))
    2317        1358 :          CALL cp_subsys_get(subsys, particles=particles_i)
    2318        1358 :          my_particles => particles_i%els
    2319             :       END IF
    2320        1358 :       i = colvar%plane_distance_param%plane(1)
    2321        1358 :       j = colvar%plane_distance_param%plane(2)
    2322        1358 :       k = colvar%plane_distance_param%plane(3)
    2323        1358 :       l = colvar%plane_distance_param%point
    2324             :       ! Get coordinates of atoms or points
    2325        1358 :       CALL get_coordinates(colvar, i, ri, my_particles)
    2326        1358 :       CALL get_coordinates(colvar, j, rj, my_particles)
    2327        1358 :       CALL get_coordinates(colvar, k, rk, my_particles)
    2328        1358 :       CALL get_coordinates(colvar, l, rl, my_particles)
    2329        5432 :       xpij = ri - rj
    2330        5432 :       xpkj = rk - rj
    2331        5432 :       xpl = rl - (ri + rj + rk)/3.0_dp
    2332        1358 :       IF (colvar%plane_distance_param%use_pbc) THEN
    2333             :          ! xpij
    2334       21728 :          ss = MATMUL(cell%h_inv, ri - rj)
    2335        5432 :          ss = ss - NINT(ss)
    2336       17654 :          xpij = MATMUL(cell%hmat, ss)
    2337             :          ! xpkj
    2338       21728 :          ss = MATMUL(cell%h_inv, rk - rj)
    2339        5432 :          ss = ss - NINT(ss)
    2340       17654 :          xpkj = MATMUL(cell%hmat, ss)
    2341             :          ! xpl
    2342       21728 :          ss = MATMUL(cell%h_inv, rl - (ri + rj + rk)/3.0_dp)
    2343        5432 :          ss = ss - NINT(ss)
    2344       17654 :          xpl = MATMUL(cell%hmat, ss)
    2345             :       END IF
    2346             :       ! xpn
    2347        1358 :       xpn(1) = xpij(2)*xpkj(3) - xpij(3)*xpkj(2)
    2348        1358 :       xpn(2) = xpij(3)*xpkj(1) - xpij(1)*xpkj(3)
    2349        1358 :       xpn(3) = xpij(1)*xpkj(2) - xpij(2)*xpkj(1)
    2350        5432 :       a = DOT_PRODUCT(xpn, xpn)
    2351        5432 :       b = DOT_PRODUCT(xpl, xpn)
    2352        1358 :       r12 = SQRT(a)
    2353        1358 :       colvar%ss = b/r12
    2354        1358 :       dsdxpn(1) = xpl(1)/r12 - b*xpn(1)/(r12*a)
    2355        1358 :       dsdxpn(2) = xpl(2)/r12 - b*xpn(2)/(r12*a)
    2356        1358 :       dsdxpn(3) = xpl(3)/r12 - b*xpn(3)/(r12*a)
    2357             :       !
    2358        1358 :       dxpndxi(1, 1) = 0.0_dp
    2359        1358 :       dxpndxi(1, 2) = 1.0_dp*xpkj(3)
    2360        1358 :       dxpndxi(1, 3) = -1.0_dp*xpkj(2)
    2361        1358 :       dxpndxi(2, 1) = -1.0_dp*xpkj(3)
    2362        1358 :       dxpndxi(2, 2) = 0.0_dp
    2363        1358 :       dxpndxi(2, 3) = 1.0_dp*xpkj(1)
    2364        1358 :       dxpndxi(3, 1) = 1.0_dp*xpkj(2)
    2365        1358 :       dxpndxi(3, 2) = -1.0_dp*xpkj(1)
    2366        1358 :       dxpndxi(3, 3) = 0.0_dp
    2367             :       !
    2368        1358 :       dxpndxj(1, 1) = 0.0_dp
    2369        1358 :       dxpndxj(1, 2) = -1.0_dp*xpkj(3) + xpij(3)
    2370        1358 :       dxpndxj(1, 3) = -1.0_dp*xpij(2) + xpkj(2)
    2371        1358 :       dxpndxj(2, 1) = -1.0_dp*xpij(3) + xpkj(3)
    2372        1358 :       dxpndxj(2, 2) = 0.0_dp
    2373        1358 :       dxpndxj(2, 3) = -1.0_dp*xpkj(1) + xpij(1)
    2374        1358 :       dxpndxj(3, 1) = -1.0_dp*xpkj(2) + xpij(2)
    2375        1358 :       dxpndxj(3, 2) = -1.0_dp*xpij(1) + xpkj(1)
    2376        1358 :       dxpndxj(3, 3) = 0.0_dp
    2377             :       !
    2378        1358 :       dxpndxk(1, 1) = 0.0_dp
    2379        1358 :       dxpndxk(1, 2) = -1.0_dp*xpij(3)
    2380        1358 :       dxpndxk(1, 3) = 1.0_dp*xpij(2)
    2381        1358 :       dxpndxk(2, 1) = 1.0_dp*xpij(3)
    2382        1358 :       dxpndxk(2, 2) = 0.0_dp
    2383        1358 :       dxpndxk(2, 3) = -1.0_dp*xpij(1)
    2384        1358 :       dxpndxk(3, 1) = -1.0_dp*xpij(2)
    2385        1358 :       dxpndxk(3, 2) = 1.0_dp*xpij(1)
    2386        1358 :       dxpndxk(3, 3) = 0.0_dp
    2387             :       !
    2388       21728 :       fi(:) = MATMUL(dsdxpn, dxpndxi) - xpn/(3.0_dp*r12)
    2389       21728 :       fj(:) = MATMUL(dsdxpn, dxpndxj) - xpn/(3.0_dp*r12)
    2390       21728 :       fk(:) = MATMUL(dsdxpn, dxpndxk) - xpn/(3.0_dp*r12)
    2391        5432 :       fl(:) = xpn/r12
    2392             :       ! Transfer derivatives on atoms
    2393        1358 :       CALL put_derivative(colvar, 1, fi)
    2394        1358 :       CALL put_derivative(colvar, 2, fj)
    2395        1358 :       CALL put_derivative(colvar, 3, fk)
    2396        1358 :       CALL put_derivative(colvar, 4, fl)
    2397             : 
    2398        1358 :    END SUBROUTINE plane_distance_colvar
    2399             : 
    2400             : ! **************************************************************************************************
    2401             : !> \brief evaluates the force due (and on) the angle between two planes.
    2402             : !>        plane-plane angle collective variable
    2403             : !> \param colvar ...
    2404             : !> \param cell ...
    2405             : !> \param subsys ...
    2406             : !> \param particles ...
    2407             : !> \author Teodoro Laino 02.2009 [created]
    2408             : ! **************************************************************************************************
    2409        1604 :    SUBROUTINE plane_plane_angle_colvar(colvar, cell, subsys, particles)
    2410             : 
    2411             :       TYPE(colvar_type), POINTER                         :: colvar
    2412             :       TYPE(cell_type), POINTER                           :: cell
    2413             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    2414             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    2415             :          POINTER                                         :: particles
    2416             : 
    2417             :       INTEGER                                            :: i1, i2, j1, j2, k1, k2, np
    2418             :       LOGICAL                                            :: check
    2419             :       REAL(dp) :: a1, a2, d, dnorm_dxpn(3), dprod12_dxpn(3), dsdxpn(3), dt_dxpn(3), dxpndxi(3, 3), &
    2420             :          dxpndxj(3, 3), dxpndxk(3, 3), fi(3), fj(3), fk(3), fmod, norm1, norm2, prod_12, ri1(3), &
    2421             :          ri2(3), rj1(3), rj2(3), rk1(3), rk2(3), ss(3), t, xpij1(3), xpij2(3), xpkj1(3), xpkj2(3), &
    2422             :          xpn1(3), xpn2(3)
    2423             :       TYPE(particle_list_type), POINTER                  :: particles_i
    2424        1604 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    2425             : 
    2426        1604 :       NULLIFY (particles_i)
    2427             : 
    2428        1604 :       check = colvar%type_id == plane_plane_angle_colvar_id
    2429           0 :       CPASSERT(check)
    2430        1604 :       IF (PRESENT(particles)) THEN
    2431        1604 :          my_particles => particles
    2432             :       ELSE
    2433           0 :          CPASSERT(PRESENT(subsys))
    2434           0 :          CALL cp_subsys_get(subsys, particles=particles_i)
    2435           0 :          my_particles => particles_i%els
    2436             :       END IF
    2437             : 
    2438             :       ! Plane 1
    2439        1604 :       IF (colvar%plane_plane_angle_param%plane1%type_of_def == plane_def_atoms) THEN
    2440        1604 :          i1 = colvar%plane_plane_angle_param%plane1%points(1)
    2441        1604 :          j1 = colvar%plane_plane_angle_param%plane1%points(2)
    2442        1604 :          k1 = colvar%plane_plane_angle_param%plane1%points(3)
    2443             : 
    2444             :          ! Get coordinates of atoms or points
    2445        1604 :          CALL get_coordinates(colvar, i1, ri1, my_particles)
    2446        1604 :          CALL get_coordinates(colvar, j1, rj1, my_particles)
    2447        1604 :          CALL get_coordinates(colvar, k1, rk1, my_particles)
    2448             : 
    2449             :          ! xpij
    2450       25664 :          ss = MATMUL(cell%h_inv, ri1 - rj1)
    2451        6416 :          ss = ss - NINT(ss)
    2452       20852 :          xpij1 = MATMUL(cell%hmat, ss)
    2453             : 
    2454             :          ! xpkj
    2455       25664 :          ss = MATMUL(cell%h_inv, rk1 - rj1)
    2456        6416 :          ss = ss - NINT(ss)
    2457       20852 :          xpkj1 = MATMUL(cell%hmat, ss)
    2458             : 
    2459             :          ! xpn
    2460        1604 :          xpn1(1) = xpij1(2)*xpkj1(3) - xpij1(3)*xpkj1(2)
    2461        1604 :          xpn1(2) = xpij1(3)*xpkj1(1) - xpij1(1)*xpkj1(3)
    2462        1604 :          xpn1(3) = xpij1(1)*xpkj1(2) - xpij1(2)*xpkj1(1)
    2463             :       ELSE
    2464           0 :          xpn1 = colvar%plane_plane_angle_param%plane1%normal_vec
    2465             :       END IF
    2466        6416 :       a1 = DOT_PRODUCT(xpn1, xpn1)
    2467        1604 :       norm1 = SQRT(a1)
    2468        1604 :       CPASSERT(norm1 /= 0.0_dp)
    2469             : 
    2470             :       ! Plane 2
    2471        1604 :       IF (colvar%plane_plane_angle_param%plane2%type_of_def == plane_def_atoms) THEN
    2472         802 :          i2 = colvar%plane_plane_angle_param%plane2%points(1)
    2473         802 :          j2 = colvar%plane_plane_angle_param%plane2%points(2)
    2474         802 :          k2 = colvar%plane_plane_angle_param%plane2%points(3)
    2475             : 
    2476             :          ! Get coordinates of atoms or points
    2477         802 :          CALL get_coordinates(colvar, i2, ri2, my_particles)
    2478         802 :          CALL get_coordinates(colvar, j2, rj2, my_particles)
    2479         802 :          CALL get_coordinates(colvar, k2, rk2, my_particles)
    2480             : 
    2481             :          ! xpij
    2482       12832 :          ss = MATMUL(cell%h_inv, ri2 - rj2)
    2483        3208 :          ss = ss - NINT(ss)
    2484       10426 :          xpij2 = MATMUL(cell%hmat, ss)
    2485             : 
    2486             :          ! xpkj
    2487       12832 :          ss = MATMUL(cell%h_inv, rk2 - rj2)
    2488        3208 :          ss = ss - NINT(ss)
    2489       10426 :          xpkj2 = MATMUL(cell%hmat, ss)
    2490             : 
    2491             :          ! xpn
    2492         802 :          xpn2(1) = xpij2(2)*xpkj2(3) - xpij2(3)*xpkj2(2)
    2493         802 :          xpn2(2) = xpij2(3)*xpkj2(1) - xpij2(1)*xpkj2(3)
    2494         802 :          xpn2(3) = xpij2(1)*xpkj2(2) - xpij2(2)*xpkj2(1)
    2495             :       ELSE
    2496        3208 :          xpn2 = colvar%plane_plane_angle_param%plane2%normal_vec
    2497             :       END IF
    2498        6416 :       a2 = DOT_PRODUCT(xpn2, xpn2)
    2499        1604 :       norm2 = SQRT(a2)
    2500        1604 :       CPASSERT(norm2 /= 0.0_dp)
    2501             : 
    2502             :       ! The value of the angle is defined only between 0 and Pi
    2503        6416 :       prod_12 = DOT_PRODUCT(xpn1, xpn2)
    2504             : 
    2505        1604 :       d = norm1*norm2
    2506        1604 :       t = prod_12/d
    2507        1604 :       t = MIN(1.0_dp, ABS(t))*SIGN(1.0_dp, t)
    2508        1604 :       colvar%ss = ACOS(t)
    2509             : 
    2510        1604 :       IF ((ABS(colvar%ss) .LT. tolerance_acos) .OR. (ABS(colvar%ss - pi) .LT. tolerance_acos)) THEN
    2511             :          fmod = 0.0_dp
    2512             :       ELSE
    2513        1600 :          fmod = -1.0_dp/SIN(colvar%ss)
    2514             :       END IF
    2515             :       ! Compute derivatives
    2516        1604 :       np = 0
    2517             :       ! Plane 1
    2518        1604 :       IF (colvar%plane_plane_angle_param%plane1%type_of_def == plane_def_atoms) THEN
    2519        1604 :          dprod12_dxpn = xpn2
    2520        6416 :          dnorm_dxpn = 1.0_dp/norm1*xpn1
    2521        6416 :          dt_dxpn = (dprod12_dxpn*d - prod_12*dnorm_dxpn*norm2)/d**2
    2522             : 
    2523        1604 :          dsdxpn(1) = fmod*dt_dxpn(1)
    2524        1604 :          dsdxpn(2) = fmod*dt_dxpn(2)
    2525        1604 :          dsdxpn(3) = fmod*dt_dxpn(3)
    2526             :          !
    2527        1604 :          dxpndxi(1, 1) = 0.0_dp
    2528        1604 :          dxpndxi(1, 2) = 1.0_dp*xpkj1(3)
    2529        1604 :          dxpndxi(1, 3) = -1.0_dp*xpkj1(2)
    2530        1604 :          dxpndxi(2, 1) = -1.0_dp*xpkj1(3)
    2531        1604 :          dxpndxi(2, 2) = 0.0_dp
    2532        1604 :          dxpndxi(2, 3) = 1.0_dp*xpkj1(1)
    2533        1604 :          dxpndxi(3, 1) = 1.0_dp*xpkj1(2)
    2534        1604 :          dxpndxi(3, 2) = -1.0_dp*xpkj1(1)
    2535        1604 :          dxpndxi(3, 3) = 0.0_dp
    2536             :          !
    2537        1604 :          dxpndxj(1, 1) = 0.0_dp
    2538        1604 :          dxpndxj(1, 2) = -1.0_dp*xpkj1(3) + xpij1(3)
    2539        1604 :          dxpndxj(1, 3) = -1.0_dp*xpij1(2) + xpkj1(2)
    2540        1604 :          dxpndxj(2, 1) = -1.0_dp*xpij1(3) + xpkj1(3)
    2541        1604 :          dxpndxj(2, 2) = 0.0_dp
    2542        1604 :          dxpndxj(2, 3) = -1.0_dp*xpkj1(1) + xpij1(1)
    2543        1604 :          dxpndxj(3, 1) = -1.0_dp*xpkj1(2) + xpij1(2)
    2544        1604 :          dxpndxj(3, 2) = -1.0_dp*xpij1(1) + xpkj1(1)
    2545        1604 :          dxpndxj(3, 3) = 0.0_dp
    2546             :          !
    2547        1604 :          dxpndxk(1, 1) = 0.0_dp
    2548        1604 :          dxpndxk(1, 2) = -1.0_dp*xpij1(3)
    2549        1604 :          dxpndxk(1, 3) = 1.0_dp*xpij1(2)
    2550        1604 :          dxpndxk(2, 1) = 1.0_dp*xpij1(3)
    2551        1604 :          dxpndxk(2, 2) = 0.0_dp
    2552        1604 :          dxpndxk(2, 3) = -1.0_dp*xpij1(1)
    2553        1604 :          dxpndxk(3, 1) = -1.0_dp*xpij1(2)
    2554        1604 :          dxpndxk(3, 2) = 1.0_dp*xpij1(1)
    2555        1604 :          dxpndxk(3, 3) = 0.0_dp
    2556             :          !
    2557       20852 :          fi = MATMUL(dsdxpn, dxpndxi)
    2558       20852 :          fj = MATMUL(dsdxpn, dxpndxj)
    2559       20852 :          fk = MATMUL(dsdxpn, dxpndxk)
    2560             : 
    2561             :          ! Transfer derivatives on atoms
    2562        1604 :          CALL put_derivative(colvar, np + 1, fi)
    2563        1604 :          CALL put_derivative(colvar, np + 2, fj)
    2564        1604 :          CALL put_derivative(colvar, np + 3, fk)
    2565        1604 :          np = 3
    2566             :       END IF
    2567             : 
    2568             :       ! Plane 2
    2569        1604 :       IF (colvar%plane_plane_angle_param%plane2%type_of_def == plane_def_atoms) THEN
    2570         802 :          dprod12_dxpn = xpn1
    2571        3208 :          dnorm_dxpn = 1.0_dp/norm2*xpn2
    2572        3208 :          dt_dxpn = (dprod12_dxpn*d - prod_12*dnorm_dxpn*norm1)/d**2
    2573             : 
    2574         802 :          dsdxpn(1) = fmod*dt_dxpn(1)
    2575         802 :          dsdxpn(2) = fmod*dt_dxpn(2)
    2576         802 :          dsdxpn(3) = fmod*dt_dxpn(3)
    2577             :          !
    2578         802 :          dxpndxi(1, 1) = 0.0_dp
    2579         802 :          dxpndxi(1, 2) = 1.0_dp*xpkj1(3)
    2580         802 :          dxpndxi(1, 3) = -1.0_dp*xpkj1(2)
    2581         802 :          dxpndxi(2, 1) = -1.0_dp*xpkj1(3)
    2582         802 :          dxpndxi(2, 2) = 0.0_dp
    2583         802 :          dxpndxi(2, 3) = 1.0_dp*xpkj1(1)
    2584         802 :          dxpndxi(3, 1) = 1.0_dp*xpkj1(2)
    2585         802 :          dxpndxi(3, 2) = -1.0_dp*xpkj1(1)
    2586         802 :          dxpndxi(3, 3) = 0.0_dp
    2587             :          !
    2588         802 :          dxpndxj(1, 1) = 0.0_dp
    2589         802 :          dxpndxj(1, 2) = -1.0_dp*xpkj1(3) + xpij1(3)
    2590         802 :          dxpndxj(1, 3) = -1.0_dp*xpij1(2) + xpkj1(2)
    2591         802 :          dxpndxj(2, 1) = -1.0_dp*xpij1(3) + xpkj1(3)
    2592         802 :          dxpndxj(2, 2) = 0.0_dp
    2593         802 :          dxpndxj(2, 3) = -1.0_dp*xpkj1(1) + xpij1(1)
    2594         802 :          dxpndxj(3, 1) = -1.0_dp*xpkj1(2) + xpij1(2)
    2595         802 :          dxpndxj(3, 2) = -1.0_dp*xpij1(1) + xpkj1(1)
    2596         802 :          dxpndxj(3, 3) = 0.0_dp
    2597             :          !
    2598         802 :          dxpndxk(1, 1) = 0.0_dp
    2599         802 :          dxpndxk(1, 2) = -1.0_dp*xpij1(3)
    2600         802 :          dxpndxk(1, 3) = 1.0_dp*xpij1(2)
    2601         802 :          dxpndxk(2, 1) = 1.0_dp*xpij1(3)
    2602         802 :          dxpndxk(2, 2) = 0.0_dp
    2603         802 :          dxpndxk(2, 3) = -1.0_dp*xpij1(1)
    2604         802 :          dxpndxk(3, 1) = -1.0_dp*xpij1(2)
    2605         802 :          dxpndxk(3, 2) = 1.0_dp*xpij1(1)
    2606         802 :          dxpndxk(3, 3) = 0.0_dp
    2607             :          !
    2608       10426 :          fi = MATMUL(dsdxpn, dxpndxi)
    2609       10426 :          fj = MATMUL(dsdxpn, dxpndxj)
    2610       10426 :          fk = MATMUL(dsdxpn, dxpndxk)
    2611             : 
    2612             :          ! Transfer derivatives on atoms
    2613         802 :          CALL put_derivative(colvar, np + 1, fi)
    2614         802 :          CALL put_derivative(colvar, np + 2, fj)
    2615         802 :          CALL put_derivative(colvar, np + 3, fk)
    2616             :       END IF
    2617             : 
    2618        1604 :    END SUBROUTINE plane_plane_angle_colvar
    2619             : 
    2620             : ! **************************************************************************************************
    2621             : !> \brief Evaluates the value of the rotation angle between two bonds
    2622             : !> \param colvar ...
    2623             : !> \param cell ...
    2624             : !> \param subsys ...
    2625             : !> \param particles ...
    2626             : !> \author Teodoro Laino 02.2006 [created]
    2627             : ! **************************************************************************************************
    2628           8 :    SUBROUTINE rotation_colvar(colvar, cell, subsys, particles)
    2629             :       TYPE(colvar_type), POINTER                         :: colvar
    2630             :       TYPE(cell_type), POINTER                           :: cell
    2631             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    2632             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    2633             :          POINTER                                         :: particles
    2634             : 
    2635             :       INTEGER                                            :: i, idum
    2636             :       REAL(dp)                                           :: a, b, fmod, t0, t1, t2, t3, xdum(3), &
    2637             :                                                             xij(3), xkj(3)
    2638             :       REAL(KIND=dp)                                      :: dp1b1(3), dp1b2(3), dp2b1(3), dp2b2(3), &
    2639             :                                                             ss(3), xp1b1(3), xp1b2(3), xp2b1(3), &
    2640             :                                                             xp2b2(3)
    2641             :       TYPE(particle_list_type), POINTER                  :: particles_i
    2642           8 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    2643             : 
    2644           8 :       NULLIFY (particles_i)
    2645             : 
    2646           0 :       CPASSERT(colvar%type_id == rotation_colvar_id)
    2647           8 :       IF (PRESENT(particles)) THEN
    2648           0 :          my_particles => particles
    2649             :       ELSE
    2650           8 :          CPASSERT(PRESENT(subsys))
    2651           8 :          CALL cp_subsys_get(subsys, particles=particles_i)
    2652           8 :          my_particles => particles_i%els
    2653             :       END IF
    2654           8 :       i = colvar%rotation_param%i_at1_bond1
    2655           8 :       CALL get_coordinates(colvar, i, xp1b1, my_particles)
    2656           8 :       i = colvar%rotation_param%i_at2_bond1
    2657           8 :       CALL get_coordinates(colvar, i, xp2b1, my_particles)
    2658           8 :       i = colvar%rotation_param%i_at1_bond2
    2659           8 :       CALL get_coordinates(colvar, i, xp1b2, my_particles)
    2660           8 :       i = colvar%rotation_param%i_at2_bond2
    2661           8 :       CALL get_coordinates(colvar, i, xp2b2, my_particles)
    2662             :       ! xij
    2663         128 :       ss = MATMUL(cell%h_inv, xp1b1 - xp2b1)
    2664          32 :       ss = ss - NINT(ss)
    2665         104 :       xij = MATMUL(cell%hmat, ss)
    2666             :       ! xkj
    2667         128 :       ss = MATMUL(cell%h_inv, xp1b2 - xp2b2)
    2668          32 :       ss = ss - NINT(ss)
    2669         104 :       xkj = MATMUL(cell%hmat, ss)
    2670             :       ! evaluation of the angle..
    2671          32 :       a = SQRT(DOT_PRODUCT(xij, xij))
    2672          32 :       b = SQRT(DOT_PRODUCT(xkj, xkj))
    2673           8 :       t0 = 1.0_dp/(a*b)
    2674           8 :       t1 = 1.0_dp/(a**3.0_dp*b)
    2675           8 :       t2 = 1.0_dp/(a*b**3.0_dp)
    2676          32 :       t3 = DOT_PRODUCT(xij, xkj)
    2677           8 :       colvar%ss = ACOS(t3*t0)
    2678           8 :       IF ((ABS(colvar%ss) .LT. tolerance_acos) .OR. (ABS(colvar%ss - pi) .LT. tolerance_acos)) THEN
    2679             :          fmod = 0.0_dp
    2680             :       ELSE
    2681           8 :          fmod = -1.0_dp/SIN(colvar%ss)
    2682             :       END IF
    2683          32 :       dp1b1 = xkj(:)*t0 - xij(:)*t1*t3
    2684          32 :       dp2b1 = -xkj(:)*t0 + xij(:)*t1*t3
    2685          32 :       dp1b2 = xij(:)*t0 - xkj(:)*t2*t3
    2686          32 :       dp2b2 = -xij(:)*t0 + xkj(:)*t2*t3
    2687             : 
    2688          32 :       xdum = dp1b1*fmod
    2689           8 :       idum = colvar%rotation_param%i_at1_bond1
    2690           8 :       CALL put_derivative(colvar, idum, xdum)
    2691          32 :       xdum = dp2b1*fmod
    2692           8 :       idum = colvar%rotation_param%i_at2_bond1
    2693           8 :       CALL put_derivative(colvar, idum, xdum)
    2694          32 :       xdum = dp1b2*fmod
    2695           8 :       idum = colvar%rotation_param%i_at1_bond2
    2696           8 :       CALL put_derivative(colvar, idum, xdum)
    2697          32 :       xdum = dp2b2*fmod
    2698           8 :       idum = colvar%rotation_param%i_at2_bond2
    2699           8 :       CALL put_derivative(colvar, idum, xdum)
    2700             : 
    2701           8 :    END SUBROUTINE rotation_colvar
    2702             : 
    2703             : ! **************************************************************************************************
    2704             : !> \brief evaluates the force due to the function of two distances
    2705             : !> \param colvar ...
    2706             : !> \param cell ...
    2707             : !> \param subsys ...
    2708             : !> \param particles ...
    2709             : !> \author Teodoro Laino 02.2006 [created]
    2710             : !> \note modified Florian Schiffmann 08.2008
    2711             : ! **************************************************************************************************
    2712         632 :    SUBROUTINE dfunct_colvar(colvar, cell, subsys, particles)
    2713             :       TYPE(colvar_type), POINTER                         :: colvar
    2714             :       TYPE(cell_type), POINTER                           :: cell
    2715             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    2716             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    2717             :          POINTER                                         :: particles
    2718             : 
    2719             :       INTEGER                                            :: i, j, k, l
    2720             :       REAL(dp)                                           :: fi(3), fj(3), fk(3), fl(3), r12, r34, &
    2721             :                                                             ss(3), xij(3), xkl(3), xpi(3), xpj(3), &
    2722             :                                                             xpk(3), xpl(3)
    2723             :       TYPE(particle_list_type), POINTER                  :: particles_i
    2724         632 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    2725             : 
    2726         632 :       NULLIFY (particles_i)
    2727             : 
    2728           0 :       CPASSERT(colvar%type_id == dfunct_colvar_id)
    2729         632 :       IF (PRESENT(particles)) THEN
    2730         632 :          my_particles => particles
    2731             :       ELSE
    2732           0 :          CPASSERT(PRESENT(subsys))
    2733           0 :          CALL cp_subsys_get(subsys, particles=particles_i)
    2734           0 :          my_particles => particles_i%els
    2735             :       END IF
    2736         632 :       i = colvar%dfunct_param%i_at_dfunct(1)
    2737         632 :       j = colvar%dfunct_param%i_at_dfunct(2)
    2738             :       ! First bond
    2739         632 :       CALL get_coordinates(colvar, i, xpi, my_particles)
    2740         632 :       CALL get_coordinates(colvar, j, xpj, my_particles)
    2741         632 :       IF (colvar%dfunct_param%use_pbc) THEN
    2742       10112 :          ss = MATMUL(cell%h_inv, xpi - xpj)
    2743        2528 :          ss = ss - NINT(ss)
    2744        8216 :          xij = MATMUL(cell%hmat, ss)
    2745             :       ELSE
    2746           0 :          xij = xpi - xpj
    2747             :       END IF
    2748         632 :       r12 = SQRT(xij(1)**2 + xij(2)**2 + xij(3)**2)
    2749             :       ! Second bond
    2750         632 :       k = colvar%dfunct_param%i_at_dfunct(3)
    2751         632 :       l = colvar%dfunct_param%i_at_dfunct(4)
    2752         632 :       CALL get_coordinates(colvar, k, xpk, my_particles)
    2753         632 :       CALL get_coordinates(colvar, l, xpl, my_particles)
    2754         632 :       IF (colvar%dfunct_param%use_pbc) THEN
    2755       10112 :          ss = MATMUL(cell%h_inv, xpk - xpl)
    2756        2528 :          ss = ss - NINT(ss)
    2757        8216 :          xkl = MATMUL(cell%hmat, ss)
    2758             :       ELSE
    2759           0 :          xkl = xpk - xpl
    2760             :       END IF
    2761         632 :       r34 = SQRT(xkl(1)**2 + xkl(2)**2 + xkl(3)**2)
    2762             :       !
    2763         632 :       colvar%ss = r12 + colvar%dfunct_param%coeff*r34
    2764        2528 :       fi(:) = xij/r12
    2765        2528 :       fj(:) = -xij/r12
    2766        2528 :       fk(:) = colvar%dfunct_param%coeff*xkl/r34
    2767        2528 :       fl(:) = -colvar%dfunct_param%coeff*xkl/r34
    2768         632 :       CALL put_derivative(colvar, 1, fi)
    2769         632 :       CALL put_derivative(colvar, 2, fj)
    2770         632 :       CALL put_derivative(colvar, 3, fk)
    2771         632 :       CALL put_derivative(colvar, 4, fl)
    2772             : 
    2773         632 :    END SUBROUTINE dfunct_colvar
    2774             : 
    2775             : ! **************************************************************************************************
    2776             : !> \brief evaluates the force due (and on) the distance from the plane collective variable
    2777             : !> \param colvar ...
    2778             : !> \param cell ...
    2779             : !> \param subsys ...
    2780             : !> \param particles ...
    2781             : !> \author Teodoro Laino 02.2006 [created]
    2782             : ! **************************************************************************************************
    2783        5495 :    SUBROUTINE angle_colvar(colvar, cell, subsys, particles)
    2784             :       TYPE(colvar_type), POINTER                         :: colvar
    2785             :       TYPE(cell_type), POINTER                           :: cell
    2786             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    2787             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    2788             :          POINTER                                         :: particles
    2789             : 
    2790             :       INTEGER                                            :: i, j, k
    2791             :       REAL(dp)                                           :: a, b, fi(3), fj(3), fk(3), fmod, ri(3), &
    2792             :                                                             rj(3), rk(3), ss(3), t0, t1, t2, t3, &
    2793             :                                                             xij(3), xkj(3)
    2794             :       TYPE(particle_list_type), POINTER                  :: particles_i
    2795        5495 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    2796             : 
    2797        5495 :       NULLIFY (particles_i)
    2798             : 
    2799           0 :       CPASSERT(colvar%type_id == angle_colvar_id)
    2800        5495 :       IF (PRESENT(particles)) THEN
    2801        5393 :          my_particles => particles
    2802             :       ELSE
    2803         102 :          CPASSERT(PRESENT(subsys))
    2804         102 :          CALL cp_subsys_get(subsys, particles=particles_i)
    2805         102 :          my_particles => particles_i%els
    2806             :       END IF
    2807        5495 :       i = colvar%angle_param%i_at_angle(1)
    2808        5495 :       j = colvar%angle_param%i_at_angle(2)
    2809        5495 :       k = colvar%angle_param%i_at_angle(3)
    2810        5495 :       CALL get_coordinates(colvar, i, ri, my_particles)
    2811        5495 :       CALL get_coordinates(colvar, j, rj, my_particles)
    2812        5495 :       CALL get_coordinates(colvar, k, rk, my_particles)
    2813             :       ! xij
    2814       87920 :       ss = MATMUL(cell%h_inv, ri - rj)
    2815       21980 :       ss = ss - NINT(ss)
    2816       71435 :       xij = MATMUL(cell%hmat, ss)
    2817             :       ! xkj
    2818       87920 :       ss = MATMUL(cell%h_inv, rk - rj)
    2819       21980 :       ss = ss - NINT(ss)
    2820       71435 :       xkj = MATMUL(cell%hmat, ss)
    2821             :       ! Evaluation of the angle..
    2822       21980 :       a = SQRT(DOT_PRODUCT(xij, xij))
    2823       21980 :       b = SQRT(DOT_PRODUCT(xkj, xkj))
    2824        5495 :       t0 = 1.0_dp/(a*b)
    2825        5495 :       t1 = 1.0_dp/(a**3.0_dp*b)
    2826        5495 :       t2 = 1.0_dp/(a*b**3.0_dp)
    2827       21980 :       t3 = DOT_PRODUCT(xij, xkj)
    2828        5495 :       colvar%ss = ACOS(t3*t0)
    2829        5495 :       IF ((ABS(colvar%ss) .LT. tolerance_acos) .OR. (ABS(colvar%ss - pi) .LT. tolerance_acos)) THEN
    2830             :          fmod = 0.0_dp
    2831             :       ELSE
    2832        5495 :          fmod = -1.0_dp/SIN(colvar%ss)
    2833             :       END IF
    2834       21980 :       fi(:) = xkj(:)*t0 - xij(:)*t1*t3
    2835       21980 :       fj(:) = -xkj(:)*t0 + xij(:)*t1*t3 - xij(:)*t0 + xkj(:)*t2*t3
    2836       21980 :       fk(:) = xij(:)*t0 - xkj(:)*t2*t3
    2837       21980 :       fi = fi*fmod
    2838       21980 :       fj = fj*fmod
    2839       21980 :       fk = fk*fmod
    2840        5495 :       CALL put_derivative(colvar, 1, fi)
    2841        5495 :       CALL put_derivative(colvar, 2, fj)
    2842        5495 :       CALL put_derivative(colvar, 3, fk)
    2843             : 
    2844        5495 :    END SUBROUTINE angle_colvar
    2845             : 
    2846             : ! **************************************************************************************************
    2847             : !> \brief evaluates the force due (and on) the distance collective variable
    2848             : !> \param colvar ...
    2849             : !> \param cell ...
    2850             : !> \param subsys ...
    2851             : !> \param particles ...
    2852             : !> \author Alessandro Laio, Fawzi Mohamed
    2853             : ! **************************************************************************************************
    2854      390519 :    SUBROUTINE dist_colvar(colvar, cell, subsys, particles)
    2855             :       TYPE(colvar_type), POINTER                         :: colvar
    2856             :       TYPE(cell_type), POINTER                           :: cell
    2857             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    2858             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    2859             :          POINTER                                         :: particles
    2860             : 
    2861             :       INTEGER                                            :: i, j
    2862             :       REAL(dp)                                           :: fi(3), fj(3), r12, ss(3), xij(3), &
    2863             :                                                             xpi(3), xpj(3)
    2864             :       TYPE(particle_list_type), POINTER                  :: particles_i
    2865      390519 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    2866             : 
    2867      390519 :       NULLIFY (particles_i)
    2868             : 
    2869           0 :       CPASSERT(colvar%type_id == dist_colvar_id)
    2870      390519 :       IF (PRESENT(particles)) THEN
    2871      378941 :          my_particles => particles
    2872             :       ELSE
    2873       11578 :          CPASSERT(PRESENT(subsys))
    2874       11578 :          CALL cp_subsys_get(subsys, particles=particles_i)
    2875       11578 :          my_particles => particles_i%els
    2876             :       END IF
    2877      390519 :       i = colvar%dist_param%i_at
    2878      390519 :       j = colvar%dist_param%j_at
    2879      390519 :       CALL get_coordinates(colvar, i, xpi, my_particles)
    2880      390519 :       CALL get_coordinates(colvar, j, xpj, my_particles)
    2881     6248304 :       ss = MATMUL(cell%h_inv, xpi - xpj)
    2882     1562076 :       ss = ss - NINT(ss)
    2883     5076747 :       xij = MATMUL(cell%hmat, ss)
    2884      390589 :       SELECT CASE (colvar%dist_param%axis_id)
    2885             :       CASE (do_clv_x)
    2886          70 :          xij(2) = 0.0_dp
    2887          70 :          xij(3) = 0.0_dp
    2888             :       CASE (do_clv_y)
    2889           0 :          xij(1) = 0.0_dp
    2890           0 :          xij(3) = 0.0_dp
    2891             :       CASE (do_clv_z)
    2892           0 :          xij(1) = 0.0_dp
    2893           0 :          xij(2) = 0.0_dp
    2894             :       CASE (do_clv_xy)
    2895           0 :          xij(3) = 0.0_dp
    2896             :       CASE (do_clv_xz)
    2897           0 :          xij(2) = 0.0_dp
    2898             :       CASE (do_clv_yz)
    2899      390519 :          xij(1) = 0.0_dp
    2900             :       CASE DEFAULT
    2901             :          !do_clv_xyz
    2902             :       END SELECT
    2903      390519 :       r12 = SQRT(xij(1)**2 + xij(2)**2 + xij(3)**2)
    2904             : 
    2905      390519 :       IF (colvar%dist_param%sign_d) THEN
    2906           0 :          SELECT CASE (colvar%dist_param%axis_id)
    2907             :          CASE (do_clv_x)
    2908           0 :             colvar%ss = xij(1)
    2909             :          CASE (do_clv_y)
    2910           0 :             colvar%ss = xij(2)
    2911             :          CASE (do_clv_z)
    2912           0 :             colvar%ss = xij(3)
    2913             :          CASE DEFAULT
    2914             :             !do_clv_xyz
    2915             :          END SELECT
    2916             : 
    2917             :       ELSE
    2918      390519 :          colvar%ss = r12
    2919             :       END IF
    2920             : 
    2921     1562076 :       fi(:) = xij/r12
    2922     1562076 :       fj(:) = -xij/r12
    2923             : 
    2924      390519 :       CALL put_derivative(colvar, 1, fi)
    2925      390519 :       CALL put_derivative(colvar, 2, fj)
    2926             : 
    2927      390519 :    END SUBROUTINE dist_colvar
    2928             : 
    2929             : ! **************************************************************************************************
    2930             : !> \brief evaluates the force due to the torsion collective variable
    2931             : !> \param colvar ...
    2932             : !> \param cell ...
    2933             : !> \param subsys ...
    2934             : !> \param particles ...
    2935             : !> \param no_riemann_sheet_op ...
    2936             : !> \author Alessandro Laio, Fawzi Mohamed
    2937             : ! **************************************************************************************************
    2938        2076 :    SUBROUTINE torsion_colvar(colvar, cell, subsys, particles, no_riemann_sheet_op)
    2939             : 
    2940             :       TYPE(colvar_type), POINTER                         :: colvar
    2941             :       TYPE(cell_type), POINTER                           :: cell
    2942             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    2943             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    2944             :          POINTER                                         :: particles
    2945             :       LOGICAL, INTENT(IN), OPTIONAL                      :: no_riemann_sheet_op
    2946             : 
    2947             :       INTEGER                                            :: i, ii
    2948             :       LOGICAL                                            :: no_riemann_sheet
    2949             :       REAL(dp) :: angle, cosine, dedphi, dedxia, dedxib, dedxic, dedxid, dedxt, dedxu, dedyia, &
    2950             :          dedyib, dedyic, dedyid, dedyt, dedyu, dedzia, dedzib, dedzic, dedzid, dedzt, dedzu, dt, &
    2951             :          e, ftmp(3), o0, rcb, rt2, rtmp(3), rtru, ru2, sine, ss(3), xba, xca, xcb, xdb, xdc, xt, &
    2952             :          xtu, xu, yba, yca, ycb, ydb, ydc, yt, ytu, yu, zba, zca, zcb, zdb, zdc, zt, ztu, zu
    2953             :       REAL(dp), DIMENSION(3, 4)                          :: rr
    2954             :       TYPE(particle_list_type), POINTER                  :: particles_i
    2955        2076 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    2956             : 
    2957        2076 :       NULLIFY (particles_i)
    2958           0 :       CPASSERT(colvar%type_id == torsion_colvar_id)
    2959        2076 :       IF (PRESENT(particles)) THEN
    2960        2076 :          my_particles => particles
    2961             :       ELSE
    2962           0 :          CPASSERT(PRESENT(subsys))
    2963           0 :          CALL cp_subsys_get(subsys, particles=particles_i)
    2964           0 :          my_particles => particles_i%els
    2965             :       END IF
    2966        2076 :       no_riemann_sheet = .FALSE.
    2967        2076 :       IF (PRESENT(no_riemann_sheet_op)) no_riemann_sheet = no_riemann_sheet_op
    2968       10380 :       DO ii = 1, 4
    2969        8304 :          i = colvar%torsion_param%i_at_tors(ii)
    2970        8304 :          CALL get_coordinates(colvar, i, rtmp, my_particles)
    2971       35292 :          rr(:, ii) = rtmp(1:3)
    2972             :       END DO
    2973        2076 :       o0 = colvar%torsion_param%o0
    2974             :       ! ba
    2975       33216 :       ss = MATMUL(cell%h_inv, rr(:, 2) - rr(:, 1))
    2976        8304 :       ss = ss - NINT(ss)
    2977       26988 :       ss = MATMUL(cell%hmat, ss)
    2978        2076 :       xba = ss(1)
    2979        2076 :       yba = ss(2)
    2980        2076 :       zba = ss(3)
    2981             :       ! cb
    2982       33216 :       ss = MATMUL(cell%h_inv, rr(:, 3) - rr(:, 2))
    2983        8304 :       ss = ss - NINT(ss)
    2984       26988 :       ss = MATMUL(cell%hmat, ss)
    2985        2076 :       xcb = ss(1)
    2986        2076 :       ycb = ss(2)
    2987        2076 :       zcb = ss(3)
    2988             :       ! dc
    2989       33216 :       ss = MATMUL(cell%h_inv, rr(:, 4) - rr(:, 3))
    2990        8304 :       ss = ss - NINT(ss)
    2991       26988 :       ss = MATMUL(cell%hmat, ss)
    2992        2076 :       xdc = ss(1)
    2993        2076 :       ydc = ss(2)
    2994        2076 :       zdc = ss(3)
    2995             :       !
    2996        2076 :       xt = yba*zcb - ycb*zba
    2997        2076 :       yt = zba*xcb - zcb*xba
    2998        2076 :       zt = xba*ycb - xcb*yba
    2999        2076 :       xu = ycb*zdc - ydc*zcb
    3000        2076 :       yu = zcb*xdc - zdc*xcb
    3001        2076 :       zu = xcb*ydc - xdc*ycb
    3002        2076 :       xtu = yt*zu - yu*zt
    3003        2076 :       ytu = zt*xu - zu*xt
    3004        2076 :       ztu = xt*yu - xu*yt
    3005        2076 :       rt2 = xt*xt + yt*yt + zt*zt
    3006        2076 :       ru2 = xu*xu + yu*yu + zu*zu
    3007        2076 :       rtru = SQRT(rt2*ru2)
    3008        2076 :       IF (rtru .NE. 0.0_dp) THEN
    3009        2076 :          rcb = SQRT(xcb*xcb + ycb*ycb + zcb*zcb)
    3010        2076 :          cosine = (xt*xu + yt*yu + zt*zu)/rtru
    3011        2076 :          sine = (xcb*xtu + ycb*ytu + zcb*ztu)/(rcb*rtru)
    3012        2076 :          cosine = MIN(1.0_dp, MAX(-1.0_dp, cosine))
    3013        2076 :          angle = ACOS(cosine)
    3014        2076 :          IF (sine .LT. 0.0_dp) angle = -angle
    3015             :          !
    3016        2076 :          dt = angle ! [rad]
    3017        2076 :          dt = MOD(2.0E4_dp*pi + dt - o0, 2.0_dp*pi)
    3018        2076 :          IF (dt .GT. pi) dt = dt - 2.0_dp*pi
    3019        2076 :          dt = o0 + dt
    3020        2076 :          colvar%torsion_param%o0 = dt
    3021             :          !
    3022             :          !     calculate improper energy and master chain rule term
    3023             :          !
    3024        2076 :          e = dt
    3025        2076 :          dedphi = 1.0_dp
    3026             :          !
    3027             :          !     chain rule terms for first derivative components
    3028             :          !
    3029             :          ! ca
    3030       33216 :          ss = MATMUL(cell%h_inv, rr(:, 3) - rr(:, 1))
    3031        8304 :          ss = ss - NINT(ss)
    3032       26988 :          ss = MATMUL(cell%hmat, ss)
    3033        2076 :          xca = ss(1)
    3034        2076 :          yca = ss(2)
    3035        2076 :          zca = ss(3)
    3036             :          ! db
    3037       33216 :          ss = MATMUL(cell%h_inv, rr(:, 4) - rr(:, 2))
    3038        8304 :          ss = ss - NINT(ss)
    3039       26988 :          ss = MATMUL(cell%hmat, ss)
    3040        2076 :          xdb = ss(1)
    3041        2076 :          ydb = ss(2)
    3042        2076 :          zdb = ss(3)
    3043             :          !
    3044        2076 :          dedxt = dedphi*(yt*zcb - ycb*zt)/(rt2*rcb)
    3045        2076 :          dedyt = dedphi*(zt*xcb - zcb*xt)/(rt2*rcb)
    3046        2076 :          dedzt = dedphi*(xt*ycb - xcb*yt)/(rt2*rcb)
    3047        2076 :          dedxu = -dedphi*(yu*zcb - ycb*zu)/(ru2*rcb)
    3048        2076 :          dedyu = -dedphi*(zu*xcb - zcb*xu)/(ru2*rcb)
    3049        2076 :          dedzu = -dedphi*(xu*ycb - xcb*yu)/(ru2*rcb)
    3050             :          !
    3051             :          !     compute first derivative components for this angle
    3052             :          !
    3053        2076 :          dedxia = zcb*dedyt - ycb*dedzt
    3054        2076 :          dedyia = xcb*dedzt - zcb*dedxt
    3055        2076 :          dedzia = ycb*dedxt - xcb*dedyt
    3056        2076 :          dedxib = yca*dedzt - zca*dedyt + zdc*dedyu - ydc*dedzu
    3057        2076 :          dedyib = zca*dedxt - xca*dedzt + xdc*dedzu - zdc*dedxu
    3058        2076 :          dedzib = xca*dedyt - yca*dedxt + ydc*dedxu - xdc*dedyu
    3059        2076 :          dedxic = zba*dedyt - yba*dedzt + ydb*dedzu - zdb*dedyu
    3060        2076 :          dedyic = xba*dedzt - zba*dedxt + zdb*dedxu - xdb*dedzu
    3061        2076 :          dedzic = yba*dedxt - xba*dedyt + xdb*dedyu - ydb*dedxu
    3062        2076 :          dedxid = zcb*dedyu - ycb*dedzu
    3063        2076 :          dedyid = xcb*dedzu - zcb*dedxu
    3064        2076 :          dedzid = ycb*dedxu - xcb*dedyu
    3065             :       ELSE
    3066             :          dedxia = 0.0_dp
    3067             :          dedyia = 0.0_dp
    3068             :          dedzia = 0.0_dp
    3069             :          dedxib = 0.0_dp
    3070             :          dedyib = 0.0_dp
    3071             :          dedzib = 0.0_dp
    3072             :          dedxic = 0.0_dp
    3073             :          dedyic = 0.0_dp
    3074             :          dedzic = 0.0_dp
    3075             :          dedxid = 0.0_dp
    3076             :          dedyid = 0.0_dp
    3077             :          dedzid = 0.0_dp
    3078             :       END IF
    3079             :       !
    3080        2076 :       colvar%ss = e
    3081        2076 :       IF (no_riemann_sheet) colvar%ss = ATAN2(SIN(e), COS(e))
    3082        2076 :       ftmp(1) = dedxia
    3083        2076 :       ftmp(2) = dedyia
    3084        2076 :       ftmp(3) = dedzia
    3085        2076 :       CALL put_derivative(colvar, 1, ftmp)
    3086        2076 :       ftmp(1) = dedxib
    3087        2076 :       ftmp(2) = dedyib
    3088        2076 :       ftmp(3) = dedzib
    3089        2076 :       CALL put_derivative(colvar, 2, ftmp)
    3090        2076 :       ftmp(1) = dedxic
    3091        2076 :       ftmp(2) = dedyic
    3092        2076 :       ftmp(3) = dedzic
    3093        2076 :       CALL put_derivative(colvar, 3, ftmp)
    3094        2076 :       ftmp(1) = dedxid
    3095        2076 :       ftmp(2) = dedyid
    3096        2076 :       ftmp(3) = dedzid
    3097        2076 :       CALL put_derivative(colvar, 4, ftmp)
    3098        2076 :    END SUBROUTINE torsion_colvar
    3099             : 
    3100             : ! **************************************************************************************************
    3101             : !> \brief evaluates the force due (and on) the Q PARM collective variable
    3102             : !> \param colvar ...
    3103             : !> \param cell ...
    3104             : !> \param subsys ...
    3105             : !> \param particles ...
    3106             : ! **************************************************************************************************
    3107          42 :    SUBROUTINE qparm_colvar(colvar, cell, subsys, particles)
    3108             :       TYPE(colvar_type), POINTER                         :: colvar
    3109             :       TYPE(cell_type), POINTER                           :: cell
    3110             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    3111             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    3112             :          POINTER                                         :: particles
    3113             : 
    3114             :       INTEGER                                            :: aa, bb, cc, i, idim, ii, j, jj, l, mm, &
    3115             :                                                             n_atoms_from, n_atoms_to, ncells(3)
    3116             :       LOGICAL                                            :: include_images
    3117             :       REAL(KIND=dp) :: denominator_tolerance, fact, ftmp(3), im_qlm, inv_n_atoms_from, nbond, &
    3118             :          pre_fac, ql, qparm, r1cut, rcut, re_qlm, rij, rij_shift, shift(3), ss(3), ss0(3), xij(3), &
    3119             :          xij_shift(3)
    3120             :       REAL(KIND=dp), DIMENSION(3)                        :: d_im_qlm_dxi, d_nbond_dxi, d_ql_dxi, &
    3121             :                                                             d_re_qlm_dxi, xpi, xpj
    3122             :       TYPE(particle_list_type), POINTER                  :: particles_i
    3123          42 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    3124             : 
    3125             :       ! settings for numerical derivatives
    3126             :       !REAL(KIND=dp) :: ri_step, dx_bond_j, dy_bond_j, dz_bond_j
    3127             :       !INTEGER :: idel
    3128             : 
    3129          42 :       n_atoms_to = colvar%qparm_param%n_atoms_to
    3130          42 :       n_atoms_from = colvar%qparm_param%n_atoms_from
    3131          42 :       rcut = colvar%qparm_param%rcut
    3132          42 :       l = colvar%qparm_param%l
    3133          42 :       r1cut = colvar%qparm_param%rstart
    3134          42 :       include_images = colvar%qparm_param%include_images
    3135          42 :       NULLIFY (particles_i)
    3136           0 :       CPASSERT(colvar%type_id == qparm_colvar_id)
    3137          42 :       IF (PRESENT(particles)) THEN
    3138           0 :          my_particles => particles
    3139             :       ELSE
    3140          42 :          CPASSERT(PRESENT(subsys))
    3141          42 :          CALL cp_subsys_get(subsys, particles=particles_i)
    3142          42 :          my_particles => particles_i%els
    3143             :       END IF
    3144          42 :       CPASSERT(r1cut .LT. rcut)
    3145          42 :       denominator_tolerance = 1.0E-8_dp
    3146             : 
    3147             :       !ri_step=0.1
    3148             :       !DO idel=-50, 50
    3149             :       !ftmp(:) = 0.0_dp
    3150             : 
    3151          42 :       qparm = 0.0_dp
    3152          42 :       inv_n_atoms_from = 1.0_dp/REAL(n_atoms_from, KIND=dp)
    3153        4578 :       DO ii = 1, n_atoms_from
    3154        4536 :          i = colvar%qparm_param%i_at_from(ii)
    3155        4536 :          CALL get_coordinates(colvar, i, xpi, my_particles)
    3156             :          !xpi(1)=xpi(1)+idel*ri_step
    3157        4536 :          ql = 0.0_dp
    3158        4536 :          d_ql_dxi(:) = 0.0_dp
    3159             : 
    3160       63504 :          DO mm = -l, l
    3161       58968 :             nbond = 0.0_dp
    3162       58968 :             re_qlm = 0.0_dp
    3163       58968 :             im_qlm = 0.0_dp
    3164       58968 :             d_re_qlm_dxi(:) = 0.0_dp
    3165       58968 :             d_im_qlm_dxi(:) = 0.0_dp
    3166       58968 :             d_nbond_dxi(:) = 0.0_dp
    3167             : 
    3168     6427512 :             jloop: DO jj = 1, n_atoms_to
    3169             : 
    3170     6368544 :                j = colvar%qparm_param%i_at_to(jj)
    3171     6368544 :                CALL get_coordinates(colvar, j, xpj, my_particles)
    3172             : 
    3173     6427512 :                IF (include_images) THEN
    3174             : 
    3175           0 :                   CPASSERT(cell%orthorhombic)
    3176             : 
    3177             :                   ! determine how many cells must be included in each direction
    3178             :                   ! based on rcut
    3179           0 :                   xij(:) = xpj(:) - xpi(:)
    3180           0 :                   ss = MATMUL(cell%h_inv, xij)
    3181             :                   ! these are fractional coordinates of the closest periodic image
    3182             :                   ! lie in the [-0.5,0.5] interval
    3183           0 :                   ss0 = ss - NINT(ss)
    3184           0 :                   DO idim = 1, 3
    3185           0 :                      shift(:) = 0.0_dp
    3186           0 :                      shift(idim) = 1.0_dp
    3187           0 :                      xij_shift = MATMUL(cell%hmat, shift)
    3188           0 :                      rij_shift = SQRT(DOT_PRODUCT(xij_shift, xij_shift))
    3189           0 :                      ncells(idim) = FLOOR(rcut/rij_shift - 0.5)
    3190             :                   END DO !idim
    3191             : 
    3192             :                   !IF (mm.eq.0) WRITE(*,'(A8,3I3,A3,I10)') "Ncells:", ncells, "J:", j
    3193           0 :                   shift(1:3) = 0.0_dp
    3194           0 :                   DO aa = -ncells(1), ncells(1)
    3195           0 :                      DO bb = -ncells(2), ncells(2)
    3196           0 :                         DO cc = -ncells(3), ncells(3)
    3197             :                            ! do not include the central atom
    3198           0 :                            IF (i == j .AND. aa .EQ. 0 .AND. bb .EQ. 0 .AND. cc .EQ. 0) CYCLE
    3199           0 :                            shift(1) = REAL(aa, KIND=dp)
    3200           0 :                            shift(2) = REAL(bb, KIND=dp)
    3201           0 :                            shift(3) = REAL(cc, KIND=dp)
    3202           0 :                            xij = MATMUL(cell%hmat, ss0(:) + shift(:))
    3203           0 :                            rij = SQRT(DOT_PRODUCT(xij, xij))
    3204             :                            !IF (rij > rcut) THEN
    3205             :                            !   IF (mm.EQ.0) WRITE(*,'(A8,4F10.5)') " --", shift, rij
    3206             :                            !ELSE
    3207             :                            !   IF (mm.EQ.0) WRITE(*,'(A8,4F10.5)') " ++", shift, rij
    3208             :                            !ENDIF
    3209           0 :                            IF (rij > rcut) CYCLE
    3210             : 
    3211             :                            ! update qlm
    3212             :                            CALL accumulate_qlm_over_neigbors(xij, rij, rcut, r1cut, &
    3213             :                                                              denominator_tolerance, l, mm, nbond, re_qlm, im_qlm, &
    3214           0 :                                                              d_re_qlm_dxi, d_im_qlm_dxi, d_nbond_dxi)
    3215             : 
    3216             :                         END DO
    3217             :                      END DO
    3218             :                   END DO
    3219             : 
    3220             :                ELSE
    3221             : 
    3222     6368544 :                   IF (i == j) CYCLE jloop
    3223    25238304 :                   xij(:) = xpj(:) - xpi(:)
    3224    25238304 :                   rij = SQRT(DOT_PRODUCT(xij, xij))
    3225     6309576 :                   IF (rij > rcut) CYCLE
    3226             : 
    3227             :                   ! update qlm
    3228             :                   CALL accumulate_qlm_over_neigbors(xij, rij, rcut, r1cut, &
    3229             :                                                     denominator_tolerance, l, mm, nbond, re_qlm, im_qlm, &
    3230      491504 :                                                     d_re_qlm_dxi, d_im_qlm_dxi, d_nbond_dxi)
    3231             : 
    3232             :                END IF ! include images
    3233             : 
    3234             :             END DO jloop
    3235             : 
    3236             :             ! this factor is necessary if one whishes to sum over m=0,L
    3237             :             ! instead of m=-L,+L. This is off now because it is cheap and safe
    3238       58968 :             fact = 1.0_dp
    3239             :             !IF (ABS(mm) .GT. 0) THEN
    3240             :             !   fact = 2.0_dp
    3241             :             !ELSE
    3242             :             !   fact = 1.0_dp
    3243             :             !ENDIF
    3244             : 
    3245       58968 :             IF (nbond .LT. denominator_tolerance) THEN
    3246           0 :                CPWARN("QPARM: number of neighbors is very close to zero!")
    3247             :             END IF
    3248             : 
    3249      235872 :             d_nbond_dxi(:) = d_nbond_dxi(:)/nbond
    3250       58968 :             re_qlm = re_qlm/nbond
    3251      235872 :             d_re_qlm_dxi(:) = d_re_qlm_dxi(:)/nbond - d_nbond_dxi(:)*re_qlm
    3252       58968 :             im_qlm = im_qlm/nbond
    3253      235872 :             d_im_qlm_dxi(:) = d_im_qlm_dxi(:)/nbond - d_nbond_dxi(:)*im_qlm
    3254             : 
    3255       58968 :             ql = ql + fact*(re_qlm*re_qlm + im_qlm*im_qlm)
    3256             :             d_ql_dxi(:) = d_ql_dxi(:) &
    3257      240408 :                           + fact*2.0_dp*(re_qlm*d_re_qlm_dxi(:) + im_qlm*d_im_qlm_dxi(:))
    3258             : 
    3259             :          END DO ! loop over m
    3260             : 
    3261        4536 :          pre_fac = (4.0_dp*pi)/(2.0_dp*l + 1)
    3262             :          !WRITE(*,'(A8,2F10.5)') "  si = ", SQRT(pre_fac*ql)
    3263        4536 :          qparm = qparm + SQRT(pre_fac*ql)
    3264       18144 :          ftmp(:) = 0.5_dp*SQRT(pre_fac/ql)*d_ql_dxi(:)
    3265             :          ! multiply by -1 because aparently we have to save the force, not the gradient
    3266       18144 :          ftmp(:) = -1.0_dp*ftmp(:)
    3267             : 
    3268        4578 :          CALL put_derivative(colvar, ii, ftmp)
    3269             : 
    3270             :       END DO ! loop over i
    3271             : 
    3272          42 :       colvar%ss = qparm*inv_n_atoms_from
    3273       36330 :       colvar%dsdr(:, :) = colvar%dsdr(:, :)*inv_n_atoms_from
    3274             : 
    3275             :       !WRITE(*,'(A15,3E20.10)') "COLVAR+DER = ", ri_step*idel, colvar%ss, -ftmp(1)
    3276             : 
    3277             :       !ENDDO ! numercal derivative
    3278             : 
    3279          42 :    END SUBROUTINE qparm_colvar
    3280             : 
    3281             : ! **************************************************************************************************
    3282             : !> \brief ...
    3283             : !> \param xij ...
    3284             : !> \param rij ...
    3285             : !> \param rcut ...
    3286             : !> \param r1cut ...
    3287             : !> \param denominator_tolerance ...
    3288             : !> \param ll ...
    3289             : !> \param mm ...
    3290             : !> \param nbond ...
    3291             : !> \param re_qlm ...
    3292             : !> \param im_qlm ...
    3293             : !> \param d_re_qlm_dxi ...
    3294             : !> \param d_im_qlm_dxi ...
    3295             : !> \param d_nbond_dxi ...
    3296             : ! **************************************************************************************************
    3297      491504 :    SUBROUTINE accumulate_qlm_over_neigbors(xij, rij, rcut, r1cut, &
    3298             :                                            denominator_tolerance, ll, mm, nbond, re_qlm, im_qlm, &
    3299             :                                            d_re_qlm_dxi, d_im_qlm_dxi, d_nbond_dxi)
    3300             : 
    3301             :       REAL(KIND=dp), INTENT(IN)                          :: xij(3), rij, rcut, r1cut, &
    3302             :                                                             denominator_tolerance
    3303             :       INTEGER, INTENT(IN)                                :: ll, mm
    3304             :       REAL(KIND=dp), INTENT(INOUT)                       :: nbond, re_qlm, im_qlm, d_re_qlm_dxi(3), &
    3305             :                                                             d_im_qlm_dxi(3), d_nbond_dxi(3)
    3306             : 
    3307             :       REAL(KIND=dp)                                      :: bond, costheta, dplm, dylm, exp0, &
    3308             :                                                             exp_fac, fi, plm, pre_fac, sqrt_c1
    3309             :       REAL(KIND=dp), DIMENSION(3)                        :: dcosTheta, dfi
    3310             : 
    3311             :       !bond = 1.0_dp/(1.0_dp+EXP(alpha*(rij-rcut)))
    3312             :       ! RZK: infinitely differentiable smooth cutoff function
    3313             :       ! that is precisely 1.0 below r1cut and precisely 0.0 above rcut
    3314      491504 :       IF (rij .GT. rcut) THEN
    3315             :          !bond = 0.0_dp
    3316             :          !exp_fac = 0.0_dp
    3317           0 :          RETURN
    3318             :       ELSE
    3319      491504 :          IF (rij .LT. r1cut) THEN
    3320             :             bond = 1.0_dp
    3321             :             exp_fac = 0.0_dp
    3322             :          ELSE
    3323         156 :             exp0 = EXP((r1cut - rcut)/(rij - rcut) - (r1cut - rcut)/(r1cut - rij))
    3324         156 :             bond = 1.0_dp/(1.0_dp + exp0)
    3325         156 :             exp_fac = ((rcut - r1cut)/(rij - rcut)**2 + (rcut - r1cut)/(r1cut - rij)**2)*exp0/(1.0_dp + exp0)**2
    3326             :          END IF
    3327             :       END IF
    3328             :       IF (bond > 1.0_dp) THEN
    3329             :          CPABORT("bond > 1.0_dp")
    3330             :       END IF
    3331             :       ! compute continuous bond order
    3332      491504 :       nbond = nbond + bond
    3333             :       IF (ABS(xij(1)) .LT. denominator_tolerance &
    3334      491504 :           .AND. ABS(xij(2)) .LT. denominator_tolerance) THEN
    3335             :          fi = 0.0_dp
    3336             :       ELSE
    3337      491504 :          fi = ATAN2(xij(2), xij(1))
    3338             :       END IF
    3339             : 
    3340      491504 :       costheta = xij(3)/rij
    3341      491504 :       IF (costheta > 1.0_dp) costheta = 1.0_dp
    3342      491504 :       IF (costheta < -1.0_dp) costheta = -1.0_dp
    3343             : 
    3344             :       ! legendre works correctly only for positive m
    3345      491504 :       plm = legendre(costheta, ll, mm)
    3346      491504 :       dplm = dlegendre(costheta, ll, mm)
    3347      491504 :       IF ((ll + ABS(mm)) > maxfac) THEN
    3348           0 :          CPABORT("(l+m) > maxfac")
    3349             :       END IF
    3350             :       ! use absolute m to compenstate for the defficiency of legendre
    3351      491504 :       sqrt_c1 = SQRT(((2*ll + 1)*fac(ll - ABS(mm)))/(4*pi*fac(ll + ABS(mm))))
    3352      491504 :       pre_fac = bond*sqrt_c1
    3353      491504 :       dylm = pre_fac*dplm
    3354             :       !WHY? IF (plm < 0.0_dp) THEN
    3355             :       !WHY?    dylm = -pre_fac*dplm
    3356             :       !WHY? ELSE
    3357             :       !WHY?    dylm = pre_fac*dplm
    3358             :       !WHY? ENDIF
    3359             : 
    3360      491504 :       re_qlm = re_qlm + pre_fac*plm*COS(mm*fi)
    3361      491504 :       im_qlm = im_qlm + pre_fac*plm*SIN(mm*fi)
    3362             : 
    3363             :       !WRITE(*,'(A8,2I4,F10.5)') "  Qlm = ", mm, j, bond
    3364             :       !WRITE(*,'(A8,2I4,2F10.5)') "  Qlm = ", mm, j, re_qlm, im_qlm
    3365             : 
    3366     1966016 :       dcosTheta(:) = xij(:)*xij(3)/(rij**3)
    3367      491504 :       dcosTheta(3) = dcosTheta(3) - 1.0_dp/rij
    3368             :       ! use tangent half-angle formula to compute d_fi/d_xi
    3369             :       ! http://math.stackexchange.com/questions/989877/continuous-differentiability-of-atan2
    3370             :       ! +/- sign changed because xij = xj - xi
    3371      491504 :       dfi(1) = xij(2)/(xij(1)**2 + xij(2)**2)
    3372      491504 :       dfi(2) = -xij(1)/(xij(1)**2 + xij(2)**2)
    3373      491504 :       dfi(3) = 0.0_dp
    3374             :       d_re_qlm_dxi(:) = d_re_qlm_dxi(:) &
    3375             :                         + exp_fac*sqrt_c1*plm*COS(mm*fi)*xij(:)/rij &
    3376             :                         + dylm*dcosTheta(:)*COS(mm*fi) &
    3377     1966016 :                         + pre_fac*plm*mm*(-1.0_dp)*SIN(mm*fi)*dfi(:)
    3378             :       d_im_qlm_dxi(:) = d_im_qlm_dxi(:) &
    3379             :                         + exp_fac*sqrt_c1*plm*SIN(mm*fi)*xij(:)/rij &
    3380             :                         + dylm*dcosTheta(:)*SIN(mm*fi) &
    3381     1966016 :                         + pre_fac*plm*mm*(+1.0_dp)*COS(mm*fi)*dfi(:)
    3382     1966016 :       d_nbond_dxi(:) = d_nbond_dxi(:) + exp_fac*xij(:)/rij
    3383             : 
    3384             :    END SUBROUTINE accumulate_qlm_over_neigbors
    3385             : 
    3386             : ! **************************************************************************************************
    3387             : !> \brief evaluates the force due (and on) the hydronium_shell collective variable
    3388             : !> \param colvar ...
    3389             : !> \param cell ...
    3390             : !> \param subsys ...
    3391             : !> \param particles ...
    3392             : !> \author Marcel Baer
    3393             : !> \note This function needs to be extended to the POINT structure!!
    3394             : !>       non-standard conform.. it's a breach in the colvar module.
    3395             : ! **************************************************************************************************
    3396          12 :    SUBROUTINE hydronium_shell_colvar(colvar, cell, subsys, particles)
    3397             :       TYPE(colvar_type), POINTER                         :: colvar
    3398             :       TYPE(cell_type), POINTER                           :: cell
    3399             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    3400             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    3401             :          POINTER                                         :: particles
    3402             : 
    3403             :       INTEGER                                            :: i, ii, j, jj, n_hydrogens, n_oxygens, &
    3404             :                                                             pm, poh, poo, qm, qoh, qoo
    3405             :       REAL(dp)                                           :: drji, fscalar, invden, lambda, nh, num, &
    3406             :                                                             qtot, rji(3), roh, roo, rrel
    3407          12 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: M, noh, noo, qloc
    3408          12 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: dM, dnoh, dnoo
    3409             :       REAL(dp), DIMENSION(3)                             :: rpi, rpj
    3410             :       TYPE(particle_list_type), POINTER                  :: particles_i
    3411          12 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    3412             : 
    3413          12 :       n_oxygens = colvar%hydronium_shell_param%n_oxygens
    3414          12 :       n_hydrogens = colvar%hydronium_shell_param%n_hydrogens
    3415          12 :       nh = colvar%hydronium_shell_param%nh
    3416          12 :       poh = colvar%hydronium_shell_param%poh
    3417          12 :       qoh = colvar%hydronium_shell_param%qoh
    3418          12 :       poo = colvar%hydronium_shell_param%poo
    3419          12 :       qoo = colvar%hydronium_shell_param%qoo
    3420          12 :       roo = colvar%hydronium_shell_param%roo
    3421          12 :       roh = colvar%hydronium_shell_param%roh
    3422          12 :       lambda = colvar%hydronium_shell_param%lambda
    3423          12 :       pm = colvar%hydronium_shell_param%pm
    3424          12 :       qm = colvar%hydronium_shell_param%qm
    3425             : 
    3426          12 :       NULLIFY (particles_i)
    3427           0 :       CPASSERT(colvar%type_id == hydronium_shell_colvar_id)
    3428          12 :       IF (PRESENT(particles)) THEN
    3429           0 :          my_particles => particles
    3430             :       ELSE
    3431          12 :          CPASSERT(PRESENT(subsys))
    3432          12 :          CALL cp_subsys_get(subsys, particles=particles_i)
    3433          12 :          my_particles => particles_i%els
    3434             :       END IF
    3435             : 
    3436          48 :       ALLOCATE (dnoh(3, n_hydrogens, n_oxygens))
    3437          36 :       ALLOCATE (noh(n_oxygens))
    3438          24 :       ALLOCATE (M(n_oxygens))
    3439          36 :       ALLOCATE (dM(3, n_hydrogens, n_oxygens))
    3440             : 
    3441          48 :       ALLOCATE (dnoo(3, n_oxygens, n_oxygens))
    3442          24 :       ALLOCATE (noo(n_oxygens))
    3443             : 
    3444          24 :       ALLOCATE (qloc(n_oxygens))
    3445             : 
    3446             :       ! Zero Arrays:
    3447        1788 :       dnoh = 0._dp
    3448         828 :       dnoo = 0._dp
    3449          60 :       M = 0._dp
    3450        1788 :       dM = 0._dp
    3451          60 :       noo = 0._dp
    3452          60 :       qloc = 0._dp
    3453          60 :       noh = 0._dp
    3454          60 :       DO ii = 1, n_oxygens
    3455          48 :          i = colvar%hydronium_shell_param%i_oxygens(ii)
    3456         192 :          rpi(:) = my_particles(i)%r(1:3)
    3457             :          ! Computing M( n ( ii ) )
    3458         480 :          DO jj = 1, n_hydrogens
    3459         432 :             j = colvar%hydronium_shell_param%i_hydrogens(jj)
    3460        1728 :             rpj(:) = my_particles(j)%r(1:3)
    3461         432 :             rji = pbc(rpj, rpi, cell)
    3462        1728 :             drji = SQRT(SUM(rji**2))
    3463         432 :             rrel = drji/roh
    3464         432 :             num = (1.0_dp - rrel**poh)
    3465         432 :             invden = 1.0_dp/(1.0_dp - rrel**qoh)
    3466         480 :             IF (ABS(1.0_dp - rrel) > 1.0E-6_dp) THEN
    3467         432 :                noh(ii) = noh(ii) + num*invden
    3468             :                fscalar = ((-poh*(rrel**(poh - 1))*invden) &
    3469         432 :                           + num*(invden)**2*qoh*(rrel**(qoh - 1)))/(drji*roh)
    3470        1728 :                dnoh(1:3, jj, ii) = rji(1:3)*fscalar
    3471             :             ELSE
    3472             :                !correct limit if rji --> roh
    3473           0 :                noh(ii) = noh(ii) + REAL(poh, dp)/REAL(qoh, dp)
    3474           0 :                fscalar = REAL(poh*(poh - qoh), dp)/(REAL(2*qoh, dp)*roh*drji)
    3475           0 :                dnoh(1:3, jj, ii) = rji(1:3)*fscalar
    3476             :             END IF
    3477             :          END DO
    3478             :          M(ii) = 1.0_dp - (1.0_dp - (noh(ii)/nh)**pm)/ &
    3479          48 :                  (1.0_dp - (noh(ii)/nh)**qm)
    3480             : 
    3481             :          ! Computing no ( ii )
    3482         252 :          DO jj = 1, n_oxygens
    3483         192 :             IF (ii == jj) CYCLE
    3484         144 :             j = colvar%hydronium_shell_param%i_oxygens(jj)
    3485         576 :             rpj(:) = my_particles(j)%r(1:3)
    3486         144 :             rji = pbc(rpj, rpi, cell)
    3487         576 :             drji = SQRT(SUM(rji**2))
    3488         144 :             rrel = drji/roo
    3489         144 :             num = (1.0_dp - rrel**poo)
    3490         144 :             invden = 1.0_dp/(1.0_dp - rrel**qoo)
    3491         192 :             IF (ABS(1.0_dp - rrel) > 1.0E-6_dp) THEN
    3492         144 :                noo(ii) = noo(ii) + num*invden
    3493             :                fscalar = ((-poo*(rrel**(poo - 1))*invden) &
    3494         144 :                           + num*(invden)**2*qoo*(rrel**(qoo - 1)))/(drji*roo)
    3495         576 :                dnoo(1:3, jj, ii) = rji(1:3)*fscalar
    3496             :             ELSE
    3497             :                !correct limit if rji --> roo
    3498           0 :                noo(ii) = noo(ii) + REAL(poo, dp)/REAL(qoo, dp)
    3499           0 :                fscalar = REAL(poo*(poo - qoo), dp)/(REAL(2*qoo, dp)*roo*drji)
    3500           0 :                dnoo(1:3, jj, ii) = rji(1:3)*fscalar
    3501             :             END IF
    3502             :          END DO
    3503             :       END DO
    3504             : 
    3505             :       ! computing qloc and Q
    3506             :       qtot = 0._dp
    3507          60 :       DO ii = 1, n_oxygens
    3508          48 :          qloc(ii) = EXP(lambda*M(ii)*noo(ii))
    3509          60 :          qtot = qtot + qloc(ii)
    3510             :       END DO
    3511             :       ! compute forces
    3512          60 :       DO ii = 1, n_oxygens
    3513             :          ! Computing f_OH
    3514         480 :          DO jj = 1, n_hydrogens
    3515             :             dM(1:3, jj, ii) = (pm*((noh(ii)/nh)**(pm - 1))*dnoh(1:3, jj, ii))/nh/ &
    3516             :                               (1.0_dp - (noh(ii)/nh)**qm) - &
    3517             :                               (1.0_dp - (noh(ii)/nh)**pm)/ &
    3518             :                               ((1.0_dp - (noh(ii)/nh)**qm)**2)* &
    3519        1728 :                               qm*dnoh(1:3, jj, ii)*(noh(ii)/nh)**(qm - 1)/nh
    3520             : 
    3521        1728 :             colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) + qloc(ii)*dM(1:3, jj, ii)*noo(ii)/qtot
    3522             :             colvar%dsdr(1:3, n_oxygens + jj) = colvar%dsdr(1:3, n_oxygens + jj) &
    3523        1776 :                                                - qloc(ii)*dM(1:3, jj, ii)*noo(ii)/qtot
    3524             :          END DO
    3525             :          ! Computing f_OO
    3526         252 :          DO jj = 1, n_oxygens
    3527         768 :             colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) + qloc(ii)*M(ii)*dnoo(1:3, jj, ii)/qtot
    3528             :             colvar%dsdr(1:3, jj) = colvar%dsdr(1:3, jj) &
    3529         816 :                                    - qloc(ii)*M(ii)*dnoo(1:3, jj, ii)/qtot
    3530             :          END DO
    3531             :       END DO
    3532             : 
    3533          12 :       colvar%ss = LOG(qtot)/lambda
    3534          12 :       DEALLOCATE (dnoh)
    3535          12 :       DEALLOCATE (noh)
    3536          12 :       DEALLOCATE (M)
    3537          12 :       DEALLOCATE (dM)
    3538          12 :       DEALLOCATE (dnoo)
    3539          12 :       DEALLOCATE (noo)
    3540          12 :       DEALLOCATE (qloc)
    3541             : 
    3542          12 :    END SUBROUTINE hydronium_shell_colvar
    3543             : 
    3544             : ! **************************************************************************************************
    3545             : !> \brief evaluates the force due (and on) the hydronium_dist collective variable;
    3546             : !>        distance between hydronium and hydroxide ion
    3547             : !> \param colvar ...
    3548             : !> \param cell ...
    3549             : !> \param subsys ...
    3550             : !> \param particles ...
    3551             : !> \author Dorothea Golze
    3552             : ! **************************************************************************************************
    3553          12 :    SUBROUTINE hydronium_dist_colvar(colvar, cell, subsys, particles)
    3554             :       TYPE(colvar_type), POINTER                         :: colvar
    3555             :       TYPE(cell_type), POINTER                           :: cell
    3556             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    3557             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    3558             :          POINTER                                         :: particles
    3559             : 
    3560             :       INTEGER                                            :: i, ii, j, jj, k, kk, n_hydrogens, &
    3561             :                                                             n_oxygens, offsetH, pf, pm, poh, qf, &
    3562             :                                                             qm, qoh
    3563             :       REAL(dp) :: drji, drki, fscalar, invden, lambda, nh, nn, num, rion, rion_den, rion_num, &
    3564             :          rji(3), rki(3), roh, rrel, sum_expfac_F, sum_expfac_noh
    3565          12 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: dexpfac_F, dexpfac_noh, dF, dM, &
    3566          12 :                                                             expfac_F, expfac_F_rki, expfac_noh, F, &
    3567          12 :                                                             M, noh
    3568          12 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: dexpfac_F_rki
    3569          12 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: ddist_rki, dnoh
    3570             :       REAL(dp), DIMENSION(3)                             :: rpi, rpj, rpk
    3571             :       TYPE(particle_list_type), POINTER                  :: particles_i
    3572          12 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    3573             : 
    3574          12 :       n_oxygens = colvar%hydronium_dist_param%n_oxygens
    3575          12 :       n_hydrogens = colvar%hydronium_dist_param%n_hydrogens
    3576          12 :       poh = colvar%hydronium_dist_param%poh
    3577          12 :       qoh = colvar%hydronium_dist_param%qoh
    3578          12 :       roh = colvar%hydronium_dist_param%roh
    3579          12 :       pm = colvar%hydronium_dist_param%pm
    3580          12 :       qm = colvar%hydronium_dist_param%qm
    3581          12 :       nh = colvar%hydronium_dist_param%nh
    3582          12 :       pf = colvar%hydronium_dist_param%pf
    3583          12 :       qf = colvar%hydronium_dist_param%qf
    3584          12 :       nn = colvar%hydronium_dist_param%nn
    3585          12 :       lambda = colvar%hydronium_dist_param%lambda
    3586             : 
    3587          12 :       NULLIFY (particles_i)
    3588           0 :       CPASSERT(colvar%type_id == hydronium_dist_colvar_id)
    3589          12 :       IF (PRESENT(particles)) THEN
    3590           0 :          my_particles => particles
    3591             :       ELSE
    3592          12 :          CPASSERT(PRESENT(subsys))
    3593          12 :          CALL cp_subsys_get(subsys, particles=particles_i)
    3594          12 :          my_particles => particles_i%els
    3595             :       END IF
    3596             : 
    3597          48 :       ALLOCATE (dnoh(3, n_hydrogens, n_oxygens))
    3598          36 :       ALLOCATE (noh(n_oxygens))
    3599          36 :       ALLOCATE (M(n_oxygens), dM(n_oxygens))
    3600          36 :       ALLOCATE (F(n_oxygens), dF(n_oxygens))
    3601          36 :       ALLOCATE (expfac_noh(n_oxygens), dexpfac_noh(n_oxygens))
    3602          36 :       ALLOCATE (expfac_F(n_oxygens), dexpfac_F(n_oxygens))
    3603          48 :       ALLOCATE (ddist_rki(3, n_oxygens, n_oxygens))
    3604          24 :       ALLOCATE (expfac_F_rki(n_oxygens))
    3605          48 :       ALLOCATE (dexpfac_F_rki(n_oxygens, n_oxygens))
    3606             : 
    3607             :       ! Zero Arrays:
    3608          60 :       noh = 0._dp
    3609        1788 :       dnoh = 0._dp
    3610          60 :       rion_num = 0._dp
    3611          60 :       F = 0._dp
    3612          60 :       M = 0._dp
    3613          60 :       dF = 0._dp
    3614          60 :       dM = 0._dp
    3615          60 :       expfac_noh = 0._dp
    3616          60 :       expfac_F = 0._dp
    3617          60 :       sum_expfac_noh = 0._dp
    3618          60 :       sum_expfac_F = 0._dp
    3619         828 :       ddist_rki = 0._dp
    3620          60 :       expfac_F_rki = 0._dp
    3621         252 :       dexpfac_F_rki = 0._dp
    3622             : 
    3623             :       !*** Calculate coordination function noh(ii) and its derivative
    3624          60 :       DO ii = 1, n_oxygens
    3625          48 :          i = colvar%hydronium_dist_param%i_oxygens(ii)
    3626         192 :          rpi(:) = my_particles(i)%r(1:3)
    3627         492 :          DO jj = 1, n_hydrogens
    3628         432 :             j = colvar%hydronium_dist_param%i_hydrogens(jj)
    3629        1728 :             rpj(:) = my_particles(j)%r(1:3)
    3630         432 :             rji = pbc(rpj, rpi, cell)
    3631        1728 :             drji = SQRT(SUM(rji**2))
    3632         432 :             rrel = drji/roh
    3633         432 :             num = (1.0_dp - rrel**poh)
    3634         432 :             invden = 1.0_dp/(1.0_dp - rrel**qoh)
    3635         480 :             IF (ABS(1.0_dp - rrel) > 1.0E-6_dp) THEN
    3636         432 :                noh(ii) = noh(ii) + num*invden
    3637             :                fscalar = ((-poh*(rrel**(poh - 1))*invden) &
    3638         432 :                           + num*(invden)**2*qoh*(rrel**(qoh - 1)))/(drji*roh)
    3639        1728 :                dnoh(1:3, jj, ii) = rji(1:3)*fscalar
    3640             :             ELSE
    3641             :                !correct limit if rji --> roh
    3642           0 :                noh(ii) = noh(ii) + REAL(poh, dp)/REAL(qoh, dp)
    3643           0 :                fscalar = REAL(poh*(poh - qoh), dp)/(REAL(2*qoh, dp)*roh*drji)
    3644           0 :                dnoh(1:3, jj, ii) = rji(1:3)*fscalar
    3645             :             END IF
    3646             :          END DO
    3647             :       END DO
    3648             : 
    3649             :       !*** Calculate M, dM, exp(lambda*M) and sum_[exp(lambda*M)]
    3650          60 :       DO ii = 1, n_oxygens
    3651          48 :          num = 1.0_dp - (noh(ii)/nh)**pm
    3652          48 :          invden = 1.0_dp/(1.0_dp - (noh(ii)/nh)**qm)
    3653          48 :          M(ii) = 1.0_dp - num*invden
    3654             :          dM(ii) = (pm*(noh(ii)/nh)**(pm - 1)*invden - qm*num*(invden**2)* &
    3655          48 :                    (noh(ii)/nh)**(qm - 1))/nh
    3656          48 :          expfac_noh(ii) = EXP(lambda*noh(ii))
    3657          48 :          dexpfac_noh(ii) = lambda*expfac_noh(ii)
    3658          60 :          sum_expfac_noh = sum_expfac_noh + expfac_noh(ii)
    3659             :       END DO
    3660             : 
    3661             :       !*** Calculate F, dF, exp(lambda*F) and sum_[exp(lambda*F)]
    3662          60 :       DO ii = 1, n_oxygens
    3663          48 :          i = colvar%hydronium_dist_param%i_oxygens(ii)
    3664          48 :          num = 1.0_dp - (noh(ii)/nn)**pf
    3665          48 :          invden = 1.0_dp/(1.0_dp - (noh(ii)/nn)**qf)
    3666          48 :          F(ii) = num*invden
    3667             :          dF(ii) = (-pf*(noh(ii)/nn)**(pf - 1)*invden + qf*num*(invden**2)* &
    3668          48 :                    (noh(ii)/nn)**(qf - 1))/nn
    3669          48 :          expfac_F(ii) = EXP(lambda*F(ii))
    3670          48 :          dexpfac_F(ii) = lambda*expfac_F(ii)
    3671          60 :          sum_expfac_F = sum_expfac_F + expfac_F(ii)
    3672             :       END DO
    3673             : 
    3674             :       !*** Calculation numerator of rion
    3675          60 :       DO ii = 1, n_oxygens
    3676          48 :          i = colvar%hydronium_dist_param%i_oxygens(ii)
    3677         192 :          rpi(:) = my_particles(i)%r(1:3)
    3678         240 :          DO kk = 1, n_oxygens
    3679         192 :             IF (ii == kk) CYCLE
    3680         144 :             k = colvar%hydronium_dist_param%i_oxygens(kk)
    3681         576 :             rpk(:) = my_particles(k)%r(1:3)
    3682         144 :             rki = pbc(rpk, rpi, cell)
    3683         576 :             drki = SQRT(SUM(rki**2))
    3684         144 :             expfac_F_rki(ii) = expfac_F_rki(ii) + drki*expfac_F(kk)
    3685         576 :             ddist_rki(1:3, kk, ii) = rki(1:3)/drki
    3686         240 :             dexpfac_F_rki(kk, ii) = drki*dexpfac_F(kk)
    3687             :          END DO
    3688          60 :          rion_num = rion_num + M(ii)*expfac_noh(ii)*expfac_F_rki(ii)
    3689             :       END DO
    3690             : 
    3691             :       !*** Final H3O+/OH- distance
    3692          12 :       rion_den = sum_expfac_noh*sum_expfac_F
    3693          12 :       rion = rion_num/rion_den
    3694          12 :       colvar%ss = rion
    3695             : 
    3696          12 :       offsetH = n_oxygens
    3697             :       !*** Derivatives numerator
    3698          60 :       DO ii = 1, n_oxygens
    3699         480 :          DO jj = 1, n_hydrogens
    3700             :             colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) &
    3701             :                                    + dM(ii)*dnoh(1:3, jj, ii)*expfac_noh(ii) &
    3702        1728 :                                    *expfac_F_rki(ii)/rion_den
    3703             :             colvar%dsdr(1:3, offsetH + jj) = colvar%dsdr(1:3, offsetH + jj) &
    3704             :                                              - dM(ii)*dnoh(1:3, jj, ii)*expfac_noh(ii) &
    3705        1728 :                                              *expfac_F_rki(ii)/rion_den
    3706             :             colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) &
    3707             :                                    + M(ii)*dexpfac_noh(ii)*dnoh(1:3, jj, ii) &
    3708        1728 :                                    *expfac_F_rki(ii)/rion_den
    3709             :             colvar%dsdr(1:3, offsetH + jj) = colvar%dsdr(1:3, offsetH + jj) &
    3710             :                                              - M(ii)*dexpfac_noh(ii)*dnoh(1:3, jj, ii) &
    3711        1776 :                                              *expfac_F_rki(ii)/rion_den
    3712             :          END DO
    3713         252 :          DO kk = 1, n_oxygens
    3714         192 :             IF (ii == kk) CYCLE
    3715             :             colvar%dsdr(1:3, kk) = colvar%dsdr(1:3, kk) &
    3716             :                                    - M(ii)*expfac_noh(ii)*ddist_rki(1:3, kk, ii) &
    3717         576 :                                    *expfac_F(kk)/rion_den
    3718             :             colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) &
    3719             :                                    + M(ii)*expfac_noh(ii)*ddist_rki(1:3, kk, ii) &
    3720         576 :                                    *expfac_F(kk)/rion_den
    3721        1488 :             DO jj = 1, n_hydrogens
    3722             :                colvar%dsdr(1:3, kk) = colvar%dsdr(1:3, kk) &
    3723             :                                       + M(ii)*expfac_noh(ii)*dexpfac_F_rki(kk, ii) &
    3724        5184 :                                       *dF(kk)*dnoh(1:3, jj, kk)/rion_den
    3725             :                colvar%dsdr(1:3, offsetH + jj) = colvar%dsdr(1:3, offsetH + jj) &
    3726             :                                                 - M(ii)*expfac_noh(ii)*dexpfac_F_rki(kk, ii) &
    3727        5376 :                                                 *dF(kk)*dnoh(1:3, jj, kk)/rion_den
    3728             :             END DO
    3729             :          END DO
    3730             :       END DO
    3731             :       !*** Derivatives denominator
    3732          60 :       DO ii = 1, n_oxygens
    3733         492 :          DO jj = 1, n_hydrogens
    3734             :             colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) &
    3735             :                                    - rion_num*sum_expfac_F*dexpfac_noh(ii) &
    3736        1728 :                                    *dnoh(1:3, jj, ii)/(rion_den**2)
    3737             :             colvar%dsdr(1:3, offsetH + jj) = colvar%dsdr(1:3, offsetH + jj) &
    3738             :                                              + rion_num*sum_expfac_F*dexpfac_noh(ii) &
    3739        1728 :                                              *dnoh(1:3, jj, ii)/(rion_den**2)
    3740             :             colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) &
    3741             :                                    - rion_num*sum_expfac_noh*dexpfac_F(ii)*dF(ii) &
    3742        1728 :                                    *dnoh(1:3, jj, ii)/(rion_den**2)
    3743             :             colvar%dsdr(1:3, offsetH + jj) = colvar%dsdr(1:3, offsetH + jj) &
    3744             :                                              + rion_num*sum_expfac_noh*dexpfac_F(ii)*dF(ii) &
    3745        1776 :                                              *dnoh(1:3, jj, ii)/(rion_den**2)
    3746             :          END DO
    3747             :       END DO
    3748             : 
    3749          12 :       DEALLOCATE (noh, M, F, expfac_noh, expfac_F)
    3750          12 :       DEALLOCATE (dnoh, dM, dF, dexpfac_noh, dexpfac_F)
    3751          12 :       DEALLOCATE (ddist_rki, expfac_F_rki, dexpfac_F_rki)
    3752             : 
    3753          12 :    END SUBROUTINE hydronium_dist_colvar
    3754             : 
    3755             : ! **************************************************************************************************
    3756             : !> \brief evaluates the force due (and on) the acid-hydronium-distance
    3757             : !>        collective variable. Colvar: distance between carboxy group and
    3758             : !>        hydronium ion.
    3759             : !> \param colvar collective variable
    3760             : !> \param cell ...
    3761             : !> \param subsys ...
    3762             : !> \param particles ...
    3763             : !> \author Dorothea Golze
    3764             : !> \note this function does not use POINTS, not reasonable for this colvar
    3765             : ! **************************************************************************************************
    3766           8 :    SUBROUTINE acid_hyd_dist_colvar(colvar, cell, subsys, particles)
    3767             :       TYPE(colvar_type), POINTER                         :: colvar
    3768             :       TYPE(cell_type), POINTER                           :: cell
    3769             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    3770             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    3771             :          POINTER                                         :: particles
    3772             : 
    3773             :       INTEGER                                            :: i, ii, j, jj, k, kk, n_hydrogens, &
    3774             :                                                             n_oxygens_acid, n_oxygens_water, &
    3775             :                                                             offsetH, offsetO, paoh, pcut, pwoh, &
    3776             :                                                             qaoh, qcut, qwoh
    3777           8 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: dexpfac, expfac, nwoh
    3778           8 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: dexpfac_rik
    3779           8 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: ddist_rik, dnaoh, dnwoh
    3780             :       REAL(KIND=dp) :: dfcut, drik, drji, drjk, fbrace, fcut, fscalar, invden, invden_cut, lambda, &
    3781             :          naoh, nc, num, num_cut, raoh, rik(3), rion, rion_den, rion_num, rji(3), rjk(3), rpi(3), &
    3782             :          rpj(3), rpk(3), rrel, rwoh
    3783             :       TYPE(particle_list_type), POINTER                  :: particles_i
    3784           8 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    3785             : 
    3786           8 :       NULLIFY (my_particles, particles_i)
    3787             : 
    3788           8 :       n_oxygens_water = colvar%acid_hyd_dist_param%n_oxygens_water
    3789           8 :       n_oxygens_acid = colvar%acid_hyd_dist_param%n_oxygens_acid
    3790           8 :       n_hydrogens = colvar%acid_hyd_dist_param%n_hydrogens
    3791           8 :       pwoh = colvar%acid_hyd_dist_param%pwoh
    3792           8 :       qwoh = colvar%acid_hyd_dist_param%qwoh
    3793           8 :       paoh = colvar%acid_hyd_dist_param%paoh
    3794           8 :       qaoh = colvar%acid_hyd_dist_param%qaoh
    3795           8 :       pcut = colvar%acid_hyd_dist_param%pcut
    3796           8 :       qcut = colvar%acid_hyd_dist_param%qcut
    3797           8 :       rwoh = colvar%acid_hyd_dist_param%rwoh
    3798           8 :       raoh = colvar%acid_hyd_dist_param%raoh
    3799           8 :       nc = colvar%acid_hyd_dist_param%nc
    3800           8 :       lambda = colvar%acid_hyd_dist_param%lambda
    3801          24 :       ALLOCATE (expfac(n_oxygens_water))
    3802          16 :       ALLOCATE (nwoh(n_oxygens_water))
    3803          32 :       ALLOCATE (dnwoh(3, n_hydrogens, n_oxygens_water))
    3804          32 :       ALLOCATE (dnaoh(3, n_hydrogens, n_oxygens_acid))
    3805          16 :       ALLOCATE (dexpfac(n_oxygens_water))
    3806          32 :       ALLOCATE (ddist_rik(3, n_oxygens_water, n_oxygens_acid))
    3807          32 :       ALLOCATE (dexpfac_rik(n_oxygens_water, n_oxygens_acid))
    3808          24 :       rion_den = 0._dp
    3809          24 :       rion_num = 0._dp
    3810          24 :       nwoh(:) = 0._dp
    3811          24 :       naoh = 0._dp
    3812         344 :       dnaoh(:, :, :) = 0._dp
    3813         344 :       dnwoh(:, :, :) = 0._dp
    3814         152 :       ddist_rik(:, :, :) = 0._dp
    3815          24 :       dexpfac(:) = 0._dp
    3816          56 :       dexpfac_rik(:, :) = 0._dp
    3817             : 
    3818           8 :       CPASSERT(colvar%type_id == acid_hyd_dist_colvar_id)
    3819           8 :       IF (PRESENT(particles)) THEN
    3820           0 :          my_particles => particles
    3821             :       ELSE
    3822           8 :          CPASSERT(PRESENT(subsys))
    3823           8 :          CALL cp_subsys_get(subsys, particles=particles_i)
    3824           8 :          my_particles => particles_i%els
    3825             :       END IF
    3826             : 
    3827             :       ! Calculate coordination functions nwoh(ii) and denominator of rion
    3828          24 :       DO ii = 1, n_oxygens_water
    3829          16 :          i = colvar%acid_hyd_dist_param%i_oxygens_water(ii)
    3830          64 :          rpi(:) = my_particles(i)%r(1:3)
    3831          96 :          DO jj = 1, n_hydrogens
    3832          80 :             j = colvar%acid_hyd_dist_param%i_hydrogens(jj)
    3833         320 :             rpj(:) = my_particles(j)%r(1:3)
    3834          80 :             rji = pbc(rpj, rpi, cell)
    3835         320 :             drji = SQRT(SUM(rji**2))
    3836          80 :             rrel = drji/rwoh
    3837          80 :             num = 1.0_dp - rrel**pwoh
    3838          80 :             invden = 1.0_dp/(1.0_dp - rrel**qwoh)
    3839          96 :             IF (ABS(1.0_dp - rrel) > 1.0E-6_dp) THEN
    3840          80 :                nwoh(ii) = nwoh(ii) + num*invden
    3841             :                fscalar = (-pwoh*(rrel**(pwoh - 1))*invden &
    3842          80 :                           + num*(invden**2)*qwoh*(rrel**(qwoh - 1)))/(drji*rwoh)
    3843         320 :                dnwoh(1:3, jj, ii) = rji(1:3)*fscalar
    3844             :             ELSE
    3845             :                !correct limit if rji --> rwoh
    3846           0 :                nwoh(ii) = nwoh(ii) + REAL(pwoh, dp)/REAL(qwoh, dp)
    3847           0 :                fscalar = REAL(pwoh*(pwoh - qwoh), dp)/(REAL(2*qwoh, dp)*rwoh*drji)
    3848           0 :                dnwoh(1:3, jj, ii) = rji(1:3)*fscalar
    3849             :             END IF
    3850             :          END DO
    3851          16 :          expfac(ii) = EXP(lambda*nwoh(ii))
    3852          16 :          dexpfac(ii) = lambda*expfac(ii)
    3853          24 :          rion_den = rion_den + expfac(ii)
    3854             :       END DO
    3855             : 
    3856             :       ! Calculate nominator of rion
    3857          24 :       DO kk = 1, n_oxygens_acid
    3858          16 :          k = colvar%acid_hyd_dist_param%i_oxygens_acid(kk)
    3859          64 :          rpk(:) = my_particles(k)%r(1:3)
    3860          56 :          DO ii = 1, n_oxygens_water
    3861          32 :             i = colvar%acid_hyd_dist_param%i_oxygens_water(ii)
    3862         128 :             rpi(:) = my_particles(i)%r(1:3)
    3863          32 :             rik = pbc(rpi, rpk, cell)
    3864         128 :             drik = SQRT(SUM(rik**2))
    3865          32 :             rion_num = rion_num + drik*expfac(ii)
    3866         128 :             ddist_rik(1:3, ii, kk) = rik(1:3)/drik
    3867          48 :             dexpfac_rik(ii, kk) = drik*dexpfac(ii)
    3868             :          END DO
    3869             :       END DO
    3870             : 
    3871             :       !Calculate cutoff function
    3872          24 :       DO kk = 1, n_oxygens_acid
    3873          16 :          k = colvar%acid_hyd_dist_param%i_oxygens_acid(kk)
    3874          64 :          rpk(:) = my_particles(k)%r(1:3)
    3875         104 :          DO jj = 1, n_hydrogens
    3876          80 :             j = colvar%acid_hyd_dist_param%i_hydrogens(jj)
    3877         320 :             rpj(:) = my_particles(j)%r(1:3)
    3878          80 :             rjk = pbc(rpj, rpk, cell)
    3879         320 :             drjk = SQRT(SUM(rjk**2))
    3880          80 :             rrel = drjk/raoh
    3881          80 :             num = 1.0_dp - rrel**paoh
    3882          80 :             invden = 1.0_dp/(1.0_dp - rrel**qaoh)
    3883          96 :             IF (ABS(1.0_dp - rrel) > 1.0E-6_dp) THEN
    3884          80 :                naoh = naoh + num*invden
    3885             :                fscalar = (-paoh*(rrel**(paoh - 1))*invden &
    3886          80 :                           + num*(invden**2)*qaoh*(rrel**(qaoh - 1)))/(drjk*raoh)
    3887         320 :                dnaoh(1:3, jj, kk) = rjk(1:3)*fscalar
    3888             :             ELSE
    3889             :                !correct limit if rjk --> raoh
    3890           0 :                naoh = naoh + REAL(paoh, dp)/REAL(qaoh, dp)
    3891           0 :                fscalar = REAL(paoh*(paoh - qaoh), dp)/(REAL(2*qaoh, dp)*raoh*drjk)
    3892           0 :                dnaoh(1:3, jj, kk) = rjk(1:3)*fscalar
    3893             :             END IF
    3894             :          END DO
    3895             :       END DO
    3896           8 :       num_cut = 1.0_dp - (naoh/nc)**pcut
    3897           8 :       invden_cut = 1.0_dp/(1.0_dp - (naoh/nc)**qcut)
    3898           8 :       fcut = num_cut*invden_cut
    3899             : 
    3900             :       !Final distance acid - hydronium
    3901             : !      fbrace = rion_num/rion_den/2.0_dp
    3902           8 :       fbrace = rion_num/rion_den/n_oxygens_acid
    3903           8 :       rion = fcut*fbrace
    3904           8 :       colvar%ss = rion
    3905             : 
    3906             :       !Derivatives of fcut
    3907             :       dfcut = ((-pcut*(naoh/nc)**(pcut - 1)*invden_cut) &
    3908           8 :                + num_cut*(invden_cut**2)*qcut*(naoh/nc)**(qcut - 1))/nc
    3909           8 :       offsetO = n_oxygens_water
    3910           8 :       offsetH = n_oxygens_water + n_oxygens_acid
    3911          24 :       DO kk = 1, n_oxygens_acid
    3912         104 :          DO jj = 1, n_hydrogens
    3913             :             colvar%dsdr(1:3, offsetO + kk) = colvar%dsdr(1:3, offsetO + kk) &
    3914         320 :                                              + dfcut*dnaoh(1:3, jj, kk)*fbrace
    3915             :             colvar%dsdr(1:3, offsetH + jj) = colvar%dsdr(1:3, offsetH + jj) &
    3916         336 :                                              - dfcut*dnaoh(1:3, jj, kk)*fbrace
    3917             :          END DO
    3918             :       END DO
    3919             : 
    3920             :       !Derivatives of fbrace
    3921             :       !***nominator
    3922          24 :       DO kk = 1, n_oxygens_acid
    3923          56 :          DO ii = 1, n_oxygens_water
    3924             :             colvar%dsdr(1:3, offsetO + kk) = colvar%dsdr(1:3, offsetO + kk) &
    3925         128 :                                              + fcut*ddist_rik(1:3, ii, kk)*expfac(ii)/rion_den/n_oxygens_acid
    3926             : !                                             + fcut*ddist_rik(1:3, ii, kk)*expfac(ii)/rion_den/2.0_dp
    3927             :             colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) &
    3928         128 :                                    - fcut*ddist_rik(1:3, ii, kk)*expfac(ii)/rion_den/n_oxygens_acid
    3929             : !                                   - fcut*ddist_rik(1:3, ii, kk)*expfac(ii)/rion_den/2.0_dp
    3930         208 :             DO jj = 1, n_hydrogens
    3931             :                colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) &
    3932         640 :                                       + fcut*dexpfac_rik(ii, kk)*dnwoh(1:3, jj, ii)/rion_den/n_oxygens_acid
    3933             : !                                      + fcut*dexpfac_rik(ii, kk)*dnwoh(1:3, jj, ii)/rion_den/2.0_dp
    3934             :                colvar%dsdr(1:3, offsetH + jj) = colvar%dsdr(1:3, offsetH + jj) &
    3935         672 :                                                 - fcut*dexpfac_rik(ii, kk)*dnwoh(1:3, jj, ii)/rion_den/n_oxygens_acid
    3936             : !                                                - fcut*dexpfac_rik(ii, kk)*dnwoh(1:3, jj, ii)/rion_den/2.0_dp
    3937             :             END DO
    3938             :          END DO
    3939             :       END DO
    3940             :       !***denominator
    3941          24 :       DO ii = 1, n_oxygens_water
    3942         104 :          DO jj = 1, n_hydrogens
    3943             :             colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) &
    3944         320 :                                    - fcut*rion_num*dexpfac(ii)*dnwoh(1:3, jj, ii)/2.0_dp/(rion_den**2)
    3945             :             colvar%dsdr(1:3, offsetH + jj) = colvar%dsdr(1:3, offsetH + jj) &
    3946         336 :                                              + fcut*rion_num*dexpfac(ii)*dnwoh(1:3, jj, ii)/2.0_dp/(rion_den**2)
    3947             :          END DO
    3948             :       END DO
    3949             : 
    3950          16 :    END SUBROUTINE acid_hyd_dist_colvar
    3951             : 
    3952             : ! **************************************************************************************************
    3953             : !> \brief evaluates the force due (and on) the acid-hydronium-shell
    3954             : !>        collective variable. Colvar: number of oxygens in 1st shell of the
    3955             : !>        hydronium.
    3956             : !> \param colvar collective variable
    3957             : !> \param cell ...
    3958             : !> \param subsys ...
    3959             : !> \param particles ...
    3960             : !> \author Dorothea Golze
    3961             : !> \note this function does not use POINTS, not reasonable for this colvar
    3962             : ! **************************************************************************************************
    3963           8 :    SUBROUTINE acid_hyd_shell_colvar(colvar, cell, subsys, particles)
    3964             :       TYPE(colvar_type), POINTER                         :: colvar
    3965             :       TYPE(cell_type), POINTER                           :: cell
    3966             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    3967             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    3968             :          POINTER                                         :: particles
    3969             : 
    3970             :       INTEGER :: i, ii, j, jj, k, kk, n_hydrogens, n_oxygens_acid, n_oxygens_water, offsetH, &
    3971             :          offsetO, paoh, pcut, pm, poo, pwoh, qaoh, qcut, qm, qoo, qwoh, tt
    3972           8 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: dM, M, noo, nwoh, qloc
    3973           8 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: dnaoh, dnoo, dnwoh
    3974             :       REAL(KIND=dp) :: dfcut, drji, drjk, drki, fcut, fscalar, invden, invden_cut, lambda, naoh, &
    3975             :          nc, nh, num, num_cut, qsol, qtot, raoh, rji(3), rjk(3), rki(3), roo, rpi(3), rpj(3), &
    3976             :          rpk(3), rrel, rwoh
    3977             :       TYPE(particle_list_type), POINTER                  :: particles_i
    3978           8 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    3979             : 
    3980           8 :       NULLIFY (my_particles, particles_i)
    3981             : 
    3982           8 :       n_oxygens_water = colvar%acid_hyd_shell_param%n_oxygens_water
    3983           8 :       n_oxygens_acid = colvar%acid_hyd_shell_param%n_oxygens_acid
    3984           8 :       n_hydrogens = colvar%acid_hyd_shell_param%n_hydrogens
    3985           8 :       pwoh = colvar%acid_hyd_shell_param%pwoh
    3986           8 :       qwoh = colvar%acid_hyd_shell_param%qwoh
    3987           8 :       paoh = colvar%acid_hyd_shell_param%paoh
    3988           8 :       qaoh = colvar%acid_hyd_shell_param%qaoh
    3989           8 :       poo = colvar%acid_hyd_shell_param%poo
    3990           8 :       qoo = colvar%acid_hyd_shell_param%qoo
    3991           8 :       pm = colvar%acid_hyd_shell_param%pm
    3992           8 :       qm = colvar%acid_hyd_shell_param%qm
    3993           8 :       pcut = colvar%acid_hyd_shell_param%pcut
    3994           8 :       qcut = colvar%acid_hyd_shell_param%qcut
    3995           8 :       rwoh = colvar%acid_hyd_shell_param%rwoh
    3996           8 :       raoh = colvar%acid_hyd_shell_param%raoh
    3997           8 :       roo = colvar%acid_hyd_shell_param%roo
    3998           8 :       nc = colvar%acid_hyd_shell_param%nc
    3999           8 :       nh = colvar%acid_hyd_shell_param%nh
    4000           8 :       lambda = colvar%acid_hyd_shell_param%lambda
    4001          24 :       ALLOCATE (nwoh(n_oxygens_water))
    4002          32 :       ALLOCATE (dnwoh(3, n_hydrogens, n_oxygens_water))
    4003          32 :       ALLOCATE (dnaoh(3, n_hydrogens, n_oxygens_acid))
    4004          16 :       ALLOCATE (M(n_oxygens_water))
    4005          16 :       ALLOCATE (dM(n_oxygens_water))
    4006          16 :       ALLOCATE (noo(n_oxygens_water))
    4007          32 :       ALLOCATE (dnoo(3, n_oxygens_water + n_oxygens_acid, n_oxygens_water))
    4008          16 :       ALLOCATE (qloc(n_oxygens_water))
    4009          24 :       nwoh(:) = 0._dp
    4010          24 :       naoh = 0._dp
    4011          24 :       noo = 0._dp
    4012         344 :       dnaoh(:, :, :) = 0._dp
    4013         344 :       dnwoh(:, :, :) = 0._dp
    4014         280 :       dnoo(:, :, :) = 0._dp
    4015          24 :       M = 0._dp
    4016          24 :       dM = 0._dp
    4017           8 :       qtot = 0._dp
    4018             : 
    4019           8 :       CPASSERT(colvar%type_id == acid_hyd_shell_colvar_id)
    4020           8 :       IF (PRESENT(particles)) THEN
    4021           0 :          my_particles => particles
    4022             :       ELSE
    4023           8 :          CPASSERT(PRESENT(subsys))
    4024           8 :          CALL cp_subsys_get(subsys, particles=particles_i)
    4025           8 :          my_particles => particles_i%els
    4026             :       END IF
    4027             : 
    4028             :       ! Calculate coordination functions nwoh(ii) and the M function
    4029          24 :       DO ii = 1, n_oxygens_water
    4030          16 :          i = colvar%acid_hyd_shell_param%i_oxygens_water(ii)
    4031          64 :          rpi(:) = my_particles(i)%r(1:3)
    4032         104 :          DO jj = 1, n_hydrogens
    4033          80 :             j = colvar%acid_hyd_shell_param%i_hydrogens(jj)
    4034         320 :             rpj(:) = my_particles(j)%r(1:3)
    4035          80 :             rji = pbc(rpj, rpi, cell)
    4036         320 :             drji = SQRT(SUM(rji**2))
    4037          80 :             rrel = drji/rwoh
    4038          80 :             num = 1.0_dp - rrel**pwoh
    4039          80 :             invden = 1.0_dp/(1.0_dp - rrel**qwoh)
    4040          96 :             IF (ABS(1.0_dp - rrel) > 1.0E-6_dp) THEN
    4041          80 :                nwoh(ii) = nwoh(ii) + num*invden
    4042             :                fscalar = (-pwoh*(rrel**(pwoh - 1))*invden &
    4043          80 :                           + num*(invden**2)*qwoh*(rrel**(qwoh - 1)))/(drji*rwoh)
    4044         320 :                dnwoh(1:3, jj, ii) = rji(1:3)*fscalar
    4045             :             ELSE
    4046             :                !correct limit if rji --> rwoh
    4047           0 :                nwoh(ii) = nwoh(ii) + REAL(pwoh, dp)/REAL(qwoh, dp)
    4048           0 :                fscalar = REAL(pwoh*(pwoh - qwoh), dp)/(REAL(2*qwoh, dp)*rwoh*drji)
    4049           0 :                dnwoh(1:3, jj, ii) = rji(1:3)*fscalar
    4050             :             END IF
    4051             :          END DO
    4052             :       END DO
    4053             : 
    4054             :       ! calculate M function
    4055          24 :       DO ii = 1, n_oxygens_water
    4056          16 :          num = 1.0_dp - (nwoh(ii)/nh)**pm
    4057          16 :          invden = 1.0_dp/(1.0_dp - (nwoh(ii)/nh)**qm)
    4058          16 :          M(ii) = 1.0_dp - num*invden
    4059             :          dM(ii) = (pm*(nwoh(ii)/nh)**(pm - 1)*invden - qm*num*(invden**2)* &
    4060          24 :                    (nwoh(ii)/nh)**(qm - 1))/nh
    4061             :       END DO
    4062             : 
    4063             :       ! Computing noo(i)
    4064          24 :       DO ii = 1, n_oxygens_water
    4065          16 :          i = colvar%acid_hyd_shell_param%i_oxygens_water(ii)
    4066          64 :          rpi(:) = my_particles(i)%r(1:3)
    4067          88 :          DO kk = 1, n_oxygens_water + n_oxygens_acid
    4068          64 :             IF (ii == kk) CYCLE
    4069          48 :             IF (kk <= n_oxygens_water) THEN
    4070          16 :                k = colvar%acid_hyd_shell_param%i_oxygens_water(kk)
    4071          64 :                rpk(:) = my_particles(k)%r(1:3)
    4072             :             ELSE
    4073          32 :                tt = kk - n_oxygens_water
    4074          32 :                k = colvar%acid_hyd_shell_param%i_oxygens_acid(tt)
    4075         128 :                rpk(:) = my_particles(k)%r(1:3)
    4076             :             END IF
    4077          48 :             rki = pbc(rpk, rpi, cell)
    4078         192 :             drki = SQRT(SUM(rki**2))
    4079          48 :             rrel = drki/roo
    4080          48 :             num = 1.0_dp - rrel**poo
    4081          48 :             invden = 1.0_dp/(1.0_dp - rrel**qoo)
    4082          64 :             IF (ABS(1.0_dp - rrel) > 1.0E-6_dp) THEN
    4083          48 :                noo(ii) = noo(ii) + num*invden
    4084             :                fscalar = (-poo*(rrel**(poo - 1))*invden &
    4085          48 :                           + num*(invden**2)*qoo*(rrel**(qoo - 1)))/(drki*roo)
    4086         192 :                dnoo(1:3, kk, ii) = rki(1:3)*fscalar
    4087             :             ELSE
    4088             :                !correct limit if rki --> roo
    4089           0 :                noo(ii) = noo(ii) + REAL(poo, dp)/REAL(qoo, dp)
    4090           0 :                fscalar = REAL(poo*(poo - qoo), dp)/(REAL(2*qoo, dp)*roo*drki)
    4091           0 :                dnoo(1:3, kk, ii) = rki(1:3)*fscalar
    4092             :             END IF
    4093             :          END DO
    4094             :       END DO
    4095             : 
    4096             :       !Calculate cutoff function
    4097          24 :       DO kk = 1, n_oxygens_acid
    4098          16 :          k = colvar%acid_hyd_shell_param%i_oxygens_acid(kk)
    4099          64 :          rpk(:) = my_particles(k)%r(1:3)
    4100         104 :          DO jj = 1, n_hydrogens
    4101          80 :             j = colvar%acid_hyd_shell_param%i_hydrogens(jj)
    4102         320 :             rpj(:) = my_particles(j)%r(1:3)
    4103          80 :             rjk = pbc(rpj, rpk, cell)
    4104         320 :             drjk = SQRT(SUM(rjk**2))
    4105          80 :             rrel = drjk/raoh
    4106          80 :             num = 1.0_dp - rrel**paoh
    4107          80 :             invden = 1.0_dp/(1.0_dp - rrel**qaoh)
    4108          96 :             IF (ABS(1.0_dp - rrel) > 1.0E-6_dp) THEN
    4109          80 :                naoh = naoh + num*invden
    4110             :                fscalar = (-paoh*(rrel**(paoh - 1))*invden &
    4111          80 :                           + num*(invden**2)*qaoh*(rrel**(qaoh - 1)))/(drjk*raoh)
    4112         320 :                dnaoh(1:3, jj, kk) = rjk(1:3)*fscalar
    4113             :             ELSE
    4114             :                !correct limit if rjk --> raoh
    4115           0 :                naoh = naoh + REAL(paoh, dp)/REAL(qaoh, dp)
    4116           0 :                fscalar = REAL(paoh*(paoh - qaoh), dp)/(REAL(2*qaoh, dp)*raoh*drjk)
    4117           0 :                dnaoh(1:3, jj, kk) = rjk(1:3)*fscalar
    4118             :             END IF
    4119             :          END DO
    4120             :       END DO
    4121           8 :       num_cut = 1.0_dp - (naoh/nc)**pcut
    4122           8 :       invden_cut = 1.0_dp/(1.0_dp - (naoh/nc)**qcut)
    4123           8 :       fcut = num_cut*invden_cut
    4124             : 
    4125             :       ! Final value: number of oxygens in 1st shell of hydronium
    4126          24 :       DO ii = 1, n_oxygens_water
    4127          16 :          qloc(ii) = EXP(lambda*M(ii)*noo(ii))
    4128          24 :          qtot = qtot + qloc(ii)
    4129             :       END DO
    4130           8 :       qsol = LOG(qtot)/lambda
    4131           8 :       colvar%ss = fcut*qsol
    4132             : 
    4133             :       ! Derivatives of fcut
    4134             :       dfcut = ((-pcut*(naoh/nc)**(pcut - 1)*invden_cut) &
    4135           8 :                + num_cut*(invden_cut**2)*qcut*(naoh/nc)**(qcut - 1))/nc
    4136           8 :       offsetO = n_oxygens_water
    4137           8 :       offsetH = n_oxygens_water + n_oxygens_acid
    4138          24 :       DO kk = 1, n_oxygens_acid
    4139         104 :          DO jj = 1, n_hydrogens
    4140             :             colvar%dsdr(1:3, offsetO + kk) = colvar%dsdr(1:3, offsetO + kk) &
    4141         320 :                                              + dfcut*dnaoh(1:3, jj, kk)*qsol
    4142             :             colvar%dsdr(1:3, offsetH + jj) = colvar%dsdr(1:3, offsetH + jj) &
    4143         336 :                                              - dfcut*dnaoh(1:3, jj, kk)*qsol
    4144             :          END DO
    4145             :       END DO
    4146             : 
    4147             :       ! Derivatives of qsol
    4148             :       !*** M derivatives
    4149          24 :       DO ii = 1, n_oxygens_water
    4150          16 :          fscalar = fcut*qloc(ii)*dM(ii)*noo(ii)/qtot
    4151         104 :          DO jj = 1, n_hydrogens
    4152             :             colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) &
    4153         320 :                                    + fscalar*dnwoh(1:3, jj, ii)
    4154             :             colvar%dsdr(1:3, offsetH + jj) = colvar%dsdr(1:3, offsetH + jj) &
    4155         336 :                                              - fscalar*dnwoh(1:3, jj, ii)
    4156             :          END DO
    4157             :       END DO
    4158             :       !*** noo derivatives
    4159          24 :       DO ii = 1, n_oxygens_water
    4160          16 :          fscalar = fcut*qloc(ii)*M(ii)/qtot
    4161          88 :          DO kk = 1, n_oxygens_water + n_oxygens_acid
    4162          64 :             IF (ii == kk) CYCLE
    4163         192 :             colvar%dsdr(1:3, ii) = colvar%dsdr(1:3, ii) + fscalar*dnoo(1:3, kk, ii)
    4164         208 :             colvar%dsdr(1:3, kk) = colvar%dsdr(1:3, kk) - fscalar*dnoo(1:3, kk, ii)
    4165             :          END DO
    4166             :       END DO
    4167             : 
    4168          16 :    END SUBROUTINE acid_hyd_shell_colvar
    4169             : 
    4170             : ! **************************************************************************************************
    4171             : !> \brief evaluates the force due (and on) the coordination-chain collective variable
    4172             : !> \param colvar ...
    4173             : !> \param cell ...
    4174             : !> \param subsys ...
    4175             : !> \param particles ...
    4176             : !> \author MI
    4177             : !> \note When the third set of atoms is not defined, this variable is equivalent
    4178             : !>       to the simple coordination number.
    4179             : ! **************************************************************************************************
    4180         514 :    SUBROUTINE coord_colvar(colvar, cell, subsys, particles)
    4181             :       TYPE(colvar_type), POINTER                         :: colvar
    4182             :       TYPE(cell_type), POINTER                           :: cell
    4183             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    4184             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    4185             :          POINTER                                         :: particles
    4186             : 
    4187             :       INTEGER                                            :: i, ii, j, jj, k, kk, n_atoms_from, &
    4188             :                                                             n_atoms_to_a, n_atoms_to_b, p_a, p_b, &
    4189             :                                                             q_a, q_b
    4190             :       REAL(dp) :: dfunc_ij, dfunc_jk, func_ij, func_jk, func_k, inv_n_atoms_from, invden_ij, &
    4191             :          invden_jk, ncoord, num_ij, num_jk, r_0_a, r_0_b, rdist_ij, rdist_jk, rij, rjk
    4192             :       REAL(dp), DIMENSION(3)                             :: ftmp_i, ftmp_j, ftmp_k, ss, xij, xjk, &
    4193             :                                                             xpi, xpj, xpk
    4194             :       TYPE(particle_list_type), POINTER                  :: particles_i
    4195         514 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    4196             : 
    4197             : ! If we defined the coordination number with KINDS then we have still
    4198             : ! to fill few missing informations...
    4199             : 
    4200         514 :       NULLIFY (particles_i)
    4201           0 :       CPASSERT(colvar%type_id == coord_colvar_id)
    4202         514 :       IF (PRESENT(particles)) THEN
    4203          42 :          my_particles => particles
    4204             :       ELSE
    4205         472 :          CPASSERT(PRESENT(subsys))
    4206         472 :          CALL cp_subsys_get(subsys, particles=particles_i)
    4207         472 :          my_particles => particles_i%els
    4208             :       END IF
    4209         514 :       n_atoms_to_a = colvar%coord_param%n_atoms_to
    4210         514 :       n_atoms_to_b = colvar%coord_param%n_atoms_to_b
    4211         514 :       n_atoms_from = colvar%coord_param%n_atoms_from
    4212         514 :       p_a = colvar%coord_param%nncrd
    4213         514 :       q_a = colvar%coord_param%ndcrd
    4214         514 :       r_0_a = colvar%coord_param%r_0
    4215         514 :       p_b = colvar%coord_param%nncrd_b
    4216         514 :       q_b = colvar%coord_param%ndcrd_b
    4217         514 :       r_0_b = colvar%coord_param%r_0_b
    4218             : 
    4219         514 :       ncoord = 0.0_dp
    4220         514 :       inv_n_atoms_from = 1.0_dp/REAL(n_atoms_from, KIND=dp)
    4221        1040 :       DO ii = 1, n_atoms_from
    4222         526 :          i = colvar%coord_param%i_at_from(ii)
    4223         526 :          CALL get_coordinates(colvar, i, xpi, my_particles)
    4224        1862 :          DO jj = 1, n_atoms_to_a
    4225         822 :             j = colvar%coord_param%i_at_to(jj)
    4226         822 :             CALL get_coordinates(colvar, j, xpj, my_particles)
    4227             :             ! define coordination of atom A with itself to be 0. also fixes rij==0 for the force calculation
    4228         822 :             IF (i .EQ. j) CYCLE
    4229       12768 :             ss = MATMUL(cell%h_inv, xpi(:) - xpj(:))
    4230        3192 :             ss = ss - NINT(ss)
    4231       10374 :             xij = MATMUL(cell%hmat, ss)
    4232         798 :             rij = SQRT(xij(1)**2 + xij(2)**2 + xij(3)**2)
    4233         798 :             IF (rij < 1.0e-8_dp) CYCLE
    4234         798 :             rdist_ij = rij/r_0_a
    4235         798 :             IF (ABS(1.0_dp - rdist_ij) > EPSILON(0.0_dp)*1.0E+4_dp) THEN
    4236         798 :                num_ij = (1.0_dp - rdist_ij**p_a)
    4237         798 :                invden_ij = 1.0_dp/(1.0_dp - rdist_ij**q_a)
    4238         798 :                func_ij = num_ij*invden_ij
    4239             :                IF (rij < 1.0E-8_dp) THEN
    4240             :                   ! provide the correct limit of the derivative
    4241             :                   dfunc_ij = 0.0_dp
    4242             :                ELSE
    4243             :                   dfunc_ij = (-p_a*rdist_ij**(p_a - 1)*invden_ij &
    4244         798 :                               + num_ij*(invden_ij)**2*q_a*rdist_ij**(q_a - 1))/(rij*r_0_a)
    4245             :                END IF
    4246             :             ELSE
    4247             :                ! Provide the correct limit for function value and derivative
    4248           0 :                func_ij = REAL(p_a, KIND=dp)/REAL(q_a, KIND=dp)
    4249           0 :                dfunc_ij = REAL(p_a, KIND=dp)*REAL((-q_a + p_a), KIND=dp)/(REAL(2*q_a, KIND=dp)*r_0_a)
    4250             :             END IF
    4251         798 :             IF (n_atoms_to_b /= 0) THEN
    4252             :                func_k = 0.0_dp
    4253          88 :                DO kk = 1, n_atoms_to_b
    4254          44 :                   k = colvar%coord_param%i_at_to_b(kk)
    4255          44 :                   IF (k .EQ. j) CYCLE
    4256          44 :                   CALL get_coordinates(colvar, k, xpk, my_particles)
    4257         704 :                   ss = MATMUL(cell%h_inv, xpj(:) - xpk(:))
    4258         176 :                   ss = ss - NINT(ss)
    4259         572 :                   xjk = MATMUL(cell%hmat, ss)
    4260          44 :                   rjk = SQRT(xjk(1)**2 + xjk(2)**2 + xjk(3)**2)
    4261          44 :                   IF (rjk < 1.0e-8_dp) CYCLE
    4262          44 :                   rdist_jk = rjk/r_0_b
    4263          44 :                   IF (ABS(1.0_dp - rdist_jk) > EPSILON(0.0_dp)*1.0E+4_dp) THEN
    4264          44 :                      num_jk = (1.0_dp - rdist_jk**p_b)
    4265          44 :                      invden_jk = 1.0_dp/(1.0_dp - rdist_jk**q_b)
    4266          44 :                      func_jk = num_jk*invden_jk
    4267             :                      IF (rjk < 1.0E-8_dp) THEN
    4268             :                         ! provide the correct limit of the derivative
    4269             :                         dfunc_jk = 0.0_dp
    4270             :                      ELSE
    4271             :                         dfunc_jk = (-p_b*rdist_jk**(p_b - 1)*invden_jk &
    4272          44 :                                     + num_jk*(invden_jk)**2*q_b*rdist_jk**(q_b - 1))/(rjk*r_0_b)
    4273             :                      END IF
    4274             :                   ELSE
    4275             :                      ! Provide the correct limit for function value and derivative
    4276           0 :                      func_jk = REAL(p_b, KIND=dp)/REAL(q_b, KIND=dp)
    4277           0 :                      dfunc_jk = REAL(p_b, KIND=dp)*REAL((-q_b + p_b), KIND=dp)/(REAL(2*q_b, KIND=dp)*r_0_b)
    4278             :                   END IF
    4279          44 :                   func_k = func_k + func_jk
    4280         176 :                   ftmp_k = -func_ij*dfunc_jk*xjk
    4281          44 :                   CALL put_derivative(colvar, n_atoms_from + n_atoms_to_a + kk, ftmp_k)
    4282             : 
    4283         176 :                   ftmp_j = -dfunc_ij*xij*func_jk + func_ij*dfunc_jk*xjk
    4284          88 :                   CALL put_derivative(colvar, n_atoms_from + jj, ftmp_j)
    4285             :                END DO
    4286             :             ELSE
    4287        3016 :                func_k = 1.0_dp
    4288        3016 :                dfunc_jk = 0.0_dp
    4289        3016 :                ftmp_j = -dfunc_ij*xij
    4290         754 :                CALL put_derivative(colvar, n_atoms_from + jj, ftmp_j)
    4291             :             END IF
    4292         798 :             ncoord = ncoord + func_ij*func_k
    4293        3192 :             ftmp_i = dfunc_ij*xij*func_k
    4294        1324 :             CALL put_derivative(colvar, ii, ftmp_i)
    4295             :          END DO
    4296             :       END DO
    4297         514 :       colvar%ss = ncoord*inv_n_atoms_from
    4298        5986 :       colvar%dsdr(:, :) = colvar%dsdr(:, :)*inv_n_atoms_from
    4299         514 :    END SUBROUTINE coord_colvar
    4300             : 
    4301             : ! **************************************************************************************************
    4302             : !> \brief ...
    4303             : !> \param colvar ...
    4304             : !> \param cell ...
    4305             : !> \param subsys ...
    4306             : !> \param particles ...
    4307             : ! **************************************************************************************************
    4308           0 :    SUBROUTINE mindist_colvar(colvar, cell, subsys, particles)
    4309             : 
    4310             :       TYPE(colvar_type), POINTER                         :: colvar
    4311             :       TYPE(cell_type), POINTER                           :: cell
    4312             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    4313             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    4314             :          POINTER                                         :: particles
    4315             : 
    4316             :       INTEGER                                            :: i, ii, j, jj, n_coord_from, n_coord_to, &
    4317             :                                                             n_dist_from, p, q
    4318             :       REAL(dp) :: den_n, den_Q, fscalar, ftemp_i(3), inv_den_n, inv_den_Q, lambda, num_n, num_Q, &
    4319             :          Qfunc, r12, r_cut, rfact, rij(3), rpi(3), rpj(3)
    4320           0 :       REAL(dp), DIMENSION(:), POINTER                    :: dqfunc_dnL, expnL, nLcoord, sum_rij
    4321           0 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: dnLcoord, dqfunc_dr
    4322             :       TYPE(particle_list_type), POINTER                  :: particles_i
    4323           0 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    4324             : 
    4325             : ! If we defined the coordination number with KINDS then we have still
    4326             : ! to fill few missing informations...
    4327             : 
    4328           0 :       NULLIFY (particles_i)
    4329           0 :       CPASSERT(colvar%type_id == mindist_colvar_id)
    4330           0 :       IF (PRESENT(particles)) THEN
    4331           0 :          my_particles => particles
    4332             :       ELSE
    4333           0 :          CPASSERT(PRESENT(subsys))
    4334           0 :          CALL cp_subsys_get(subsys, particles=particles_i)
    4335           0 :          my_particles => particles_i%els
    4336             :       END IF
    4337             : 
    4338           0 :       n_dist_from = colvar%mindist_param%n_dist_from
    4339           0 :       n_coord_from = colvar%mindist_param%n_coord_from
    4340           0 :       n_coord_to = colvar%mindist_param%n_coord_to
    4341           0 :       p = colvar%mindist_param%p_exp
    4342           0 :       q = colvar%mindist_param%q_exp
    4343           0 :       r_cut = colvar%mindist_param%r_cut
    4344           0 :       lambda = colvar%mindist_param%lambda
    4345             : 
    4346           0 :       NULLIFY (nLcoord, dnLcoord, dqfunc_dr, dqfunc_dnL, expnL, sum_rij)
    4347           0 :       ALLOCATE (nLcoord(n_coord_from))
    4348           0 :       ALLOCATE (dnLcoord(3, n_coord_from, n_coord_to))
    4349           0 :       ALLOCATE (expnL(n_coord_from))
    4350           0 :       ALLOCATE (sum_rij(n_coord_from))
    4351           0 :       ALLOCATE (dqfunc_dr(3, n_dist_from, n_coord_from))
    4352           0 :       ALLOCATE (dqfunc_dnL(n_coord_from))
    4353             : 
    4354             :       ! coordination numbers
    4355           0 :       nLcoord = 0.0_dp
    4356           0 :       dnLcoord = 0.0_dp
    4357           0 :       expnL = 0.0_dp
    4358           0 :       den_Q = 0.0_dp
    4359           0 :       DO i = 1, n_coord_from
    4360           0 :          ii = colvar%mindist_param%i_coord_from(i)
    4361           0 :          rpi = my_particles(ii)%r(1:3)
    4362           0 :          DO j = 1, n_coord_to
    4363           0 :             jj = colvar%mindist_param%i_coord_to(j)
    4364           0 :             rpj = my_particles(jj)%r(1:3)
    4365           0 :             rij = pbc(rpj, rpi, cell)
    4366           0 :             r12 = SQRT(rij(1)*rij(1) + rij(2)*rij(2) + rij(3)*rij(3))
    4367           0 :             rfact = r12/r_cut
    4368           0 :             num_n = 1.0_dp - rfact**p
    4369           0 :             den_n = 1.0_dp - rfact**q
    4370           0 :             inv_den_n = 1.0_dp/den_n
    4371           0 :             IF (ABS(inv_den_n) < 1.e-10_dp) THEN
    4372           0 :                inv_den_n = 1.e-10_dp
    4373           0 :                num_n = ABS(num_n)
    4374             :             END IF
    4375             : 
    4376           0 :             fscalar = (-p*rfact**(p - 1) + num_n*q*rfact**(q - 1)*inv_den_n)*inv_den_n/(r_cut*r12)
    4377             : 
    4378           0 :             dnLcoord(1, i, j) = rij(1)*fscalar
    4379           0 :             dnLcoord(2, i, j) = rij(2)*fscalar
    4380           0 :             dnLcoord(3, i, j) = rij(3)*fscalar
    4381             : 
    4382           0 :             nLcoord(i) = nLcoord(i) + num_n*inv_den_n
    4383             :          END DO
    4384           0 :          expnL(i) = EXP(lambda*nLcoord(i))
    4385           0 :          den_Q = den_Q + expnL(i)
    4386             :       END DO
    4387           0 :       inv_den_Q = 1.0_dp/den_Q
    4388             : 
    4389           0 :       qfunc = 0.0_dp
    4390           0 :       dqfunc_dr = 0.0_dp
    4391           0 :       dqfunc_dnL = 0.0_dp
    4392           0 :       num_Q = 0.0_dp
    4393           0 :       sum_rij = 0.0_dp
    4394           0 :       DO i = 1, n_dist_from
    4395           0 :          ii = colvar%mindist_param%i_dist_from(i)
    4396           0 :          rpi = my_particles(ii)%r(1:3)
    4397           0 :          DO j = 1, n_coord_from
    4398           0 :             jj = colvar%mindist_param%i_coord_from(j)
    4399           0 :             rpj = my_particles(jj)%r(1:3)
    4400           0 :             rij = pbc(rpj, rpi, cell)
    4401           0 :             r12 = SQRT(rij(1)*rij(1) + rij(2)*rij(2) + rij(3)*rij(3))
    4402             : 
    4403           0 :             num_Q = num_Q + r12*expnL(j)
    4404             : 
    4405           0 :             sum_rij(j) = sum_rij(j) + r12
    4406           0 :             dqfunc_dr(1, i, j) = expnL(j)*rij(1)/r12
    4407           0 :             dqfunc_dr(2, i, j) = expnL(j)*rij(2)/r12
    4408           0 :             dqfunc_dr(3, i, j) = expnL(j)*rij(3)/r12
    4409             : 
    4410             :          END DO
    4411             : 
    4412             :       END DO
    4413             : 
    4414             :       ! Function and derivatives
    4415           0 :       qfunc = num_Q*inv_den_Q
    4416           0 :       dqfunc_dr = dqfunc_dr*inv_den_Q
    4417           0 :       colvar%ss = qfunc
    4418             : 
    4419           0 :       DO i = 1, n_coord_from
    4420           0 :          dqfunc_dnL(i) = lambda*expnL(i)*inv_den_Q*(sum_rij(i) - num_Q*inv_den_Q)
    4421             :       END DO
    4422             : 
    4423             :       !Compute Forces
    4424           0 :       DO i = 1, n_dist_from
    4425           0 :          DO j = 1, n_coord_from
    4426           0 :             ftemp_i(1) = dqfunc_dr(1, i, j)
    4427           0 :             ftemp_i(2) = dqfunc_dr(2, i, j)
    4428           0 :             ftemp_i(3) = dqfunc_dr(3, i, j)
    4429             : 
    4430           0 :             CALL put_derivative(colvar, i, ftemp_i)
    4431           0 :             CALL put_derivative(colvar, j + n_dist_from, -ftemp_i)
    4432             : 
    4433             :          END DO
    4434             :       END DO
    4435           0 :       DO i = 1, n_coord_from
    4436           0 :          DO j = 1, n_coord_to
    4437           0 :             ftemp_i(1) = dqfunc_dnL(i)*dnLcoord(1, i, j)
    4438           0 :             ftemp_i(2) = dqfunc_dnL(i)*dnLcoord(2, i, j)
    4439           0 :             ftemp_i(3) = dqfunc_dnL(i)*dnLcoord(3, i, j)
    4440             : 
    4441           0 :             CALL put_derivative(colvar, i + n_dist_from, ftemp_i)
    4442           0 :             CALL put_derivative(colvar, j + n_dist_from + n_coord_from, -ftemp_i)
    4443             : 
    4444             :          END DO
    4445             :       END DO
    4446             : 
    4447           0 :       DEALLOCATE (nLcoord)
    4448           0 :       DEALLOCATE (dnLcoord)
    4449           0 :       DEALLOCATE (expnL)
    4450           0 :       DEALLOCATE (dqfunc_dr)
    4451           0 :       DEALLOCATE (sum_rij)
    4452           0 :       DEALLOCATE (dqfunc_dnL)
    4453             : 
    4454           0 :    END SUBROUTINE mindist_colvar
    4455             : 
    4456             : ! **************************************************************************************************
    4457             : !> \brief  evaluates function and forces due to a combination of COLVARs
    4458             : !> \param colvar ...
    4459             : !> \param cell ...
    4460             : !> \param subsys ...
    4461             : !> \param particles ...
    4462             : !> \author Teodoro Laino [tlaino] - 12.2008
    4463             : ! **************************************************************************************************
    4464          89 :    SUBROUTINE combine_colvar(colvar, cell, subsys, particles)
    4465             :       TYPE(colvar_type), POINTER                         :: colvar
    4466             :       TYPE(cell_type), POINTER                           :: cell
    4467             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    4468             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    4469             :          POINTER                                         :: particles
    4470             : 
    4471             :       CHARACTER(LEN=default_string_length)               :: def_error, this_error
    4472             :       CHARACTER(LEN=default_string_length), &
    4473          89 :          ALLOCATABLE, DIMENSION(:)                       :: my_par
    4474             :       INTEGER                                            :: i, ii, j, ncolv, ndim
    4475             :       REAL(dp)                                           :: err
    4476          89 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: dss_vals, my_val, ss_vals
    4477          89 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: fi
    4478             :       TYPE(particle_list_type), POINTER                  :: particles_i
    4479          89 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    4480             : 
    4481           0 :       CPASSERT(colvar%type_id == combine_colvar_id)
    4482          89 :       IF (PRESENT(particles)) THEN
    4483          23 :          my_particles => particles
    4484             :       ELSE
    4485          66 :          CPASSERT(PRESENT(subsys))
    4486          66 :          CALL cp_subsys_get(subsys, particles=particles_i)
    4487          66 :          my_particles => particles_i%els
    4488             :       END IF
    4489             : 
    4490          89 :       ncolv = SIZE(colvar%combine_cvs_param%colvar_p)
    4491         267 :       ALLOCATE (ss_vals(ncolv))
    4492         178 :       ALLOCATE (dss_vals(ncolv))
    4493             : 
    4494             :       ! Evaluate the individual COLVARs
    4495         267 :       DO i = 1, ncolv
    4496         178 :          CALL colvar_recursive_eval(colvar%combine_cvs_param%colvar_p(i)%colvar, cell, my_particles)
    4497         267 :          ss_vals(i) = colvar%combine_cvs_param%colvar_p(i)%colvar%ss
    4498             :       END DO
    4499             : 
    4500             :       ! Evaluate the combination of the COLVARs
    4501          89 :       CALL initf(1)
    4502             :       ndim = SIZE(colvar%combine_cvs_param%c_parameters) + &
    4503          89 :              SIZE(colvar%combine_cvs_param%variables)
    4504         267 :       ALLOCATE (my_par(ndim))
    4505         267 :       my_par(1:SIZE(colvar%combine_cvs_param%variables)) = colvar%combine_cvs_param%variables
    4506         134 :       my_par(SIZE(colvar%combine_cvs_param%variables) + 1:) = colvar%combine_cvs_param%c_parameters
    4507         267 :       ALLOCATE (my_val(ndim))
    4508         267 :       my_val(1:SIZE(colvar%combine_cvs_param%variables)) = ss_vals
    4509         134 :       my_val(SIZE(colvar%combine_cvs_param%variables) + 1:) = colvar%combine_cvs_param%v_parameters
    4510          89 :       CALL parsef(1, TRIM(colvar%combine_cvs_param%function), my_par)
    4511          89 :       colvar%ss = evalf(1, my_val)
    4512         267 :       DO i = 1, ncolv
    4513         178 :          dss_vals(i) = evalfd(1, i, my_val, colvar%combine_cvs_param%dx, err)
    4514         267 :          IF ((ABS(err) > colvar%combine_cvs_param%lerr)) THEN
    4515          22 :             WRITE (this_error, "(A,G12.6,A)") "(", err, ")"
    4516          22 :             WRITE (def_error, "(A,G12.6,A)") "(", colvar%combine_cvs_param%lerr, ")"
    4517          22 :             CALL compress(this_error, .TRUE.)
    4518          22 :             CALL compress(def_error, .TRUE.)
    4519             :             CALL cp_warn(__LOCATION__, &
    4520             :                          'ASSERTION (cond) failed at line '//cp_to_string(__LINE__)// &
    4521             :                          ' Error '//TRIM(this_error)//' in computing numerical derivatives larger then'// &
    4522          22 :                          TRIM(def_error)//' . ')
    4523             :          END IF
    4524             :       END DO
    4525          89 :       DEALLOCATE (my_val)
    4526          89 :       DEALLOCATE (my_par)
    4527          89 :       CALL finalizef()
    4528             : 
    4529             :       ! Evaluate forces
    4530         267 :       ALLOCATE (fi(3, colvar%n_atom_s))
    4531          89 :       ii = 0
    4532         267 :       DO i = 1, ncolv
    4533        1151 :          DO j = 1, colvar%combine_cvs_param%colvar_p(i)%colvar%n_atom_s
    4534         884 :             ii = ii + 1
    4535        3714 :             fi(:, ii) = colvar%combine_cvs_param%colvar_p(i)%colvar%dsdr(:, j)*dss_vals(i)
    4536             :          END DO
    4537             :       END DO
    4538             : 
    4539         973 :       DO i = 1, colvar%n_atom_s
    4540         973 :          CALL put_derivative(colvar, i, fi(:, i))
    4541             :       END DO
    4542             : 
    4543          89 :       DEALLOCATE (fi)
    4544          89 :       DEALLOCATE (ss_vals)
    4545          89 :       DEALLOCATE (dss_vals)
    4546         178 :    END SUBROUTINE combine_colvar
    4547             : 
    4548             : ! **************************************************************************************************
    4549             : !> \brief evaluates the force due (and on) reaction path collective variable
    4550             : !>             ss(R) = [\sum_i i*dt exp{-\lambda \sum_a(S_a(R)-f_a(i))^2}]/
    4551             : !>                     [\sum_i exp{-\lambda \sum_a(S_a(R)-f_a(i))^2}]
    4552             : !> \param colvar ...
    4553             : !> \param cell ...
    4554             : !> \param subsys ...
    4555             : !> \param particles ...
    4556             : !> \par History
    4557             : !>      extended MI 01.2010
    4558             : !> \author fschiff
    4559             : !> \note the system is still able to move in the space spanned by the CV
    4560             : !>       perpendicular to the path
    4561             : ! **************************************************************************************************
    4562         256 :    SUBROUTINE reaction_path_colvar(colvar, cell, subsys, particles)
    4563             :       TYPE(colvar_type), POINTER                         :: colvar
    4564             :       TYPE(cell_type), POINTER                           :: cell
    4565             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    4566             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    4567             :          POINTER                                         :: particles
    4568             : 
    4569             :       TYPE(particle_list_type), POINTER                  :: particles_i
    4570         256 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    4571             : 
    4572           0 :       CPASSERT(colvar%type_id == reaction_path_colvar_id)
    4573         256 :       IF (PRESENT(particles)) THEN
    4574           8 :          my_particles => particles
    4575             :       ELSE
    4576         248 :          CPASSERT(PRESENT(subsys))
    4577         248 :          CALL cp_subsys_get(subsys, particles=particles_i)
    4578         248 :          my_particles => particles_i%els
    4579             :       END IF
    4580             : 
    4581         256 :       IF (colvar%reaction_path_param%dist_rmsd) THEN
    4582         204 :          CALL rpath_dist_rmsd(colvar, my_particles)
    4583          52 :       ELSEIF (colvar%reaction_path_param%rmsd) THEN
    4584           0 :          CALL rpath_rmsd(colvar, my_particles)
    4585             :       ELSE
    4586          52 :          CALL rpath_colvar(colvar, cell, my_particles)
    4587             :       END IF
    4588             : 
    4589         256 :    END SUBROUTINE reaction_path_colvar
    4590             : 
    4591             : ! **************************************************************************************************
    4592             : !> \brief  position along the path calculated using selected colvars
    4593             : !>         as compared to functions describing the variation of these same colvars
    4594             : !>         along the path given as reference
    4595             : !> \param colvar ...
    4596             : !> \param cell ...
    4597             : !> \param particles ...
    4598             : !> \author fschiff
    4599             : ! **************************************************************************************************
    4600          52 :    SUBROUTINE rpath_colvar(colvar, cell, particles)
    4601             :       TYPE(colvar_type), POINTER                         :: colvar
    4602             :       TYPE(cell_type), POINTER                           :: cell
    4603             :       TYPE(particle_type), DIMENSION(:), POINTER         :: particles
    4604             : 
    4605             :       INTEGER                                            :: i, iend, ii, istart, j, k, ncolv, nconf
    4606             :       REAL(dp)                                           :: lambda, step_size
    4607          52 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: s1, ss_vals
    4608          52 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: ds1, f_vals, fi, s1v
    4609          52 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: ds1v
    4610             : 
    4611          52 :       istart = colvar%reaction_path_param%function_bounds(1)
    4612          52 :       iend = colvar%reaction_path_param%function_bounds(2)
    4613             : 
    4614          52 :       nconf = colvar%reaction_path_param%nr_frames
    4615          52 :       step_size = colvar%reaction_path_param%step_size
    4616          52 :       ncolv = colvar%reaction_path_param%n_components
    4617          52 :       lambda = colvar%reaction_path_param%lambda
    4618         208 :       ALLOCATE (f_vals(ncolv, istart:iend))
    4619      608608 :       f_vals(:, :) = colvar%reaction_path_param%f_vals
    4620         156 :       ALLOCATE (ss_vals(ncolv))
    4621             : 
    4622         156 :       DO i = 1, ncolv
    4623         104 :          CALL colvar_recursive_eval(colvar%reaction_path_param%colvar_p(i)%colvar, cell, particles)
    4624         156 :          ss_vals(i) = colvar%reaction_path_param%colvar_p(i)%colvar%ss
    4625             :       END DO
    4626             : 
    4627         156 :       ALLOCATE (s1v(2, istart:iend))
    4628         208 :       ALLOCATE (ds1v(ncolv, 2, istart:iend))
    4629             : 
    4630          52 :       ALLOCATE (s1(2))
    4631         156 :       ALLOCATE (ds1(ncolv, 2))
    4632             : 
    4633      202904 :       DO k = istart, iend
    4634      608556 :          s1v(1, k) = REAL(k, kind=dp)*step_size*EXP(-lambda*DOT_PRODUCT(ss_vals(:) - f_vals(:, k), ss_vals(:) - f_vals(:, k)))
    4635      608556 :          s1v(2, k) = EXP(-lambda*DOT_PRODUCT(ss_vals(:) - f_vals(:, k), ss_vals(:) - f_vals(:, k)))
    4636      608608 :          DO j = 1, ncolv
    4637      405704 :             ds1v(j, 1, k) = f_vals(j, k)*s1v(1, k)
    4638      608556 :             ds1v(j, 2, k) = f_vals(j, k)*s1v(2, k)
    4639             :          END DO
    4640             :       END DO
    4641         156 :       DO i = 1, 2
    4642         104 :          s1(i) = accurate_sum(s1v(i, :))
    4643         364 :          DO j = 1, ncolv
    4644         312 :             ds1(j, i) = accurate_sum(ds1v(j, i, :))
    4645             :          END DO
    4646             :       END DO
    4647             : 
    4648          52 :       colvar%ss = s1(1)/s1(2)/REAL(nconf - 1, dp)
    4649             : 
    4650         156 :       ALLOCATE (fi(3, colvar%n_atom_s))
    4651             : 
    4652          52 :       ii = 0
    4653         156 :       DO i = 1, ncolv
    4654         364 :          DO j = 1, colvar%reaction_path_param%colvar_p(i)%colvar%n_atom_s
    4655         208 :             ii = ii + 1
    4656             :             fi(:, ii) = colvar%reaction_path_param%colvar_p(i)%colvar%dsdr(:, j)*lambda* &
    4657         936 :                         (ds1(i, 1)/s1(2)/REAL(nconf - 1, dp) - colvar%ss*ds1(i, 2)/s1(2))*2.0_dp
    4658             :          END DO
    4659             :       END DO
    4660             : 
    4661         260 :       DO i = 1, colvar%n_atom_s
    4662         260 :          CALL put_derivative(colvar, i, fi(:, i))
    4663             :       END DO
    4664             : 
    4665          52 :       DEALLOCATE (fi)
    4666          52 :       DEALLOCATE (f_vals)
    4667          52 :       DEALLOCATE (ss_vals)
    4668          52 :       DEALLOCATE (s1v)
    4669          52 :       DEALLOCATE (ds1v)
    4670          52 :       DEALLOCATE (s1)
    4671          52 :       DEALLOCATE (ds1)
    4672             : 
    4673          52 :    END SUBROUTINE rpath_colvar
    4674             : 
    4675             : ! **************************************************************************************************
    4676             : !> \brief  position along the path calculated from the positions of a selected list of
    4677             : !>         atoms as compared to the same positions in reference
    4678             : !>         configurations belonging to the given path.
    4679             : !> \param colvar ...
    4680             : !> \param particles ...
    4681             : !> \date  01.2010
    4682             : !> \author MI
    4683             : ! **************************************************************************************************
    4684         204 :    SUBROUTINE rpath_dist_rmsd(colvar, particles)
    4685             :       TYPE(colvar_type), POINTER                         :: colvar
    4686             :       TYPE(particle_type), DIMENSION(:), POINTER         :: particles
    4687             : 
    4688             :       INTEGER                                            :: i, iat, ii, ik, natom, nconf, rmsd_atom
    4689         204 :       INTEGER, DIMENSION(:), POINTER                     :: iatom
    4690             :       REAL(dp)                                           :: lambda, my_rmsd, s1(2), sum_exp
    4691         204 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: r, r0, vec_dif
    4692         204 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: dvec_dif, fi, riat, s1v
    4693         204 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: ds1
    4694         204 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :, :)       :: ds1v
    4695         204 :       REAL(dp), DIMENSION(:, :), POINTER                 :: path_conf
    4696             : 
    4697         204 :       nconf = colvar%reaction_path_param%nr_frames
    4698         204 :       rmsd_atom = colvar%reaction_path_param%n_components
    4699         204 :       lambda = colvar%reaction_path_param%lambda
    4700         204 :       path_conf => colvar%reaction_path_param%r_ref
    4701         204 :       iatom => colvar%reaction_path_param%i_rmsd
    4702             : 
    4703         204 :       natom = SIZE(particles)
    4704             : 
    4705         612 :       ALLOCATE (r0(3*natom))
    4706         408 :       ALLOCATE (r(3*natom))
    4707         612 :       ALLOCATE (riat(3, rmsd_atom))
    4708         612 :       ALLOCATE (vec_dif(rmsd_atom))
    4709         408 :       ALLOCATE (dvec_dif(3, rmsd_atom))
    4710         612 :       ALLOCATE (s1v(2, nconf))
    4711        1020 :       ALLOCATE (ds1v(3, rmsd_atom, 2, nconf))
    4712         612 :       ALLOCATE (ds1(3, rmsd_atom, 2))
    4713        3672 :       DO i = 1, natom
    4714        3468 :          ii = (i - 1)*3
    4715        3468 :          r0(ii + 1) = particles(i)%r(1)
    4716        3468 :          r0(ii + 2) = particles(i)%r(2)
    4717        3672 :          r0(ii + 3) = particles(i)%r(3)
    4718             :       END DO
    4719             : 
    4720        2040 :       DO iat = 1, rmsd_atom
    4721        1836 :          ii = iatom(iat)
    4722        7548 :          riat(:, iat) = particles(ii)%r
    4723             :       END DO
    4724             : 
    4725        1224 :       DO ik = 1, nconf
    4726       18360 :          DO i = 1, natom
    4727       17340 :             ii = (i - 1)*3
    4728       17340 :             r(ii + 1) = path_conf(ii + 1, ik)
    4729       17340 :             r(ii + 2) = path_conf(ii + 2, ik)
    4730       18360 :             r(ii + 3) = path_conf(ii + 3, ik)
    4731             :          END DO
    4732             : 
    4733        1020 :          CALL rmsd3(particles, r, r0, output_unit=-1, my_val=my_rmsd, rotate=.TRUE.)
    4734             : 
    4735        1020 :          sum_exp = 0.0_dp
    4736       10200 :          DO iat = 1, rmsd_atom
    4737        9180 :             i = iatom(iat)
    4738        9180 :             ii = (i - 1)*3
    4739             :             vec_dif(iat) = (riat(1, iat) - r(ii + 1))**2 + (riat(2, iat) - r(ii + 2))**2 &
    4740        9180 :                            + (riat(3, iat) - r(ii + 3))**2
    4741       10200 :             sum_exp = sum_exp + vec_dif(iat)
    4742             :          END DO
    4743             : 
    4744        1020 :          s1v(1, ik) = REAL(ik - 1, dp)*EXP(-lambda*sum_exp)
    4745        1020 :          s1v(2, ik) = EXP(-lambda*sum_exp)
    4746       10404 :          DO iat = 1, rmsd_atom
    4747        9180 :             i = iatom(iat)
    4748        9180 :             ii = (i - 1)*3
    4749        9180 :             ds1v(1, iat, 1, ik) = r(ii + 1)*s1v(1, ik)
    4750        9180 :             ds1v(1, iat, 2, ik) = r(ii + 1)*s1v(2, ik)
    4751        9180 :             ds1v(2, iat, 1, ik) = r(ii + 2)*s1v(1, ik)
    4752        9180 :             ds1v(2, iat, 2, ik) = r(ii + 2)*s1v(2, ik)
    4753        9180 :             ds1v(3, iat, 1, ik) = r(ii + 3)*s1v(1, ik)
    4754       10200 :             ds1v(3, iat, 2, ik) = r(ii + 3)*s1v(2, ik)
    4755             :          END DO
    4756             : 
    4757             :       END DO
    4758         204 :       s1(1) = accurate_sum(s1v(1, :))
    4759         204 :       s1(2) = accurate_sum(s1v(2, :))
    4760         612 :       DO i = 1, 2
    4761        4284 :          DO iat = 1, rmsd_atom
    4762        3672 :             ds1(1, iat, i) = accurate_sum(ds1v(1, iat, i, :))
    4763        3672 :             ds1(2, iat, i) = accurate_sum(ds1v(2, iat, i, :))
    4764        4080 :             ds1(3, iat, i) = accurate_sum(ds1v(3, iat, i, :))
    4765             :          END DO
    4766             :       END DO
    4767             : 
    4768         204 :       colvar%ss = s1(1)/s1(2)/REAL(nconf - 1, dp)
    4769             : 
    4770         408 :       ALLOCATE (fi(3, rmsd_atom))
    4771             : 
    4772        2040 :       DO iat = 1, rmsd_atom
    4773        1836 :          fi(1, iat) = 2.0_dp*lambda/s1(2)/REAL(nconf - 1, dp)*(ds1(1, iat, 1) - ds1(1, iat, 2)*s1(1)/s1(2))
    4774        1836 :          fi(2, iat) = 2.0_dp*lambda/s1(2)/REAL(nconf - 1, dp)*(ds1(2, iat, 1) - ds1(2, iat, 2)*s1(1)/s1(2))
    4775        1836 :          fi(3, iat) = 2.0_dp*lambda/s1(2)/REAL(nconf - 1, dp)*(ds1(3, iat, 1) - ds1(3, iat, 2)*s1(1)/s1(2))
    4776        2040 :          CALL put_derivative(colvar, iat, fi(:, iat))
    4777             :       END DO
    4778             : 
    4779         204 :       DEALLOCATE (fi)
    4780         204 :       DEALLOCATE (r0)
    4781         204 :       DEALLOCATE (r)
    4782         204 :       DEALLOCATE (riat)
    4783         204 :       DEALLOCATE (vec_dif)
    4784         204 :       DEALLOCATE (dvec_dif)
    4785         204 :       DEALLOCATE (s1v)
    4786         204 :       DEALLOCATE (ds1v)
    4787         204 :       DEALLOCATE (ds1)
    4788             : 
    4789         204 :    END SUBROUTINE rpath_dist_rmsd
    4790             : 
    4791             : ! **************************************************************************************************
    4792             : !> \brief ...
    4793             : !> \param colvar ...
    4794             : !> \param particles ...
    4795             : ! **************************************************************************************************
    4796           0 :    SUBROUTINE rpath_rmsd(colvar, particles)
    4797             :       TYPE(colvar_type), POINTER                         :: colvar
    4798             :       TYPE(particle_type), DIMENSION(:), POINTER         :: particles
    4799             : 
    4800             :       INTEGER                                            :: i, iat, ii, ik, natom, nconf, rmsd_atom
    4801           0 :       INTEGER, DIMENSION(:), POINTER                     :: iatom
    4802             :       REAL(dp)                                           :: lambda, my_rmsd, s1(2)
    4803             :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: r, r0
    4804           0 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: fi, riat, s1v
    4805           0 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: ds1
    4806           0 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :, :)       :: ds1v
    4807           0 :       REAL(dp), DIMENSION(:, :), POINTER                 :: path_conf
    4808           0 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: weight
    4809             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: drmsd
    4810             : 
    4811           0 :       nconf = colvar%reaction_path_param%nr_frames
    4812           0 :       rmsd_atom = colvar%reaction_path_param%n_components
    4813           0 :       lambda = colvar%reaction_path_param%lambda
    4814           0 :       path_conf => colvar%reaction_path_param%r_ref
    4815           0 :       iatom => colvar%reaction_path_param%i_rmsd
    4816             : 
    4817           0 :       natom = SIZE(particles)
    4818             : 
    4819           0 :       ALLOCATE (r0(3*natom))
    4820           0 :       ALLOCATE (r(3*natom))
    4821           0 :       ALLOCATE (riat(3, rmsd_atom))
    4822           0 :       ALLOCATE (s1v(2, nconf))
    4823           0 :       ALLOCATE (ds1v(3, rmsd_atom, 2, nconf))
    4824           0 :       ALLOCATE (ds1(3, rmsd_atom, 2))
    4825           0 :       ALLOCATE (drmsd(3, natom))
    4826           0 :       drmsd = 0.0_dp
    4827           0 :       ALLOCATE (weight(natom))
    4828             : 
    4829           0 :       DO i = 1, natom
    4830           0 :          ii = (i - 1)*3
    4831           0 :          r0(ii + 1) = particles(i)%r(1)
    4832           0 :          r0(ii + 2) = particles(i)%r(2)
    4833           0 :          r0(ii + 3) = particles(i)%r(3)
    4834             :       END DO
    4835             : 
    4836           0 :       DO iat = 1, rmsd_atom
    4837           0 :          ii = iatom(iat)
    4838           0 :          riat(:, iat) = particles(ii)%r
    4839             :       END DO
    4840             : 
    4841             : ! set weights of atoms in the rmsd list
    4842           0 :       weight = 0.0_dp
    4843           0 :       DO iat = 1, rmsd_atom
    4844           0 :          i = iatom(iat)
    4845           0 :          weight(i) = 1.0_dp
    4846             :       END DO
    4847             : 
    4848           0 :       DO ik = 1, nconf
    4849           0 :          DO i = 1, natom
    4850           0 :             ii = (i - 1)*3
    4851           0 :             r(ii + 1) = path_conf(ii + 1, ik)
    4852           0 :             r(ii + 2) = path_conf(ii + 2, ik)
    4853           0 :             r(ii + 3) = path_conf(ii + 3, ik)
    4854             :          END DO
    4855             : 
    4856             :          CALL rmsd3(particles, r0, r, output_unit=-1, weights=weight, my_val=my_rmsd, &
    4857           0 :                     rotate=.FALSE., drmsd3=drmsd)
    4858             : 
    4859           0 :          s1v(1, ik) = REAL(ik - 1, dp)*EXP(-lambda*my_rmsd)
    4860           0 :          s1v(2, ik) = EXP(-lambda*my_rmsd)
    4861           0 :          DO iat = 1, rmsd_atom
    4862           0 :             i = iatom(iat)
    4863           0 :             ds1v(1, iat, 1, ik) = drmsd(1, i)*s1v(1, ik)
    4864           0 :             ds1v(1, iat, 2, ik) = drmsd(1, i)*s1v(2, ik)
    4865           0 :             ds1v(2, iat, 1, ik) = drmsd(2, i)*s1v(1, ik)
    4866           0 :             ds1v(2, iat, 2, ik) = drmsd(2, i)*s1v(2, ik)
    4867           0 :             ds1v(3, iat, 1, ik) = drmsd(3, i)*s1v(1, ik)
    4868           0 :             ds1v(3, iat, 2, ik) = drmsd(3, i)*s1v(2, ik)
    4869             :          END DO
    4870             :       END DO ! ik
    4871             : 
    4872           0 :       s1(1) = accurate_sum(s1v(1, :))
    4873           0 :       s1(2) = accurate_sum(s1v(2, :))
    4874           0 :       DO i = 1, 2
    4875           0 :          DO iat = 1, rmsd_atom
    4876           0 :             ds1(1, iat, i) = accurate_sum(ds1v(1, iat, i, :))
    4877           0 :             ds1(2, iat, i) = accurate_sum(ds1v(2, iat, i, :))
    4878           0 :             ds1(3, iat, i) = accurate_sum(ds1v(3, iat, i, :))
    4879             :          END DO
    4880             :       END DO
    4881             : 
    4882           0 :       colvar%ss = s1(1)/s1(2)/REAL(nconf - 1, dp)
    4883             : 
    4884           0 :       ALLOCATE (fi(3, rmsd_atom))
    4885             : 
    4886           0 :       DO iat = 1, rmsd_atom
    4887           0 :          fi(1, iat) = -lambda/s1(2)/REAL(nconf - 1, dp)*(ds1(1, iat, 1) - ds1(1, iat, 2)*s1(1)/s1(2))
    4888           0 :          fi(2, iat) = -lambda/s1(2)/REAL(nconf - 1, dp)*(ds1(2, iat, 1) - ds1(2, iat, 2)*s1(1)/s1(2))
    4889           0 :          fi(3, iat) = -lambda/s1(2)/REAL(nconf - 1, dp)*(ds1(3, iat, 1) - ds1(3, iat, 2)*s1(1)/s1(2))
    4890           0 :          CALL put_derivative(colvar, iat, fi(:, iat))
    4891             :       END DO
    4892             : 
    4893           0 :       DEALLOCATE (fi)
    4894           0 :       DEALLOCATE (r0)
    4895           0 :       DEALLOCATE (r)
    4896           0 :       DEALLOCATE (riat)
    4897           0 :       DEALLOCATE (s1v)
    4898           0 :       DEALLOCATE (ds1v)
    4899           0 :       DEALLOCATE (ds1)
    4900           0 :       DEALLOCATE (drmsd)
    4901           0 :       DEALLOCATE (weight)
    4902             : 
    4903           0 :    END SUBROUTINE rpath_rmsd
    4904             : 
    4905             : ! **************************************************************************************************
    4906             : !> \brief evaluates the force due (and on) distance from reaction path collective variable
    4907             : !>             ss(R) = -1/\lambda \log[\sum_i exp{-\lambda \sum_a(S_a(R)-f_a(i))^2}]
    4908             : !> \param colvar ...
    4909             : !> \param cell ...
    4910             : !> \param subsys ...
    4911             : !> \param particles ...
    4912             : !> \date 01.2010
    4913             : !> \author MI
    4914             : ! **************************************************************************************************
    4915         248 :    SUBROUTINE distance_from_path_colvar(colvar, cell, subsys, particles)
    4916             :       TYPE(colvar_type), POINTER                         :: colvar
    4917             :       TYPE(cell_type), POINTER                           :: cell
    4918             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    4919             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    4920             :          POINTER                                         :: particles
    4921             : 
    4922             :       TYPE(particle_list_type), POINTER                  :: particles_i
    4923         248 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    4924             : 
    4925           0 :       CPASSERT(colvar%type_id == distance_from_path_colvar_id)
    4926         248 :       IF (PRESENT(particles)) THEN
    4927           0 :          my_particles => particles
    4928             :       ELSE
    4929         248 :          CPASSERT(PRESENT(subsys))
    4930         248 :          CALL cp_subsys_get(subsys, particles=particles_i)
    4931         248 :          my_particles => particles_i%els
    4932             :       END IF
    4933             : 
    4934         248 :       IF (colvar%reaction_path_param%dist_rmsd) THEN
    4935         204 :          CALL dpath_dist_rmsd(colvar, my_particles)
    4936          44 :       ELSEIF (colvar%reaction_path_param%rmsd) THEN
    4937           0 :          CALL dpath_rmsd(colvar, my_particles)
    4938             :       ELSE
    4939          44 :          CALL dpath_colvar(colvar, cell, my_particles)
    4940             :       END IF
    4941             : 
    4942         248 :    END SUBROUTINE distance_from_path_colvar
    4943             : 
    4944             : ! **************************************************************************************************
    4945             : !> \brief  distance from path calculated using selected colvars
    4946             : !>         as compared to functions describing the variation of these same colvars
    4947             : !>         along the path given as reference
    4948             : !> \param colvar ...
    4949             : !> \param cell ...
    4950             : !> \param particles ...
    4951             : !> \date  01.2010
    4952             : !> \author MI
    4953             : ! **************************************************************************************************
    4954          44 :    SUBROUTINE dpath_colvar(colvar, cell, particles)
    4955             :       TYPE(colvar_type), POINTER                         :: colvar
    4956             :       TYPE(cell_type), POINTER                           :: cell
    4957             :       TYPE(particle_type), DIMENSION(:), POINTER         :: particles
    4958             : 
    4959             :       INTEGER                                            :: i, iend, ii, istart, j, k, ncolv
    4960             :       REAL(dp)                                           :: lambda, s1
    4961          44 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: ds1, s1v, ss_vals
    4962          44 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: ds1v, f_vals, fi
    4963             : 
    4964          44 :       istart = colvar%reaction_path_param%function_bounds(1)
    4965          44 :       iend = colvar%reaction_path_param%function_bounds(2)
    4966             : 
    4967          44 :       ncolv = colvar%reaction_path_param%n_components
    4968          44 :       lambda = colvar%reaction_path_param%lambda
    4969         176 :       ALLOCATE (f_vals(ncolv, istart:iend))
    4970      514976 :       f_vals(:, :) = colvar%reaction_path_param%f_vals
    4971         132 :       ALLOCATE (ss_vals(ncolv))
    4972             : 
    4973         132 :       DO i = 1, ncolv
    4974          88 :          CALL colvar_recursive_eval(colvar%reaction_path_param%colvar_p(i)%colvar, cell, particles)
    4975         132 :          ss_vals(i) = colvar%reaction_path_param%colvar_p(i)%colvar%ss
    4976             :       END DO
    4977             : 
    4978         132 :       ALLOCATE (s1v(istart:iend))
    4979         132 :       ALLOCATE (ds1v(ncolv, istart:iend))
    4980          88 :       ALLOCATE (ds1(ncolv))
    4981             : 
    4982      171688 :       DO k = istart, iend
    4983      514932 :          s1v(k) = EXP(-lambda*DOT_PRODUCT(ss_vals(:) - f_vals(:, k), ss_vals(:) - f_vals(:, k)))
    4984      514976 :          DO j = 1, ncolv
    4985      514932 :             ds1v(j, k) = f_vals(j, k)*s1v(k)
    4986             :          END DO
    4987             :       END DO
    4988             : 
    4989          44 :       s1 = accurate_sum(s1v(:))
    4990         132 :       DO j = 1, ncolv
    4991         132 :          ds1(j) = accurate_sum(ds1v(j, :))
    4992             :       END DO
    4993          44 :       colvar%ss = -1.0_dp/lambda*LOG(s1)
    4994             : 
    4995         132 :       ALLOCATE (fi(3, colvar%n_atom_s))
    4996             : 
    4997          44 :       ii = 0
    4998         132 :       DO i = 1, ncolv
    4999         308 :          DO j = 1, colvar%reaction_path_param%colvar_p(i)%colvar%n_atom_s
    5000         176 :             ii = ii + 1
    5001             :             fi(:, ii) = colvar%reaction_path_param%colvar_p(i)%colvar%dsdr(:, j)* &
    5002         792 :                         2.0_dp*(ss_vals(i) - ds1(i)/s1)
    5003             :          END DO
    5004             :       END DO
    5005             : 
    5006         220 :       DO i = 1, colvar%n_atom_s
    5007         220 :          CALL put_derivative(colvar, i, fi(:, i))
    5008             :       END DO
    5009             : 
    5010          44 :       DEALLOCATE (fi)
    5011          44 :       DEALLOCATE (f_vals)
    5012          44 :       DEALLOCATE (ss_vals)
    5013          44 :       DEALLOCATE (s1v)
    5014          44 :       DEALLOCATE (ds1v)
    5015          44 :       DEALLOCATE (ds1)
    5016             : 
    5017          44 :    END SUBROUTINE dpath_colvar
    5018             : 
    5019             : ! **************************************************************************************************
    5020             : !> \brief  distance from path calculated from the positions of a selected list of
    5021             : !>         atoms as compared to the same positions in reference
    5022             : !>         configurations belonging to the given path.
    5023             : !> \param colvar ...
    5024             : !> \param particles ...
    5025             : !> \date  01.2010
    5026             : !> \author MI
    5027             : ! **************************************************************************************************
    5028         204 :    SUBROUTINE dpath_dist_rmsd(colvar, particles)
    5029             : 
    5030             :       TYPE(colvar_type), POINTER                         :: colvar
    5031             :       TYPE(particle_type), DIMENSION(:), POINTER         :: particles
    5032             : 
    5033             :       INTEGER                                            :: i, iat, ii, ik, natom, nconf, rmsd_atom
    5034         204 :       INTEGER, DIMENSION(:), POINTER                     :: iatom
    5035             :       REAL(dp)                                           :: lambda, s1, sum_exp
    5036         204 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: r, r0, s1v, vec_dif
    5037         204 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: ds1, dvec_dif, fi, riat
    5038         204 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: ds1v
    5039         204 :       REAL(dp), DIMENSION(:, :), POINTER                 :: path_conf
    5040             : 
    5041         204 :       nconf = colvar%reaction_path_param%nr_frames
    5042         204 :       rmsd_atom = colvar%reaction_path_param%n_components
    5043         204 :       lambda = colvar%reaction_path_param%lambda
    5044         204 :       path_conf => colvar%reaction_path_param%r_ref
    5045         204 :       iatom => colvar%reaction_path_param%i_rmsd
    5046             : 
    5047         204 :       natom = SIZE(particles)
    5048             : 
    5049         612 :       ALLOCATE (r0(3*natom))
    5050         408 :       ALLOCATE (r(3*natom))
    5051         612 :       ALLOCATE (riat(3, rmsd_atom))
    5052         612 :       ALLOCATE (vec_dif(rmsd_atom))
    5053         408 :       ALLOCATE (dvec_dif(3, rmsd_atom))
    5054         612 :       ALLOCATE (s1v(nconf))
    5055         816 :       ALLOCATE (ds1v(3, rmsd_atom, nconf))
    5056         408 :       ALLOCATE (ds1(3, rmsd_atom))
    5057        3672 :       DO i = 1, natom
    5058        3468 :          ii = (i - 1)*3
    5059        3468 :          r0(ii + 1) = particles(i)%r(1)
    5060        3468 :          r0(ii + 2) = particles(i)%r(2)
    5061        3672 :          r0(ii + 3) = particles(i)%r(3)
    5062             :       END DO
    5063             : 
    5064        2040 :       DO iat = 1, rmsd_atom
    5065        1836 :          ii = iatom(iat)
    5066        7548 :          riat(:, iat) = particles(ii)%r
    5067             :       END DO
    5068             : 
    5069        1224 :       DO ik = 1, nconf
    5070       18360 :          DO i = 1, natom
    5071       17340 :             ii = (i - 1)*3
    5072       17340 :             r(ii + 1) = path_conf(ii + 1, ik)
    5073       17340 :             r(ii + 2) = path_conf(ii + 2, ik)
    5074       18360 :             r(ii + 3) = path_conf(ii + 3, ik)
    5075             :          END DO
    5076             : 
    5077        1020 :          CALL rmsd3(particles, r, r0, output_unit=-1, rotate=.TRUE.)
    5078             : 
    5079        1020 :          sum_exp = 0.0_dp
    5080       10200 :          DO iat = 1, rmsd_atom
    5081        9180 :             i = iatom(iat)
    5082        9180 :             ii = (i - 1)*3
    5083        9180 :             vec_dif(iat) = (riat(1, iat) - r(ii + 1))**2 + (riat(2, iat) - r(ii + 2))**2 + (riat(3, iat) - r(ii + 3))**2
    5084        9180 :             sum_exp = sum_exp + vec_dif(iat)
    5085        9180 :             dvec_dif(1, iat) = r(ii + 1)
    5086        9180 :             dvec_dif(2, iat) = r(ii + 2)
    5087       10200 :             dvec_dif(3, iat) = r(ii + 3)
    5088             :          END DO
    5089        1020 :          s1v(ik) = EXP(-lambda*sum_exp)
    5090       10404 :          DO iat = 1, rmsd_atom
    5091        9180 :             ds1v(1, iat, ik) = dvec_dif(1, iat)*s1v(ik)
    5092        9180 :             ds1v(2, iat, ik) = dvec_dif(2, iat)*s1v(ik)
    5093       10200 :             ds1v(3, iat, ik) = dvec_dif(3, iat)*s1v(ik)
    5094             :          END DO
    5095             :       END DO
    5096             : 
    5097         204 :       s1 = accurate_sum(s1v(:))
    5098        2040 :       DO iat = 1, rmsd_atom
    5099        1836 :          ds1(1, iat) = accurate_sum(ds1v(1, iat, :))
    5100        1836 :          ds1(2, iat) = accurate_sum(ds1v(2, iat, :))
    5101        2040 :          ds1(3, iat) = accurate_sum(ds1v(3, iat, :))
    5102             :       END DO
    5103         204 :       colvar%ss = -1.0_dp/lambda*LOG(s1)
    5104             : 
    5105         408 :       ALLOCATE (fi(3, rmsd_atom))
    5106             : 
    5107        2040 :       DO iat = 1, rmsd_atom
    5108        7344 :          fi(:, iat) = 2.0_dp*(riat(:, iat) - ds1(:, iat)/s1)
    5109        2040 :          CALL put_derivative(colvar, iat, fi(:, iat))
    5110             :       END DO
    5111             : 
    5112         204 :       DEALLOCATE (fi)
    5113         204 :       DEALLOCATE (r0)
    5114         204 :       DEALLOCATE (r)
    5115         204 :       DEALLOCATE (riat)
    5116         204 :       DEALLOCATE (vec_dif)
    5117         204 :       DEALLOCATE (dvec_dif)
    5118         204 :       DEALLOCATE (s1v)
    5119         204 :       DEALLOCATE (ds1v)
    5120         204 :       DEALLOCATE (ds1)
    5121         204 :    END SUBROUTINE dpath_dist_rmsd
    5122             : 
    5123             : ! **************************************************************************************************
    5124             : !> \brief ...
    5125             : !> \param colvar ...
    5126             : !> \param particles ...
    5127             : ! **************************************************************************************************
    5128           0 :    SUBROUTINE dpath_rmsd(colvar, particles)
    5129             : 
    5130             :       TYPE(colvar_type), POINTER                         :: colvar
    5131             :       TYPE(particle_type), DIMENSION(:), POINTER         :: particles
    5132             : 
    5133             :       INTEGER                                            :: i, iat, ii, ik, natom, nconf, rmsd_atom
    5134           0 :       INTEGER, DIMENSION(:), POINTER                     :: iatom
    5135             :       REAL(dp)                                           :: lambda, my_rmsd, s1
    5136           0 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: r, r0, s1v
    5137           0 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: ds1, fi, riat
    5138           0 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :, :)          :: ds1v
    5139           0 :       REAL(dp), DIMENSION(:, :), POINTER                 :: path_conf
    5140           0 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: weight
    5141             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: drmsd
    5142             : 
    5143           0 :       nconf = colvar%reaction_path_param%nr_frames
    5144           0 :       rmsd_atom = colvar%reaction_path_param%n_components
    5145           0 :       lambda = colvar%reaction_path_param%lambda
    5146           0 :       path_conf => colvar%reaction_path_param%r_ref
    5147           0 :       iatom => colvar%reaction_path_param%i_rmsd
    5148             : 
    5149           0 :       natom = SIZE(particles)
    5150             : 
    5151           0 :       ALLOCATE (r0(3*natom))
    5152           0 :       ALLOCATE (r(3*natom))
    5153           0 :       ALLOCATE (riat(3, rmsd_atom))
    5154           0 :       ALLOCATE (s1v(nconf))
    5155           0 :       ALLOCATE (ds1v(3, rmsd_atom, nconf))
    5156           0 :       ALLOCATE (ds1(3, rmsd_atom))
    5157           0 :       ALLOCATE (drmsd(3, natom))
    5158           0 :       drmsd = 0.0_dp
    5159           0 :       ALLOCATE (weight(natom))
    5160             : 
    5161           0 :       DO i = 1, natom
    5162           0 :          ii = (i - 1)*3
    5163           0 :          r0(ii + 1) = particles(i)%r(1)
    5164           0 :          r0(ii + 2) = particles(i)%r(2)
    5165           0 :          r0(ii + 3) = particles(i)%r(3)
    5166             :       END DO
    5167             : 
    5168           0 :       DO iat = 1, rmsd_atom
    5169           0 :          ii = iatom(iat)
    5170           0 :          riat(:, iat) = particles(ii)%r
    5171             :       END DO
    5172             : 
    5173             : ! set weights of atoms in the rmsd list
    5174           0 :       weight = 0.0_dp
    5175           0 :       DO iat = 1, rmsd_atom
    5176           0 :          i = iatom(iat)
    5177           0 :          weight(i) = 1.0_dp
    5178             :       END DO
    5179             : 
    5180           0 :       DO ik = 1, nconf
    5181           0 :          DO i = 1, natom
    5182           0 :             ii = (i - 1)*3
    5183           0 :             r(ii + 1) = path_conf(ii + 1, ik)
    5184           0 :             r(ii + 2) = path_conf(ii + 2, ik)
    5185           0 :             r(ii + 3) = path_conf(ii + 3, ik)
    5186             :          END DO
    5187             : 
    5188             :          CALL rmsd3(particles, r0, r, output_unit=-1, weights=weight, my_val=my_rmsd, &
    5189           0 :                     rotate=.FALSE., drmsd3=drmsd)
    5190             : 
    5191           0 :          s1v(ik) = EXP(-lambda*my_rmsd)
    5192           0 :          DO iat = 1, rmsd_atom
    5193           0 :             i = iatom(iat)
    5194           0 :             ds1v(1, iat, ik) = drmsd(1, i)*s1v(ik)
    5195           0 :             ds1v(2, iat, ik) = drmsd(2, i)*s1v(ik)
    5196           0 :             ds1v(3, iat, ik) = drmsd(3, i)*s1v(ik)
    5197             :          END DO
    5198             :       END DO
    5199             : 
    5200           0 :       s1 = accurate_sum(s1v(:))
    5201           0 :       DO iat = 1, rmsd_atom
    5202           0 :          ds1(1, iat) = accurate_sum(ds1v(1, iat, :))
    5203           0 :          ds1(2, iat) = accurate_sum(ds1v(2, iat, :))
    5204           0 :          ds1(3, iat) = accurate_sum(ds1v(3, iat, :))
    5205             :       END DO
    5206           0 :       colvar%ss = -1.0_dp/lambda*LOG(s1)
    5207             : 
    5208           0 :       ALLOCATE (fi(3, rmsd_atom))
    5209             : 
    5210           0 :       DO iat = 1, rmsd_atom
    5211           0 :          fi(:, iat) = ds1(:, iat)/s1
    5212           0 :          CALL put_derivative(colvar, iat, fi(:, iat))
    5213             :       END DO
    5214             : 
    5215           0 :       DEALLOCATE (fi)
    5216           0 :       DEALLOCATE (r0)
    5217           0 :       DEALLOCATE (r)
    5218           0 :       DEALLOCATE (riat)
    5219           0 :       DEALLOCATE (s1v)
    5220           0 :       DEALLOCATE (ds1v)
    5221           0 :       DEALLOCATE (ds1)
    5222           0 :       DEALLOCATE (drmsd)
    5223           0 :       DEALLOCATE (weight)
    5224             : 
    5225           0 :    END SUBROUTINE dpath_rmsd
    5226             : 
    5227             : ! **************************************************************************************************
    5228             : !> \brief evaluates the force due to population colvar
    5229             : !> \param colvar ...
    5230             : !> \param cell ...
    5231             : !> \param subsys ...
    5232             : !> \param particles ...
    5233             : !> \date  01.2009
    5234             : !> \author fsterpone
    5235             : ! **************************************************************************************************
    5236         144 :    SUBROUTINE population_colvar(colvar, cell, subsys, particles)
    5237             :       TYPE(colvar_type), POINTER                         :: colvar
    5238             :       TYPE(cell_type), POINTER                           :: cell
    5239             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    5240             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    5241             :          POINTER                                         :: particles
    5242             : 
    5243             :       INTEGER                                            :: i, ii, jj, n_atoms_from, n_atoms_to, &
    5244             :                                                             ndcrd, nncrd
    5245             :       REAL(dp) :: dfunc, dfunc_coord, ftmp(3), func, func_coord, inv_n_atoms_from, invden, n_0, &
    5246             :          ncoord, norm, num, population, r12, r_0, rdist, sigma, ss(3), xij(3)
    5247         144 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: ftmp_coord
    5248             :       REAL(dp), DIMENSION(3)                             :: xpi, xpj
    5249             :       TYPE(particle_list_type), POINTER                  :: particles_i
    5250         144 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    5251             : 
    5252             : ! If we defined the coordination number with KINDS then we have still
    5253             : ! to fill few missing informations...
    5254             : 
    5255         144 :       NULLIFY (particles_i)
    5256           0 :       CPASSERT(colvar%type_id == population_colvar_id)
    5257         144 :       IF (PRESENT(particles)) THEN
    5258           0 :          my_particles => particles
    5259             :       ELSE
    5260         144 :          CPASSERT(PRESENT(subsys))
    5261         144 :          CALL cp_subsys_get(subsys, particles=particles_i)
    5262         144 :          my_particles => particles_i%els
    5263             :       END IF
    5264         144 :       n_atoms_to = colvar%population_param%n_atoms_to
    5265         144 :       n_atoms_from = colvar%population_param%n_atoms_from
    5266         144 :       nncrd = colvar%population_param%nncrd
    5267         144 :       ndcrd = colvar%population_param%ndcrd
    5268         144 :       r_0 = colvar%population_param%r_0
    5269         144 :       n_0 = colvar%population_param%n0
    5270         144 :       sigma = colvar%population_param%sigma
    5271             : 
    5272         432 :       ALLOCATE (ftmp_coord(3, n_atoms_to))
    5273        1296 :       ftmp_coord = 0.0_dp
    5274             : 
    5275         144 :       ncoord = 0.0_dp
    5276         144 :       population = 0.0_dp
    5277             : 
    5278        1872 :       colvar%dsdr = 0.0_dp
    5279         144 :       inv_n_atoms_from = 1.0_dp/REAL(n_atoms_from, KIND=dp)
    5280             : 
    5281         144 :       norm = SQRT(pi*2.0_dp)*sigma
    5282         144 :       norm = 1/norm
    5283             : 
    5284         288 :       DO ii = 1, n_atoms_from
    5285         144 :          i = colvar%population_param%i_at_from(ii)
    5286         144 :          CALL get_coordinates(colvar, i, xpi, my_particles)
    5287         432 :          DO jj = 1, n_atoms_to
    5288         288 :             i = colvar%population_param%i_at_to(jj)
    5289         288 :             CALL get_coordinates(colvar, i, xpj, my_particles)
    5290        4608 :             ss = MATMUL(cell%h_inv, xpi(:) - xpj(:))
    5291        1152 :             ss = ss - NINT(ss)
    5292        3744 :             xij = MATMUL(cell%hmat, ss)
    5293         288 :             r12 = SQRT(xij(1)**2 + xij(2)**2 + xij(3)**2)
    5294         288 :             IF (r12 < 1.0e-8_dp) CYCLE
    5295         288 :             rdist = r12/r_0
    5296         288 :             num = (1.0_dp - rdist**nncrd)
    5297         288 :             invden = 1.0_dp/(1.0_dp - rdist**ndcrd)
    5298         288 :             func_coord = num*invden
    5299             :             dfunc_coord = (-nncrd*rdist**(nncrd - 1)*invden &
    5300         288 :                            + num*(invden)**2*ndcrd*rdist**(ndcrd - 1))/(r12*r_0)
    5301             : 
    5302         288 :             ncoord = ncoord + func_coord
    5303         288 :             ftmp_coord(1, jj) = dfunc_coord*xij(1)
    5304         288 :             ftmp_coord(2, jj) = dfunc_coord*xij(2)
    5305         432 :             ftmp_coord(3, jj) = dfunc_coord*xij(3)
    5306             :          END DO
    5307             : 
    5308         144 :          func = EXP(-(ncoord - n_0)**2/(2.0_dp*sigma*sigma))
    5309         144 :          dfunc = -func*(ncoord - n_0)/(sigma*sigma)
    5310             : 
    5311         144 :          population = population + norm*func
    5312         432 :          DO jj = 1, n_atoms_to
    5313         288 :             ftmp(1) = ftmp_coord(1, jj)*dfunc
    5314         288 :             ftmp(2) = ftmp_coord(2, jj)*dfunc
    5315         288 :             ftmp(3) = ftmp_coord(3, jj)*dfunc
    5316         288 :             CALL put_derivative(colvar, ii, ftmp)
    5317         288 :             ftmp(1) = -ftmp_coord(1, jj)*dfunc
    5318         288 :             ftmp(2) = -ftmp_coord(2, jj)*dfunc
    5319         288 :             ftmp(3) = -ftmp_coord(3, jj)*dfunc
    5320         432 :             CALL put_derivative(colvar, n_atoms_from + jj, ftmp)
    5321             :          END DO
    5322         288 :          ncoord = 0.0_dp
    5323             :       END DO
    5324         144 :       colvar%ss = population
    5325         288 :    END SUBROUTINE population_colvar
    5326             : 
    5327             : ! **************************************************************************************************
    5328             : !> \brief evaluates the force due to the gyration radius colvar
    5329             : !>        sum_i (r_i-rcom)^2/N
    5330             : !> \param colvar ...
    5331             : !> \param cell ...
    5332             : !> \param subsys ...
    5333             : !> \param particles ...
    5334             : !> \date  03.2009
    5335             : !> \author MI
    5336             : ! **************************************************************************************************
    5337           8 :    SUBROUTINE gyration_radius_colvar(colvar, cell, subsys, particles)
    5338             : 
    5339             :       TYPE(colvar_type), POINTER                         :: colvar
    5340             :       TYPE(cell_type), POINTER                           :: cell
    5341             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    5342             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    5343             :          POINTER                                         :: particles
    5344             : 
    5345             :       INTEGER                                            :: i, ii, n_atoms
    5346             :       REAL(dp)                                           :: dri2, func, gyration, inv_n, mass_tot, mi
    5347             :       REAL(dp), DIMENSION(3)                             :: dfunc, dxi, ftmp, ss, xpcom, xpi
    5348             :       TYPE(particle_list_type), POINTER                  :: particles_i
    5349           8 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    5350             : 
    5351           8 :       NULLIFY (particles_i, my_particles)
    5352           0 :       CPASSERT(colvar%type_id == gyration_colvar_id)
    5353           8 :       IF (PRESENT(particles)) THEN
    5354           0 :          my_particles => particles
    5355             :       ELSE
    5356           8 :          CPASSERT(PRESENT(subsys))
    5357           8 :          CALL cp_subsys_get(subsys, particles=particles_i)
    5358           8 :          my_particles => particles_i%els
    5359             :       END IF
    5360           8 :       n_atoms = colvar%gyration_param%n_atoms
    5361           8 :       inv_n = 1.0_dp/n_atoms
    5362             : 
    5363             :       !compute COM position
    5364           8 :       xpcom = 0.0_dp
    5365           8 :       mass_tot = 0.0_dp
    5366         112 :       DO ii = 1, n_atoms
    5367         104 :          i = colvar%gyration_param%i_at(ii)
    5368         104 :          CALL get_coordinates(colvar, i, xpi, my_particles)
    5369         104 :          CALL get_mass(colvar, i, mi, my_particles)
    5370         416 :          xpcom(:) = xpcom(:) + xpi(:)*mi
    5371         216 :          mass_tot = mass_tot + mi
    5372             :       END DO
    5373          32 :       xpcom(:) = xpcom(:)/mass_tot
    5374             : 
    5375           8 :       func = 0.0_dp
    5376           8 :       ftmp = 0.0_dp
    5377           8 :       dfunc = 0.0_dp
    5378         112 :       DO ii = 1, n_atoms
    5379         104 :          i = colvar%gyration_param%i_at(ii)
    5380         104 :          CALL get_coordinates(colvar, i, xpi, my_particles)
    5381        1664 :          ss = MATMUL(cell%h_inv, xpi(:) - xpcom(:))
    5382         416 :          ss = ss - NINT(ss)
    5383        1352 :          dxi = MATMUL(cell%hmat, ss)
    5384         104 :          dri2 = (dxi(1)**2 + dxi(2)**2 + dxi(3)**2)
    5385         104 :          func = func + dri2
    5386         424 :          dfunc(:) = dfunc(:) + dxi(:)
    5387             :       END DO
    5388           8 :       gyration = SQRT(inv_n*func)
    5389             : 
    5390         112 :       DO ii = 1, n_atoms
    5391         104 :          i = colvar%gyration_param%i_at(ii)
    5392         104 :          CALL get_coordinates(colvar, i, xpi, my_particles)
    5393         104 :          CALL get_mass(colvar, i, mi, my_particles)
    5394        1664 :          ss = MATMUL(cell%h_inv, xpi(:) - xpcom(:))
    5395         416 :          ss = ss - NINT(ss)
    5396        1352 :          dxi = MATMUL(cell%hmat, ss)
    5397         104 :          ftmp(1) = dxi(1) - dfunc(1)*mi/mass_tot
    5398         104 :          ftmp(2) = dxi(2) - dfunc(2)*mi/mass_tot
    5399         104 :          ftmp(3) = dxi(3) - dfunc(3)*mi/mass_tot
    5400         416 :          ftmp(:) = ftmp(:)*inv_n/gyration
    5401         216 :          CALL put_derivative(colvar, ii, ftmp)
    5402             :       END DO
    5403           8 :       colvar%ss = gyration
    5404             : 
    5405           8 :    END SUBROUTINE gyration_radius_colvar
    5406             : 
    5407             : ! **************************************************************************************************
    5408             : !> \brief evaluates the force due to the rmsd colvar
    5409             : !> \param colvar ...
    5410             : !> \param subsys ...
    5411             : !> \param particles ...
    5412             : !> \date  12.2009
    5413             : !> \author MI
    5414             : !> \note  could be extended to be used with more than 2 reference structures
    5415             : ! **************************************************************************************************
    5416          24 :    SUBROUTINE rmsd_colvar(colvar, subsys, particles)
    5417             :       TYPE(colvar_type), POINTER                         :: colvar
    5418             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    5419             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    5420             :          POINTER                                         :: particles
    5421             : 
    5422          24 :       CALL rmsd_colvar_low(colvar, subsys, particles)
    5423          24 :    END SUBROUTINE rmsd_colvar
    5424             : 
    5425             : ! **************************************************************************************************
    5426             : !> \brief  evaluates the force due to the rmsd colvar
    5427             : !>        ss = (RMSDA-RMSDB)/(RMSDA+RMSDB)
    5428             : !>        RMSD is calculated with respect to two reference structures, A and B,
    5429             : !>        considering all the atoms of the system or only a subset of them,
    5430             : !>        as selected by the input keyword LIST
    5431             : !> \param colvar ...
    5432             : !> \param subsys ...
    5433             : !> \param particles ...
    5434             : !> \date  12.2009
    5435             : !> \par History TL 2012 (generalized to any number of frames)
    5436             : !> \author MI
    5437             : ! **************************************************************************************************
    5438          24 :    SUBROUTINE rmsd_colvar_low(colvar, subsys, particles)
    5439             : 
    5440             :       TYPE(colvar_type), POINTER                         :: colvar
    5441             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    5442             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    5443             :          POINTER                                         :: particles
    5444             : 
    5445             :       INTEGER                                            :: i, ii, natom, nframes
    5446             :       REAL(kind=dp)                                      :: cv_val, f1, ftmp(3)
    5447          24 :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:)           :: der, r, rmsd
    5448          24 :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :)        :: r0
    5449          24 :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: drmsd
    5450          24 :       REAL(kind=dp), DIMENSION(:), POINTER               :: weights
    5451             :       TYPE(particle_list_type), POINTER                  :: particles_i
    5452          24 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    5453             : 
    5454          24 :       NULLIFY (my_particles, particles_i, weights)
    5455           0 :       CPASSERT(colvar%type_id == rmsd_colvar_id)
    5456          24 :       IF (PRESENT(particles)) THEN
    5457           0 :          my_particles => particles
    5458             :       ELSE
    5459          24 :          CPASSERT(PRESENT(subsys))
    5460          24 :          CALL cp_subsys_get(subsys, particles=particles_i)
    5461          24 :          my_particles => particles_i%els
    5462             :       END IF
    5463             : 
    5464          24 :       natom = SIZE(my_particles)
    5465          24 :       nframes = colvar%rmsd_param%nr_frames
    5466          96 :       ALLOCATE (drmsd(3, natom, nframes))
    5467        1788 :       drmsd = 0.0_dp
    5468             : 
    5469          96 :       ALLOCATE (r0(3*natom, nframes))
    5470          72 :       ALLOCATE (rmsd(nframes))
    5471          48 :       ALLOCATE (der(nframes))
    5472          72 :       ALLOCATE (r(3*natom))
    5473             : 
    5474          24 :       weights => colvar%rmsd_param%weights
    5475         312 :       DO i = 1, natom
    5476         288 :          ii = (i - 1)*3
    5477         288 :          r(ii + 1) = my_particles(i)%r(1)
    5478         288 :          r(ii + 2) = my_particles(i)%r(2)
    5479         312 :          r(ii + 3) = my_particles(i)%r(3)
    5480             :       END DO
    5481        1356 :       r0(:, :) = colvar%rmsd_param%r_ref
    5482          60 :       rmsd = 0.0_dp
    5483             : 
    5484          24 :       CALL rmsd3(my_particles, r, r0(:, 1), output_unit=-1, weights=weights, my_val=rmsd(1), rotate=.FALSE., drmsd3=drmsd(:, :, 1))
    5485             : 
    5486          24 :       IF (nframes == 2) THEN
    5487             :          CALL rmsd3(my_particles, r, r0(:, 2), output_unit=-1, weights=weights, &
    5488          12 :                     my_val=rmsd(2), rotate=.FALSE., drmsd3=drmsd(:, :, 2))
    5489             : 
    5490          12 :          f1 = 1.0_dp/(rmsd(1) + rmsd(2))
    5491             :          ! (rmsdA-rmsdB)/(rmsdA+rmsdB)
    5492          12 :          cv_val = (rmsd(1) - rmsd(2))*f1
    5493             :          ! (rmsdA+rmsdB)^-1-(rmsdA-rmsdB)/(rmsdA+rmsdB)^2
    5494          12 :          der(1) = f1 - cv_val*f1
    5495             :          ! -(rmsdA+rmsdB)^-1-(rmsdA-rmsdB)/(rmsdA+rmsdB)^2
    5496          12 :          der(2) = -f1 - cv_val*f1
    5497             : 
    5498          84 :          DO i = 1, colvar%rmsd_param%n_atoms
    5499          72 :             ii = colvar%rmsd_param%i_rmsd(i)
    5500          84 :             IF (weights(ii) > 0.0_dp) THEN
    5501          72 :                ftmp(1) = der(1)*drmsd(1, ii, 1) + der(2)*drmsd(1, ii, 2)
    5502          72 :                ftmp(2) = der(1)*drmsd(2, ii, 1) + der(2)*drmsd(2, ii, 2)
    5503          72 :                ftmp(3) = der(1)*drmsd(3, ii, 1) + der(2)*drmsd(3, ii, 2)
    5504          72 :                CALL put_derivative(colvar, i, ftmp)
    5505             :             END IF
    5506             :          END DO
    5507          12 :       ELSE IF (nframes == 1) THEN
    5508             :          ! Protect in case of numerical issues (for two identical frames!)
    5509          12 :          rmsd(1) = ABS(rmsd(1))
    5510          12 :          cv_val = SQRT(rmsd(1))
    5511          12 :          f1 = 0.0_dp
    5512          12 :          IF (cv_val /= 0.0_dp) f1 = 0.5_dp/cv_val
    5513          84 :          DO i = 1, colvar%rmsd_param%n_atoms
    5514          72 :             ii = colvar%rmsd_param%i_rmsd(i)
    5515          84 :             IF (weights(ii) > 0.0_dp) THEN
    5516          72 :                ftmp(1) = f1*drmsd(1, ii, 1)
    5517          72 :                ftmp(2) = f1*drmsd(2, ii, 1)
    5518          72 :                ftmp(3) = f1*drmsd(3, ii, 1)
    5519          72 :                CALL put_derivative(colvar, i, ftmp)
    5520             :             END IF
    5521             :          END DO
    5522             :       ELSE
    5523           0 :          CPABORT("RMSD implemented only for 1 and 2 reference frames!")
    5524             :       END IF
    5525          24 :       colvar%ss = cv_val
    5526             : 
    5527          24 :       DEALLOCATE (der)
    5528          24 :       DEALLOCATE (r0)
    5529          24 :       DEALLOCATE (r)
    5530          24 :       DEALLOCATE (drmsd)
    5531          24 :       DEALLOCATE (rmsd)
    5532             : 
    5533          24 :    END SUBROUTINE rmsd_colvar_low
    5534             : 
    5535             : ! **************************************************************************************************
    5536             : !> \brief evaluates the force from ring puckering collective variables
    5537             : !>   Cramer and Pople, JACS 97 1354 (1975)
    5538             : !> \param colvar ...
    5539             : !> \param cell ...
    5540             : !> \param subsys ...
    5541             : !> \param particles ...
    5542             : !> \date 08.2012
    5543             : !> \author JGH
    5544             : ! **************************************************************************************************
    5545         352 :    SUBROUTINE ring_puckering_colvar(colvar, cell, subsys, particles)
    5546             :       TYPE(colvar_type), POINTER                         :: colvar
    5547             :       TYPE(cell_type), POINTER                           :: cell
    5548             :       TYPE(cp_subsys_type), OPTIONAL, POINTER            :: subsys
    5549             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    5550             :          POINTER                                         :: particles
    5551             : 
    5552             :       INTEGER                                            :: i, ii, j, jj, m, nring
    5553             :       REAL(KIND=dp)                                      :: a, at, b, da, db, ds, kr, rpxpp, svar
    5554         352 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: cosj, sinj, z
    5555         352 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: r
    5556         352 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: nforce, zforce
    5557             :       REAL(KIND=dp), DIMENSION(3)                        :: ftmp, nv, r0, rp, rpp, uv
    5558             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: dnvp, dnvpp
    5559             :       TYPE(particle_list_type), POINTER                  :: particles_i
    5560         352 :       TYPE(particle_type), DIMENSION(:), POINTER         :: my_particles
    5561             : 
    5562           0 :       CPASSERT(colvar%type_id == ring_puckering_colvar_id)
    5563         352 :       IF (PRESENT(particles)) THEN
    5564         132 :          my_particles => particles
    5565             :       ELSE
    5566         220 :          CPASSERT(PRESENT(subsys))
    5567         220 :          CALL cp_subsys_get(subsys, particles=particles_i)
    5568         220 :          my_particles => particles_i%els
    5569             :       END IF
    5570             : 
    5571         352 :       nring = colvar%ring_puckering_param%nring
    5572        2464 :       ALLOCATE (r(3, nring), z(nring), cosj(nring), sinj(nring))
    5573        2464 :       ALLOCATE (nforce(3, 3, nring), zforce(nring, nring, 3))
    5574        2310 :       DO ii = 1, nring
    5575        1958 :          i = colvar%ring_puckering_param%atoms(ii)
    5576        2310 :          CALL get_coordinates(colvar, i, r(:, ii), my_particles)
    5577             :       END DO
    5578             :       ! get all atoms within PBC distance of atom 1
    5579        1408 :       r0(:) = r(:, 1)
    5580        2310 :       DO ii = 1, nring
    5581        8184 :          r(:, ii) = pbc(r(:, ii), r0, cell)
    5582             :       END DO
    5583             :       !compute origin position
    5584         352 :       r0 = 0.0_dp
    5585        2310 :       DO ii = 1, nring
    5586        8184 :          r0(:) = r0(:) + r(:, ii)
    5587             :       END DO
    5588         352 :       kr = 1._dp/REAL(nring, KIND=dp)
    5589        1408 :       r0(:) = r0(:)*kr
    5590        2310 :       DO ii = 1, nring
    5591        8184 :          r(:, ii) = r(:, ii) - r0(:)
    5592             :       END DO
    5593             :       ! orientation vectors
    5594         352 :       rp = 0._dp
    5595         352 :       rpp = 0._dp
    5596        2310 :       DO ii = 1, nring
    5597        1958 :          cosj(ii) = COS(twopi*(ii - 1)*kr)
    5598        1958 :          sinj(ii) = SIN(twopi*(ii - 1)*kr)
    5599        7832 :          rp(:) = rp(:) + r(:, ii)*sinj(ii)
    5600        8184 :          rpp(:) = rpp(:) + r(:, ii)*cosj(ii)
    5601             :       END DO
    5602         352 :       nv = vector_product(rp, rpp)
    5603        2464 :       nv = nv/SQRT(SUM(nv**2))
    5604             : 
    5605             :       ! derivatives of normal
    5606         352 :       uv = vector_product(rp, rpp)
    5607        1408 :       rpxpp = SQRT(SUM(uv**2))
    5608        1408 :       DO i = 1, 3
    5609        1056 :          uv = 0._dp
    5610        1056 :          uv(i) = 1._dp
    5611        4224 :          uv = vector_product(uv, rpp)/rpxpp
    5612        7392 :          dnvp(:, i) = uv - nv*SUM(uv*nv)
    5613        1056 :          uv = 0._dp
    5614        1056 :          uv(i) = 1._dp
    5615        4224 :          uv = vector_product(rp, uv)/rpxpp
    5616        7744 :          dnvpp(:, i) = uv - nv*SUM(uv*nv)
    5617             :       END DO
    5618        2310 :       DO ii = 1, nring
    5619       25806 :          nforce(:, :, ii) = dnvp(:, :)*sinj(ii) + dnvpp(:, :)*cosj(ii)
    5620             :       END DO
    5621             : 
    5622             :       ! molecular z-coordinate
    5623        2310 :       DO ii = 1, nring
    5624        8184 :          z(ii) = SUM(r(:, ii)*nv(:))
    5625             :       END DO
    5626             :       ! z-force
    5627        2310 :       DO ii = 1, nring
    5628       13376 :          DO jj = 1, nring
    5629       11066 :             IF (ii == jj) THEN
    5630        7832 :                zforce(ii, jj, :) = nv
    5631             :             ELSE
    5632       36432 :                zforce(ii, jj, :) = 0._dp
    5633             :             END IF
    5634       46222 :             DO i = 1, 3
    5635      143858 :                DO j = 1, 3
    5636      132792 :                   zforce(ii, jj, i) = zforce(ii, jj, i) + r(j, ii)*nforce(j, i, jj)
    5637             :                END DO
    5638             :             END DO
    5639             :          END DO
    5640             :       END DO
    5641             : 
    5642         352 :       IF (colvar%ring_puckering_param%iq == 0) THEN
    5643             :          ! total puckering amplitude
    5644         550 :          svar = SQRT(SUM(z**2))
    5645         550 :          DO ii = 1, nring
    5646         462 :             ftmp = 0._dp
    5647        2948 :             DO jj = 1, nring
    5648       10406 :                ftmp(:) = ftmp(:) + zforce(jj, ii, :)*z(jj)
    5649             :             END DO
    5650        1848 :             ftmp = ftmp/svar
    5651         550 :             CALL put_derivative(colvar, ii, ftmp)
    5652             :          END DO
    5653             :       ELSE
    5654         264 :          m = ABS(colvar%ring_puckering_param%iq)
    5655         264 :          CPASSERT(m /= 1)
    5656         264 :          IF (MOD(nring, 2) == 0 .AND. colvar%ring_puckering_param%iq == nring/2) THEN
    5657             :             ! single puckering amplitude
    5658          66 :             svar = 0._dp
    5659         418 :             DO ii = 1, nring
    5660         418 :                IF (MOD(ii, 2) == 0) THEN
    5661         176 :                   svar = svar - z(ii)
    5662             :                ELSE
    5663         176 :                   svar = svar + z(ii)
    5664             :                END IF
    5665             :             END DO
    5666          66 :             svar = svar*SQRT(kr)
    5667         418 :             DO ii = 1, nring
    5668         352 :                ftmp = 0._dp
    5669        2288 :                DO jj = 1, nring
    5670        2288 :                   IF (MOD(jj, 2) == 0) THEN
    5671        3872 :                      ftmp(:) = ftmp(:) - zforce(jj, ii, :)*SQRT(kr)
    5672             :                   ELSE
    5673        3872 :                      ftmp(:) = ftmp(:) + zforce(jj, ii, :)*SQRT(kr)
    5674             :                   END IF
    5675             :                END DO
    5676        1474 :                CALL put_derivative(colvar, ii, -ftmp)
    5677             :             END DO
    5678             :          ELSE
    5679         198 :             CPASSERT(m <= (nring - 1)/2)
    5680         198 :             a = 0._dp
    5681         198 :             b = 0._dp
    5682        1342 :             DO ii = 1, nring
    5683        1144 :                a = a + z(ii)*COS(twopi*m*(ii - 1)*kr)
    5684        1342 :                b = b - z(ii)*SIN(twopi*m*(ii - 1)*kr)
    5685             :             END DO
    5686         198 :             a = a*SQRT(2._dp*kr)
    5687         198 :             b = b*SQRT(2._dp*kr)
    5688         198 :             IF (colvar%ring_puckering_param%iq > 0) THEN
    5689             :                ! puckering amplitude
    5690         110 :                svar = SQRT(a*a + b*b)
    5691         110 :                da = a/svar
    5692         110 :                db = b/svar
    5693             :             ELSE
    5694             :                ! puckering phase angle
    5695          88 :                at = ATAN2(a, b)
    5696          88 :                IF (at > pi/2._dp) THEN
    5697          28 :                   svar = 2.5_dp*pi - at
    5698             :                ELSE
    5699          60 :                   svar = 0.5_dp*pi - at
    5700             :                END IF
    5701          88 :                da = -b/(a*a + b*b)
    5702          88 :                db = a/(a*a + b*b)
    5703             :             END IF
    5704        1342 :             DO jj = 1, nring
    5705        1144 :                ftmp = 0._dp
    5706        7788 :                DO ii = 1, nring
    5707        6644 :                   ds = da*COS(twopi*m*(ii - 1)*kr)
    5708        6644 :                   ds = ds - db*SIN(twopi*m*(ii - 1)*kr)
    5709       27720 :                   ftmp(:) = ftmp(:) + ds*SQRT(2._dp*kr)*zforce(ii, jj, :)
    5710             :                END DO
    5711        1342 :                CALL put_derivative(colvar, jj, ftmp)
    5712             :             END DO
    5713             :          END IF
    5714             :       END IF
    5715             : 
    5716         352 :       colvar%ss = svar
    5717             : 
    5718         352 :       DEALLOCATE (r, z, cosj, sinj, nforce, zforce)
    5719             : 
    5720         352 :    END SUBROUTINE ring_puckering_colvar
    5721             : 
    5722             : ! **************************************************************************************************
    5723             : !> \brief used to print reaction_path function values on an arbitrary dimensional grid
    5724             : !> \param iw1 ...
    5725             : !> \param ncol ...
    5726             : !> \param f_vals ...
    5727             : !> \param v_count ...
    5728             : !> \param gp ...
    5729             : !> \param grid_sp ...
    5730             : !> \param step_size ...
    5731             : !> \param istart ...
    5732             : !> \param iend ...
    5733             : !> \param s1v ...
    5734             : !> \param s1 ...
    5735             : !> \param p_bounds ...
    5736             : !> \param lambda ...
    5737             : !> \param ifunc ...
    5738             : !> \param nconf ...
    5739             : !> \return ...
    5740             : !> \author fschiff
    5741             : ! **************************************************************************************************
    5742        2315 :    RECURSIVE FUNCTION rec_eval_grid(iw1, ncol, f_vals, v_count, &
    5743             :                                     gp, grid_sp, step_size, istart, iend, s1v, s1, p_bounds, lambda, ifunc, nconf) RESULT(k)
    5744             :       INTEGER                                            :: iw1, ncol
    5745             :       REAL(dp), DIMENSION(:, :), POINTER                 :: f_vals
    5746             :       INTEGER                                            :: v_count
    5747             :       REAL(dp), DIMENSION(:), POINTER                    :: gp, grid_sp
    5748             :       REAL(dp)                                           :: step_size
    5749             :       INTEGER                                            :: istart, iend
    5750             :       REAL(dp), DIMENSION(:, :), POINTER                 :: s1v
    5751             :       REAL(dp), DIMENSION(:), POINTER                    :: s1
    5752             :       INTEGER, DIMENSION(:, :), POINTER                  :: p_bounds
    5753             :       REAL(dp)                                           :: lambda
    5754             :       INTEGER                                            :: ifunc, nconf, k
    5755             : 
    5756             :       INTEGER                                            :: count1, i
    5757             : 
    5758        2315 :       k = 1
    5759        2315 :       IF (v_count .LT. ncol) THEN
    5760         110 :          count1 = v_count + 1
    5761        2420 :          DO i = p_bounds(1, count1), p_bounds(2, count1)
    5762        2310 :             gp(count1) = REAL(i, KIND=dp)*grid_sp(count1)
    5763             :             k = rec_eval_grid(iw1, ncol, f_vals, count1, gp, grid_sp, step_size, &
    5764        2420 :                               istart, iend, s1v, s1, p_bounds, lambda, ifunc, nconf)
    5765             :          END DO
    5766        2205 :       ELSE IF (v_count == ncol .AND. ifunc == 1) THEN
    5767     5162346 :          DO i = istart, iend
    5768             :             s1v(1, i) = REAL(i, kind=dp)*step_size*EXP(-lambda*DOT_PRODUCT(gp(:) - f_vals(:, i), &
    5769    15483069 :                                                                            gp(:) - f_vals(:, i)))
    5770    15484392 :             s1v(2, i) = EXP(-lambda*DOT_PRODUCT(gp(:) - f_vals(:, i), gp(:) - f_vals(:, i)))
    5771             :          END DO
    5772        3969 :          DO i = 1, 2
    5773        3969 :             s1(i) = accurate_sum(s1v(i, :))
    5774             :          END DO
    5775        1323 :          WRITE (iw1, '(5F10.5)') gp(:), s1(1)/s1(2)/REAL(nconf - 1, dp)
    5776         882 :       ELSE IF (v_count == ncol .AND. ifunc == 2) THEN
    5777     3441564 :          DO i = istart, iend
    5778    10322928 :             s1v(1, i) = EXP(-lambda*DOT_PRODUCT(gp(:) - f_vals(:, i), gp(:) - f_vals(:, i)))
    5779             :          END DO
    5780         882 :          s1(1) = accurate_sum(s1v(1, :))
    5781             : 
    5782         882 :          WRITE (iw1, '(5F10.5)') gp(:), -lambda*LOG(s1(1))
    5783             :       END IF
    5784        2315 :    END FUNCTION rec_eval_grid
    5785             : 
    5786             : ! **************************************************************************************************
    5787             : !> \brief  Reads the coordinates of reference configurations given in input
    5788             : !>         either as xyz files or in &COORD section
    5789             : !> \param frame_section ...
    5790             : !> \param para_env ...
    5791             : !> \param nr_frames ...
    5792             : !> \param r_ref ...
    5793             : !> \param n_atoms ...
    5794             : !> \date 01.2010
    5795             : !> \author MI
    5796             : ! **************************************************************************************************
    5797          12 :    SUBROUTINE read_frames(frame_section, para_env, nr_frames, r_ref, n_atoms)
    5798             : 
    5799             :       TYPE(section_vals_type), POINTER                   :: frame_section
    5800             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    5801             :       INTEGER, INTENT(IN)                                :: nr_frames
    5802             :       REAL(dp), DIMENSION(:, :), POINTER                 :: r_ref
    5803             :       INTEGER, INTENT(OUT)                               :: n_atoms
    5804             : 
    5805             :       CHARACTER(LEN=default_path_length)                 :: filename
    5806             :       CHARACTER(LEN=default_string_length)               :: dummy_char
    5807             :       INTEGER                                            :: i, j, natom
    5808             :       LOGICAL                                            :: explicit, my_end
    5809          12 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rptr
    5810             :       TYPE(section_vals_type), POINTER                   :: coord_section
    5811             : 
    5812          12 :       NULLIFY (rptr)
    5813             : 
    5814          58 :       DO i = 1, nr_frames
    5815          46 :          coord_section => section_vals_get_subs_vals(frame_section, "COORD", i_rep_section=i)
    5816          46 :          CALL section_vals_get(coord_section, explicit=explicit)
    5817             :          ! Cartesian Coordinates
    5818          58 :          IF (explicit) THEN
    5819             :             CALL section_vals_val_get(coord_section, "_DEFAULT_KEYWORD_", &
    5820           0 :                                       n_rep_val=natom)
    5821           0 :             IF (i == 1) THEN
    5822           0 :                ALLOCATE (r_ref(3*natom, nr_frames))
    5823           0 :                n_atoms = natom
    5824             :             ELSE
    5825           0 :                CPASSERT(3*natom == SIZE(r_ref, 1))
    5826             :             END IF
    5827           0 :             DO j = 1, natom
    5828             :                CALL section_vals_val_get(coord_section, "_DEFAULT_KEYWORD_", &
    5829           0 :                                          i_rep_val=j, r_vals=rptr)
    5830           0 :                r_ref((j - 1)*3 + 1:(j - 1)*3 + 3, i) = rptr(1:3)
    5831             :             END DO ! natom
    5832             :          ELSE
    5833             :             BLOCK
    5834             :                TYPE(cp_parser_type)               :: parser
    5835          46 :                CALL section_vals_val_get(frame_section, "COORD_FILE_NAME", i_rep_section=i, c_val=filename)
    5836          46 :                CPASSERT(TRIM(filename) /= "")
    5837          46 :                ALLOCATE (rptr(3))
    5838          46 :                CALL parser_create(parser, filename, para_env=para_env, parse_white_lines=.TRUE.)
    5839          46 :                CALL parser_get_next_line(parser, 1)
    5840             :                ! Start parser
    5841          46 :                CALL parser_get_object(parser, natom)
    5842          46 :                CALL parser_get_next_line(parser, 1)
    5843          46 :                IF (i == 1) THEN
    5844          48 :                   ALLOCATE (r_ref(3*natom, nr_frames))
    5845          12 :                   n_atoms = natom
    5846             :                ELSE
    5847          34 :                   CPASSERT(3*natom == SIZE(r_ref, 1))
    5848             :                END IF
    5849         798 :                DO j = 1, natom
    5850             :                   ! Atom coordinates
    5851         752 :                   CALL parser_get_next_line(parser, 1, at_end=my_end)
    5852         752 :                   IF (my_end) &
    5853             :                      CALL cp_abort(__LOCATION__, &
    5854             :                                    "Number of lines in XYZ format not equal to the number of atoms."// &
    5855             :                                    " Error in XYZ format for COORD_A (CV rmsd). Very probably the"// &
    5856           0 :                                    " line with title is missing or is empty. Please check the XYZ file and rerun your job!")
    5857         752 :                   READ (parser%input_line, *) dummy_char, rptr(1:3)
    5858         752 :                   r_ref((j - 1)*3 + 1, i) = cp_unit_to_cp2k(rptr(1), "angstrom")
    5859         752 :                   r_ref((j - 1)*3 + 2, i) = cp_unit_to_cp2k(rptr(2), "angstrom")
    5860         798 :                   r_ref((j - 1)*3 + 3, i) = cp_unit_to_cp2k(rptr(3), "angstrom")
    5861             :                END DO ! natom
    5862         230 :                CALL parser_release(parser)
    5863             :             END BLOCK
    5864          46 :             DEALLOCATE (rptr)
    5865             :          END IF
    5866             :       END DO ! nr_frames
    5867             : 
    5868          12 :    END SUBROUTINE read_frames
    5869             : 
    5870             : ! **************************************************************************************************
    5871             : !> \brief evaluates the collective variable associated with a hydrogen bond
    5872             : !> \param colvar ...
    5873             : !> \param cell ...
    5874             : !> \param subsys ...
    5875             : !> \param particles ...
    5876             : !> \param qs_env should be removed
    5877             : !> \author alin m elena
    5878             : ! **************************************************************************************************
    5879           0 :    SUBROUTINE Wc_colvar(colvar, cell, subsys, particles, qs_env)
    5880             :       TYPE(colvar_type), POINTER               :: colvar
    5881             :       TYPE(cell_type), POINTER                 :: cell
    5882             :       TYPE(cp_subsys_type), OPTIONAL, POINTER  :: subsys
    5883             :       TYPE(particle_type), DIMENSION(:), &
    5884             :          OPTIONAL, POINTER                      :: particles
    5885             :       TYPE(qs_environment_type), POINTER, OPTIONAL       :: qs_env
    5886             : 
    5887             :       INTEGER                                  :: Od, H, Oa
    5888             :       REAL(dp)                                 :: rOd(3), rOa(3), rH(3), &
    5889             :                                                   x, y, s(3), xv(3), dmin, amin
    5890             :       INTEGER                                  :: idmin, iamin, i, j
    5891             :       TYPE(particle_list_type), POINTER        :: particles_i
    5892             :       TYPE(particle_type), DIMENSION(:), &
    5893           0 :          POINTER                                :: my_particles
    5894           0 :       TYPE(wannier_centres_type), DIMENSION(:), POINTER :: wc
    5895           0 :       INTEGER, ALLOCATABLE                     :: wcai(:), wcdi(:)
    5896             :       INTEGER                                  :: nwca, nwcd
    5897             :       REAL(dp)                                 :: rcut
    5898             : 
    5899           0 :       NULLIFY (particles_i, wc)
    5900             : 
    5901           0 :       CPASSERT(colvar%type_id == Wc_colvar_id)
    5902           0 :       IF (PRESENT(particles)) THEN
    5903           0 :          my_particles => particles
    5904             :       ELSE
    5905           0 :          CPASSERT(PRESENT(subsys))
    5906           0 :          CALL cp_subsys_get(subsys, particles=particles_i)
    5907           0 :          my_particles => particles_i%els
    5908             :       END IF
    5909           0 :       CALL get_qs_env(qs_env, WannierCentres=wc)
    5910           0 :       rcut = colvar%Wc%rcut ! distances are in bohr as far as I remember
    5911           0 :       Od = colvar%Wc%ids(1)
    5912           0 :       H = colvar%Wc%ids(2)
    5913           0 :       Oa = colvar%Wc%ids(3)
    5914           0 :       CALL get_coordinates(colvar, Od, rOd, my_particles)
    5915           0 :       CALL get_coordinates(colvar, H, rH, my_particles)
    5916           0 :       CALL get_coordinates(colvar, Oa, rOa, my_particles)
    5917           0 :       ALLOCATE (wcai(SIZE(wc(1)%WannierHamDiag)))
    5918           0 :       ALLOCATE (wcdi(SIZE(wc(1)%WannierHamDiag)))
    5919           0 :       nwca = 0
    5920           0 :       nwcd = 0
    5921           0 :       DO j = 1, SIZE(wc(1)%WannierHamDiag)
    5922           0 :          x = distance(rOd - wc(1)%centres(:, j))
    5923           0 :          y = distance(rOa - wc(1)%centres(:, j))
    5924           0 :          IF (x < rcut) THEN
    5925           0 :             nwcd = nwcd + 1
    5926           0 :             wcdi(nwcd) = j
    5927           0 :             CYCLE
    5928             :          END IF
    5929           0 :          IF (y < rcut) THEN
    5930           0 :             nwca = nwca + 1
    5931           0 :             wcai(nwca) = j
    5932             :          END IF
    5933             :       END DO
    5934             : 
    5935           0 :       dmin = distance(rH - wc(1)%centres(:, wcdi(1)))
    5936           0 :       amin = distance(rH - wc(1)%centres(:, wcai(1)))
    5937           0 :       idmin = wcdi(1)
    5938           0 :       iamin = wcai(1)
    5939             :       !dmin constains the smallest numer, amin the next smallest
    5940           0 :       DO i = 2, nwcd
    5941           0 :          x = distance(rH - wc(1)%centres(:, wcdi(i)))
    5942           0 :          IF (x < dmin) THEN
    5943           0 :             dmin = x
    5944           0 :             idmin = wcdi(i)
    5945             :          END IF
    5946             :       END DO
    5947           0 :       DO i = 2, nwca
    5948           0 :          x = distance(rH - wc(1)%centres(:, wcai(i)))
    5949           0 :          IF (x < amin) THEN
    5950           0 :             amin = x
    5951           0 :             iamin = wcai(i)
    5952             :          END IF
    5953             :       END DO
    5954             : !     zero=0.0_dp
    5955             : !     CALL put_derivative(colvar, 1, zero)
    5956             : !     CALL put_derivative(colvar, 2,zero)
    5957             : !     CALL put_derivative(colvar, 3, zero)
    5958             : 
    5959             : !     write(*,'(2(i0,1x),4(f16.8,1x))')idmin,iamin,wc(1)%WannierHamDiag(idmin),wc(1)%WannierHamDiag(iamin),dmin,amin
    5960           0 :       colvar%ss = wc(1)%WannierHamDiag(idmin) - wc(1)%WannierHamDiag(iamin)
    5961           0 :       DEALLOCATE (wcai)
    5962           0 :       DEALLOCATE (wcdi)
    5963             : 
    5964             :    CONTAINS
    5965             : ! **************************************************************************************************
    5966             : !> \brief ...
    5967             : !> \param rij ...
    5968             : !> \return ...
    5969             : ! **************************************************************************************************
    5970           0 :       REAL(dp) FUNCTION distance(rij)
    5971             :       REAL(dp), INTENT(in)                               :: rij(3)
    5972             : 
    5973           0 :          s = MATMUL(cell%h_inv, rij)
    5974           0 :          s = s - NINT(s)
    5975           0 :          xv = MATMUL(cell%hmat, s)
    5976           0 :          distance = SQRT(DOT_PRODUCT(xv, xv))
    5977           0 :       END FUNCTION distance
    5978             : 
    5979             :    END SUBROUTINE Wc_colvar
    5980             : 
    5981             : ! **************************************************************************************************
    5982             : !> \brief evaluates the collective variable associated with a hydrogen bond wire
    5983             : !> \param colvar ...
    5984             : !> \param cell ...
    5985             : !> \param subsys ...
    5986             : !> \param particles ...
    5987             : !> \param qs_env ...
    5988             : !> \author alin m elena
    5989             : ! **************************************************************************************************
    5990          10 :    SUBROUTINE HBP_colvar(colvar, cell, subsys, particles, qs_env)
    5991             :       TYPE(colvar_type), POINTER               :: colvar
    5992             :       TYPE(cell_type), POINTER                 :: cell
    5993             :       TYPE(cp_subsys_type), OPTIONAL, POINTER  :: subsys
    5994             :       TYPE(particle_type), DIMENSION(:), &
    5995             :          OPTIONAL, POINTER                      :: particles
    5996             :       TYPE(qs_environment_type), POINTER, OPTIONAL       :: qs_env ! optional just because I am lazy... but I should get rid of it...
    5997             : 
    5998             :       INTEGER                                  :: Od, H, Oa
    5999             :       REAL(dp)                                 :: rOd(3), rOa(3), rH(3), &
    6000             :                                                   x, y, s(3), xv(3), dmin, amin
    6001             :       INTEGER                                  :: idmin, iamin, i, j, il, output_unit
    6002             :       TYPE(particle_list_type), POINTER        :: particles_i
    6003             :       TYPE(particle_type), DIMENSION(:), &
    6004          10 :          POINTER                                :: my_particles
    6005             :       TYPE(wannier_centres_type), &
    6006          10 :          DIMENSION(:), POINTER :: wc
    6007          10 :       INTEGER, ALLOCATABLE                     :: wcai(:), wcdi(:)
    6008             :       INTEGER                                  :: nwca, nwcd
    6009             :       REAL(dp)                                 :: rcut
    6010             : 
    6011          10 :       NULLIFY (particles_i, wc)
    6012          20 :       output_unit = cp_logger_get_default_io_unit()
    6013             : 
    6014          10 :       CPASSERT(colvar%type_id == HBP_colvar_id)
    6015          10 :       IF (PRESENT(particles)) THEN
    6016           0 :          my_particles => particles
    6017             :       ELSE
    6018          10 :          CPASSERT(PRESENT(subsys))
    6019          10 :          CALL cp_subsys_get(subsys, particles=particles_i)
    6020          10 :          my_particles => particles_i%els
    6021             :       END IF
    6022          10 :       CALL get_qs_env(qs_env, WannierCentres=wc)
    6023          10 :       rcut = colvar%HBP%rcut ! distances are in bohr as far as I remember
    6024          30 :       ALLOCATE (wcai(SIZE(wc(1)%WannierHamDiag)))
    6025          20 :       ALLOCATE (wcdi(SIZE(wc(1)%WannierHamDiag)))
    6026          10 :       colvar%ss = 0.0_dp
    6027          20 :       DO il = 1, colvar%HBP%nPoints
    6028          10 :          Od = colvar%HBP%ids(il, 1)
    6029          10 :          H = colvar%HBP%ids(il, 2)
    6030          10 :          Oa = colvar%HBP%ids(il, 3)
    6031          10 :          CALL get_coordinates(colvar, Od, rOd, my_particles)
    6032          10 :          CALL get_coordinates(colvar, H, rH, my_particles)
    6033          10 :          CALL get_coordinates(colvar, Oa, rOa, my_particles)
    6034          10 :          nwca = 0
    6035          10 :          nwcd = 0
    6036          90 :          DO j = 1, SIZE(wc(1)%WannierHamDiag)
    6037         320 :             x = distance(rOd - wc(1)%centres(:, j))
    6038         320 :             y = distance(rOa - wc(1)%centres(:, j))
    6039          80 :             IF (x < rcut) THEN
    6040          30 :                nwcd = nwcd + 1
    6041          30 :                wcdi(nwcd) = j
    6042          30 :                CYCLE
    6043             :             END IF
    6044          60 :             IF (y < rcut) THEN
    6045          26 :                nwca = nwca + 1
    6046          26 :                wcai(nwca) = j
    6047             :             END IF
    6048             :          END DO
    6049             : 
    6050          40 :          dmin = distance(rH - wc(1)%centres(:, wcdi(1)))
    6051          40 :          amin = distance(rH - wc(1)%centres(:, wcai(1)))
    6052          10 :          idmin = wcdi(1)
    6053          10 :          iamin = wcai(1)
    6054             :          !dmin constains the smallest numer, amin the next smallest
    6055          30 :          DO i = 2, nwcd
    6056          80 :             x = distance(rH - wc(1)%centres(:, wcdi(i)))
    6057          30 :             IF (x < dmin) THEN
    6058           2 :                dmin = x
    6059           2 :                idmin = wcdi(i)
    6060             :             END IF
    6061             :          END DO
    6062          26 :          DO i = 2, nwca
    6063          64 :             x = distance(rH - wc(1)%centres(:, wcai(i)))
    6064          26 :             IF (x < amin) THEN
    6065           8 :                amin = x
    6066           8 :                iamin = wcai(i)
    6067             :             END IF
    6068             :          END DO
    6069          10 :          colvar%HBP%ewc(il) = colvar%HBP%shift + wc(1)%WannierHamDiag(idmin) - wc(1)%WannierHamDiag(iamin)
    6070          20 :          colvar%ss = colvar%ss + colvar%HBP%shift + wc(1)%WannierHamDiag(idmin) - wc(1)%WannierHamDiag(iamin)
    6071             :       END DO
    6072          10 :       IF (output_unit > 0) THEN
    6073          10 :          DO il = 1, colvar%HBP%nPoints
    6074          10 :             WRITE (output_unit, '(a,1(f16.8,1x))') "HBP| = ", colvar%HBP%ewc(il)
    6075             :          END DO
    6076           5 :          WRITE (output_unit, '(a,1(f16.8,1x))') "HBP|\theta(x) = ", colvar%ss
    6077             :       END IF
    6078          10 :       DEALLOCATE (wcai)
    6079          20 :       DEALLOCATE (wcdi)
    6080             : 
    6081             :    CONTAINS
    6082             : ! **************************************************************************************************
    6083             : !> \brief ...
    6084             : !> \param rij ...
    6085             : !> \return ...
    6086             : ! **************************************************************************************************
    6087         216 :       REAL(dp) FUNCTION distance(rij)
    6088             :       REAL(dp), INTENT(in)                               :: rij(3)
    6089             : 
    6090        2808 :          s = MATMUL(cell%h_inv, rij)
    6091         864 :          s = s - NINT(s)
    6092        2808 :          xv = MATMUL(cell%hmat, s)
    6093         864 :          distance = SQRT(DOT_PRODUCT(xv, xv))
    6094         216 :       END FUNCTION distance
    6095             : 
    6096             :    END SUBROUTINE HBP_colvar
    6097             : 
    6098             : END MODULE colvar_methods

Generated by: LCOV version 1.15