LCOV - code coverage report
Current view: top level - src - colvar_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:06f838d) Lines: 80.9 % 3500 2831
Test Date: 2026-06-05 07:04:50 Functions: 89.6 % 48 43

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

Generated by: LCOV version 2.0-1