LCOV - code coverage report
Current view: top level - src - constraint_clv.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:9ccafda) Lines: 91.0 % 288 262
Test Date: 2026-10-15 00:55:44 Functions: 85.7 % 21 18

            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 Module that handles the COLLECTIVE constraints
      10              : !> \par History
      11              : !>      none
      12              : !> \author Teodoro Laino [tlaino]
      13              : ! **************************************************************************************************
      14              : MODULE constraint_clv
      15              :    USE cell_types,                      ONLY: cell_type
      16              :    USE colvar_methods,                  ONLY: colvar_eval_mol_f
      17              :    USE colvar_types,                    ONLY: colvar_type,&
      18              :                                               diff_colvar
      19              :    USE input_section_types,             ONLY: section_vals_get,&
      20              :                                               section_vals_get_subs_vals,&
      21              :                                               section_vals_type,&
      22              :                                               section_vals_val_get,&
      23              :                                               section_vals_val_set
      24              :    USE kinds,                           ONLY: dp
      25              :    USE molecule_kind_types,             ONLY: colvar_constraint_type,&
      26              :                                               fixd_constraint_type,&
      27              :                                               get_molecule_kind,&
      28              :                                               molecule_kind_type
      29              :    USE molecule_types,                  ONLY: get_molecule,&
      30              :                                               global_constraint_type,&
      31              :                                               local_colvar_constraint_type,&
      32              :                                               molecule_type
      33              :    USE particle_types,                  ONLY: particle_type
      34              : #include "./base/base_uses.f90"
      35              : 
      36              :    IMPLICIT NONE
      37              : 
      38              :    PRIVATE
      39              :    PUBLIC :: shake_roll_colv_int, &
      40              :              rattle_roll_colv_int, &
      41              :              shake_colv_int, &
      42              :              rattle_colv_int, &
      43              :              shake_roll_colv_ext, &
      44              :              rattle_roll_colv_ext, &
      45              :              shake_colv_ext, &
      46              :              rattle_colv_ext, &
      47              :              shake_update_colv_int, &
      48              :              shake_update_colv_ext, shake_update_colv_targets, shake_update_colv_low, check_colv_int
      49              : 
      50              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'constraint_clv'
      51              : 
      52              : CONTAINS
      53              : 
      54              : ! **************************************************************************************************
      55              : !> \brief Evaluate position or velocity residuals of local collective variables.
      56              : !> \param molecule ...
      57              : !> \param particle_set ...
      58              : !> \param cell ...
      59              : !> \param max_sigma ...
      60              : !> \param pos ...
      61              : !> \param vel ...
      62              : !> \param rmat ...
      63              : !> \param veps ...
      64              : ! **************************************************************************************************
      65          378 :    SUBROUTINE check_colv_int(molecule, particle_set, cell, max_sigma, pos, vel, rmat, veps)
      66              :       TYPE(molecule_type), POINTER                       :: molecule
      67              :       TYPE(particle_type), POINTER                       :: particle_set(:)
      68              :       TYPE(cell_type), POINTER                           :: cell
      69              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
      70              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: pos(:, :), vel(:, :), rmat(:, :), &
      71              :                                                             veps(:, :)
      72              : 
      73              :       INTEGER                                            :: iconst
      74              :       REAL(KIND=dp)                                      :: sigma
      75          378 :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
      76          378 :       TYPE(fixd_constraint_type), POINTER                :: fixd_list(:)
      77          378 :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
      78              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
      79              : 
      80          378 :       molecule_kind => molecule%molecule_kind
      81          378 :       CALL get_molecule_kind(molecule_kind, colv_list=colv_list, fixd_list=fixd_list)
      82          378 :       CALL get_molecule(molecule, lcolv=lcolv)
      83          378 :       IF (.NOT. ASSOCIATED(colv_list)) RETURN
      84          378 :       CPASSERT(PRESENT(pos) .NEQV. PRESENT(vel))
      85          378 :       DO iconst = 1, SIZE(colv_list)
      86            0 :          IF (colv_list(iconst)%restraint%active) CYCLE
      87          378 :          IF (PRESENT(pos)) THEN
      88              :             CALL colvar_eval_mol_f(lcolv(iconst)%colvar, cell, particles=particle_set, &
      89            0 :                                    pos=pos, fixd_list=fixd_list)
      90            0 :             sigma = diff_colvar(lcolv(iconst)%colvar, colv_list(iconst)%expected_value)
      91            0 :             max_sigma = MAX(max_sigma, ABS(sigma))
      92              :          ELSE
      93              :             sigma = rattle_con_eval(lcolv(iconst)%colvar_old, vel, roll=PRESENT(rmat), &
      94              :                                     rmat=rmat, veps=veps, particles=particle_set) - &
      95            0 :                     colv_list(iconst)%target_velocity
      96            0 :             max_sigma = MAX(max_sigma, rattle_colv_residual(sigma, colv_list(iconst)))
      97              :          END IF
      98              :       END DO
      99          378 :    END SUBROUTINE check_colv_int
     100              : 
     101              : ! **************************************************************************************************
     102              : !> \brief Intramolecular subroutine
     103              : !>      shake_colv algorithm for collective variables constraints
     104              : !>      updates the multiplier one molecule type at a time
     105              : !> \param molecule ...
     106              : !> \param particle_set ...
     107              : !> \param pos ...
     108              : !> \param vel ...
     109              : !> \param dt ...
     110              : !> \param ishake ...
     111              : !> \param cell ...
     112              : !> \param imass ...
     113              : !> \param max_sigma ...
     114              : !> \par History
     115              : !>      none
     116              : !> \author Teodoro Laino [tlaino]
     117              : ! **************************************************************************************************
     118        18617 :    SUBROUTINE shake_colv_int(molecule, particle_set, pos, vel, dt, ishake, &
     119        18617 :                              cell, imass, max_sigma)
     120              : 
     121              :       TYPE(molecule_type), POINTER                       :: molecule
     122              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     123              :       REAL(KIND=dp), INTENT(INOUT)                       :: pos(:, :), vel(:, :)
     124              :       REAL(kind=dp), INTENT(in)                          :: dt
     125              :       INTEGER, INTENT(IN)                                :: ishake
     126              :       TYPE(cell_type), POINTER                           :: cell
     127              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     128              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     129              : 
     130        18617 :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     131        18617 :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     132        18617 :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     133              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     134              : 
     135        18617 :       NULLIFY (fixd_list)
     136        18617 :       molecule_kind => molecule%molecule_kind
     137        18617 :       CALL get_molecule_kind(molecule_kind, colv_list=colv_list, fixd_list=fixd_list)
     138        18617 :       CALL get_molecule(molecule, lcolv=lcolv)
     139              :       ! Real Shake
     140              :       CALL shake_colv_low(fixd_list, colv_list, lcolv, &
     141        18617 :                           particle_set, pos, vel, dt, ishake, cell, imass, max_sigma)
     142              : 
     143        18617 :    END SUBROUTINE shake_colv_int
     144              : 
     145              : ! **************************************************************************************************
     146              : !> \brief Intramolecular subroutine for updating the TARGET value of collective
     147              : !>        constraints
     148              : !> \param molecule ...
     149              : !> \param dt ...
     150              : !> \param motion_section ...
     151              : !> \author Teodoro Laino [tlaino] - University of Zurich
     152              : ! **************************************************************************************************
     153            0 :    SUBROUTINE shake_update_colv_int(molecule, dt, motion_section)
     154              : 
     155              :       TYPE(molecule_type), POINTER                       :: molecule
     156              :       REAL(kind=dp), INTENT(in)                          :: dt
     157              :       TYPE(section_vals_type), POINTER                   :: motion_section
     158              : 
     159            0 :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     160              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     161              : 
     162            0 :       molecule_kind => molecule%molecule_kind
     163            0 :       CALL get_molecule_kind(molecule_kind, colv_list=colv_list)
     164              :       ! Real update of the Shake target
     165            0 :       CALL shake_update_colv_low(colv_list, dt, motion_section)
     166              : 
     167            0 :    END SUBROUTINE shake_update_colv_int
     168              : 
     169              : ! **************************************************************************************************
     170              : !> \brief Intramolecular subroutine
     171              : !>      rattle algorithm for collective variables constraints
     172              : !>      updates the multiplier one molecule type at a time
     173              : !> \param molecule ...
     174              : !> \param particle_set ...
     175              : !> \param vel ...
     176              : !> \param dt ...
     177              : !> \param irattle ...
     178              : !> \param cell ...
     179              : !> \param imass ...
     180              : !> \param max_sigma ...
     181              : !> \par History
     182              : !>      none
     183              : !> \author Teodoro Laino [tlaino]
     184              : ! **************************************************************************************************
     185         7848 :    SUBROUTINE rattle_colv_int(molecule, particle_set, vel, dt, irattle, &
     186         7848 :                               cell, imass, max_sigma)
     187              : 
     188              :       TYPE(molecule_type), POINTER                       :: molecule
     189              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     190              :       REAL(KIND=dp), INTENT(INOUT)                       :: vel(:, :)
     191              :       REAL(kind=dp), INTENT(in)                          :: dt
     192              :       INTEGER, INTENT(IN)                                :: irattle
     193              :       TYPE(cell_type), POINTER                           :: cell
     194              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     195              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     196              : 
     197         7848 :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     198         7848 :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     199         7848 :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     200              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     201              : 
     202         7848 :       NULLIFY (fixd_list)
     203         7848 :       molecule_kind => molecule%molecule_kind
     204         7848 :       CALL get_molecule_kind(molecule_kind, colv_list=colv_list, fixd_list=fixd_list)
     205         7848 :       CALL get_molecule(molecule, lcolv=lcolv)
     206              :       ! Real Rattle
     207              :       CALL rattle_colv_low(fixd_list, colv_list, lcolv, &
     208         7848 :                            particle_set, vel, dt, irattle, cell, imass, max_sigma)
     209              : 
     210         7848 :    END SUBROUTINE rattle_colv_int
     211              : 
     212              : ! **************************************************************************************************
     213              : !> \brief Intramolecular subroutine
     214              : !>      shake algorithm (box allowed to change) for collective variables constraints
     215              : !>      updates the multiplier one molecule type at a time
     216              : !> \param molecule ...
     217              : !> \param particle_set ...
     218              : !> \param pos ...
     219              : !> \param vel ...
     220              : !> \param r_shake ...
     221              : !> \param v_shake ...
     222              : !> \param dt ...
     223              : !> \param ishake ...
     224              : !> \param cell ...
     225              : !> \param imass ...
     226              : !> \param max_sigma ...
     227              : !> \par History
     228              : !>      none
     229              : !> \author Teodoro Laino [tlaino]
     230              : ! **************************************************************************************************
     231        15773 :    SUBROUTINE shake_roll_colv_int(molecule, particle_set, pos, vel, r_shake, v_shake, &
     232        15773 :                                   dt, ishake, cell, imass, max_sigma)
     233              : 
     234              :       TYPE(molecule_type), POINTER                       :: molecule
     235              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     236              :       REAL(KIND=dp), INTENT(INOUT)                       :: pos(:, :), vel(:, :)
     237              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: r_shake, v_shake
     238              :       REAL(kind=dp), INTENT(in)                          :: dt
     239              :       INTEGER, INTENT(in)                                :: ishake
     240              :       TYPE(cell_type), POINTER                           :: cell
     241              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     242              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     243              : 
     244        15773 :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     245        15773 :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     246        15773 :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     247              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     248              : 
     249        15773 :       NULLIFY (fixd_list)
     250        15773 :       molecule_kind => molecule%molecule_kind
     251        15773 :       CALL get_molecule_kind(molecule_kind, colv_list=colv_list, fixd_list=fixd_list)
     252        15773 :       CALL get_molecule(molecule, lcolv=lcolv)
     253              :       ! Real Shake
     254              :       CALL shake_roll_colv_low(fixd_list, colv_list, lcolv, &
     255              :                                particle_set, pos, vel, r_shake, v_shake, dt, ishake, cell, &
     256        15773 :                                imass, max_sigma)
     257              : 
     258        15773 :    END SUBROUTINE shake_roll_colv_int
     259              : 
     260              : ! **************************************************************************************************
     261              : !> \brief Intramolecular subroutine
     262              : !>      rattle algorithm (box allowed to change) for collective variables constraints
     263              : !>      updates the multiplier one molecule type at a time
     264              : !> \param molecule ...
     265              : !> \param particle_set ...
     266              : !> \param vel ...
     267              : !> \param r_rattle ...
     268              : !> \param dt ...
     269              : !> \param irattle ...
     270              : !> \param veps ...
     271              : !> \param cell ...
     272              : !> \param imass ...
     273              : !> \param max_sigma ...
     274              : !> \par History
     275              : !>      none
     276              : !> \author Teodoro Laino [tlaino]
     277              : ! **************************************************************************************************
     278         5521 :    SUBROUTINE rattle_roll_colv_int(molecule, particle_set, vel, r_rattle, &
     279         5521 :                                    dt, irattle, veps, cell, imass, max_sigma)
     280              : 
     281              :       TYPE(molecule_type), POINTER                       :: molecule
     282              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     283              :       REAL(KIND=dp), INTENT(INOUT)                       :: vel(:, :)
     284              :       REAL(KIND=dp), INTENT(IN)                          :: r_rattle(:, :), dt
     285              :       INTEGER, INTENT(in)                                :: irattle
     286              :       REAL(KIND=dp), INTENT(IN)                          :: veps(:, :)
     287              :       TYPE(cell_type), POINTER                           :: cell
     288              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     289              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     290              : 
     291         5521 :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     292         5521 :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     293         5521 :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     294              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     295              : 
     296         5521 :       NULLIFY (fixd_list)
     297         5521 :       molecule_kind => molecule%molecule_kind
     298         5521 :       CALL get_molecule_kind(molecule_kind, colv_list=colv_list, fixd_list=fixd_list)
     299         5521 :       CALL get_molecule(molecule, lcolv=lcolv)
     300              :       ! Real Rattle
     301              :       CALL rattle_roll_colv_low(fixd_list, colv_list, lcolv, &
     302              :                                 particle_set, vel, r_rattle, dt, irattle, veps, cell, &
     303         5521 :                                 imass, max_sigma)
     304              : 
     305         5521 :    END SUBROUTINE rattle_roll_colv_int
     306              : 
     307              : ! **************************************************************************************************
     308              : !> \brief Intermolecular subroutine
     309              : !>      shake_colv algorithm for collective variables constraints
     310              : !>      updates the multiplier one molecule type at a time
     311              : !> \param gci ...
     312              : !> \param particle_set ...
     313              : !> \param pos ...
     314              : !> \param vel ...
     315              : !> \param dt ...
     316              : !> \param ishake ...
     317              : !> \param cell ...
     318              : !> \param imass ...
     319              : !> \param max_sigma ...
     320              : !> \par History
     321              : !>      none
     322              : !> \author Teodoro Laino [tlaino]
     323              : ! **************************************************************************************************
     324         1887 :    SUBROUTINE shake_colv_ext(gci, particle_set, pos, vel, dt, ishake, &
     325         1887 :                              cell, imass, max_sigma)
     326              : 
     327              :       TYPE(global_constraint_type), POINTER              :: gci
     328              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     329              :       REAL(KIND=dp), INTENT(INOUT)                       :: pos(:, :), vel(:, :)
     330              :       REAL(kind=dp), INTENT(in)                          :: dt
     331              :       INTEGER, INTENT(IN)                                :: ishake
     332              :       TYPE(cell_type), POINTER                           :: cell
     333              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     334              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     335              : 
     336              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     337              :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     338              :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     339              : 
     340         1887 :       colv_list => gci%colv_list
     341         1887 :       fixd_list => gci%fixd_list
     342         1887 :       lcolv => gci%lcolv
     343              :       ! Real Shake
     344              :       CALL shake_colv_low(fixd_list, colv_list, lcolv, &
     345         1887 :                           particle_set, pos, vel, dt, ishake, cell, imass, max_sigma)
     346              : 
     347         1887 :    END SUBROUTINE shake_colv_ext
     348              : 
     349              : ! **************************************************************************************************
     350              : !> \brief Intermolecular subroutine for updating the TARGET value for collective
     351              : !>        constraints
     352              : !> \param gci ...
     353              : !> \param dt ...
     354              : !> \param motion_section ...
     355              : !> \author Teodoro Laino [tlaino]
     356              : ! **************************************************************************************************
     357         1254 :    SUBROUTINE shake_update_colv_ext(gci, dt, motion_section)
     358              : 
     359              :       TYPE(global_constraint_type), POINTER              :: gci
     360              :       REAL(kind=dp), INTENT(in)                          :: dt
     361              :       TYPE(section_vals_type), POINTER                   :: motion_section
     362              : 
     363              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     364              : 
     365         1254 :       colv_list => gci%colv_list
     366              :       ! Real update of the Shake target
     367         1254 :       CALL shake_update_colv_low(colv_list, dt, motion_section)
     368              : 
     369         1254 :    END SUBROUTINE shake_update_colv_ext
     370              : 
     371              : ! **************************************************************************************************
     372              : !> \brief Intermolecular subroutine
     373              : !>      rattle algorithm for collective variables constraints
     374              : !>      updates the multiplier one molecule type at a time
     375              : !> \param gci ...
     376              : !> \param particle_set ...
     377              : !> \param vel ...
     378              : !> \param dt ...
     379              : !> \param irattle ...
     380              : !> \param cell ...
     381              : !> \param imass ...
     382              : !> \param max_sigma ...
     383              : !> \par History
     384              : !>      none
     385              : !> \author Teodoro Laino [tlaino]
     386              : ! **************************************************************************************************
     387         1734 :    SUBROUTINE rattle_colv_ext(gci, particle_set, vel, dt, irattle, &
     388         1734 :                               cell, imass, max_sigma)
     389              : 
     390              :       TYPE(global_constraint_type), POINTER              :: gci
     391              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     392              :       REAL(KIND=dp), INTENT(INOUT)                       :: vel(:, :)
     393              :       REAL(kind=dp), INTENT(in)                          :: dt
     394              :       INTEGER, INTENT(IN)                                :: irattle
     395              :       TYPE(cell_type), POINTER                           :: cell
     396              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     397              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     398              : 
     399              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     400              :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     401              :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     402              : 
     403         1734 :       colv_list => gci%colv_list
     404         1734 :       fixd_list => gci%fixd_list
     405         1734 :       lcolv => gci%lcolv
     406              :       ! Real Rattle
     407              :       CALL rattle_colv_low(fixd_list, colv_list, lcolv, &
     408         1734 :                            particle_set, vel, dt, irattle, cell, imass, max_sigma)
     409              : 
     410         1734 :    END SUBROUTINE rattle_colv_ext
     411              : 
     412              : ! **************************************************************************************************
     413              : !> \brief Intermolecular subroutine
     414              : !>      shake algorithm (box allowed to change) for collective variables constraints
     415              : !>      updates the multiplier one molecule type at a time
     416              : !> \param gci ...
     417              : !> \param particle_set ...
     418              : !> \param pos ...
     419              : !> \param vel ...
     420              : !> \param r_shake ...
     421              : !> \param v_shake ...
     422              : !> \param dt ...
     423              : !> \param ishake ...
     424              : !> \param cell ...
     425              : !> \param imass ...
     426              : !> \param max_sigma ...
     427              : !> \par History
     428              : !>      none
     429              : !> \author Teodoro Laino [tlaino]
     430              : ! **************************************************************************************************
     431            0 :    SUBROUTINE shake_roll_colv_ext(gci, particle_set, pos, vel, r_shake, v_shake, &
     432            0 :                                   dt, ishake, cell, imass, max_sigma)
     433              : 
     434              :       TYPE(global_constraint_type), POINTER              :: gci
     435              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     436              :       REAL(KIND=dp), INTENT(INOUT)                       :: pos(:, :), vel(:, :)
     437              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: r_shake, v_shake
     438              :       REAL(kind=dp), INTENT(in)                          :: dt
     439              :       INTEGER, INTENT(in)                                :: ishake
     440              :       TYPE(cell_type), POINTER                           :: cell
     441              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     442              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     443              : 
     444              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     445              :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     446              :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     447              : 
     448            0 :       colv_list => gci%colv_list
     449            0 :       fixd_list => gci%fixd_list
     450            0 :       lcolv => gci%lcolv
     451              :       ! Real Shake
     452              :       CALL shake_roll_colv_low(fixd_list, colv_list, lcolv, &
     453              :                                particle_set, pos, vel, r_shake, v_shake, dt, ishake, cell, &
     454            0 :                                imass, max_sigma)
     455              : 
     456            0 :    END SUBROUTINE shake_roll_colv_ext
     457              : 
     458              : ! **************************************************************************************************
     459              : !> \brief Intermolecular subroutine
     460              : !>      rattle algorithm (box allowed to change) for collective variables constraints
     461              : !>      updates the multiplier one molecule type at a time
     462              : !> \param gci ...
     463              : !> \param particle_set ...
     464              : !> \param vel ...
     465              : !> \param r_rattle ...
     466              : !> \param dt ...
     467              : !> \param irattle ...
     468              : !> \param veps ...
     469              : !> \param cell ...
     470              : !> \param imass ...
     471              : !> \param max_sigma ...
     472              : !> \par History
     473              : !>      none
     474              : !> \author Teodoro Laino [tlaino]
     475              : ! **************************************************************************************************
     476            0 :    SUBROUTINE rattle_roll_colv_ext(gci, particle_set, vel, r_rattle, &
     477            0 :                                    dt, irattle, veps, cell, imass, max_sigma)
     478              : 
     479              :       TYPE(global_constraint_type), POINTER              :: gci
     480              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     481              :       REAL(KIND=dp), INTENT(INOUT)                       :: vel(:, :)
     482              :       REAL(KIND=dp), INTENT(IN)                          :: r_rattle(:, :), dt
     483              :       INTEGER, INTENT(in)                                :: irattle
     484              :       REAL(KIND=dp), INTENT(IN)                          :: veps(:, :)
     485              :       TYPE(cell_type), POINTER                           :: cell
     486              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     487              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     488              : 
     489              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     490              :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     491              :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     492              : 
     493            0 :       colv_list => gci%colv_list
     494            0 :       fixd_list => gci%fixd_list
     495            0 :       lcolv => gci%lcolv
     496              :       ! Real Rattle
     497              :       CALL rattle_roll_colv_low(fixd_list, colv_list, lcolv, &
     498              :                                 particle_set, vel, r_rattle, dt, irattle, veps, cell, &
     499            0 :                                 imass, max_sigma)
     500              : 
     501            0 :    END SUBROUTINE rattle_roll_colv_ext
     502              : 
     503              : ! **************************************************************************************************
     504              : !> \brief Real Shake subroutine - Low Level
     505              : !>      shake_colv algorithm for collective variables constraints
     506              : !>      updates the multiplier one molecule type at a time
     507              : !> \param fixd_list ...
     508              : !> \param colv_list ...
     509              : !> \param lcolv ...
     510              : !> \param particle_set ...
     511              : !> \param pos ...
     512              : !> \param vel ...
     513              : !> \param dt ...
     514              : !> \param ishake ...
     515              : !> \param cell ...
     516              : !> \param imass ...
     517              : !> \param max_sigma ...
     518              : !> \par History
     519              : !>      none
     520              : !> \author Teodoro Laino [tlaino]
     521              : ! **************************************************************************************************
     522        20504 :    SUBROUTINE shake_colv_low(fixd_list, colv_list, lcolv, &
     523        20504 :                              particle_set, pos, vel, dt, ishake, cell, imass, max_sigma)
     524              :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     525              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     526              :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     527              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     528              :       REAL(KIND=dp), INTENT(INOUT)                       :: pos(:, :), vel(:, :)
     529              :       REAL(kind=dp), INTENT(in)                          :: dt
     530              :       INTEGER, INTENT(IN)                                :: ishake
     531              :       TYPE(cell_type), POINTER                           :: cell
     532              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     533              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     534              : 
     535              :       INTEGER                                            :: iconst
     536              :       REAL(KIND=dp)                                      :: del_lam, dtby2, dtsqby2, fdotf_sum
     537              : 
     538        20504 :       dtsqby2 = dt*dt*.5_dp
     539        20504 :       dtby2 = dt*.5_dp
     540        20504 :       IF (ishake == 1) THEN
     541        10120 :          DO iconst = 1, SIZE(colv_list)
     542         6935 :             IF (colv_list(iconst)%restraint%active) CYCLE
     543              :             ! Update positions
     544              :             CALL update_con_colv(pos, dtsqby2, lcolv(iconst), &
     545              :                                  lambda=lcolv(iconst)%lambda, &
     546         6015 :                                  imass=imass)
     547              :             ! Update velocities
     548              :             CALL update_con_colv(vel, dtby2, lcolv(iconst), &
     549              :                                  lambda=lcolv(iconst)%lambda, &
     550        10120 :                                  imass=imass)
     551              :          END DO
     552              :       ELSE
     553       106879 :          DO iconst = 1, SIZE(colv_list)
     554        89560 :             IF (colv_list(iconst)%restraint%active) CYCLE
     555              :             ! Update colvar
     556              :             CALL colvar_eval_mol_f(lcolv(iconst)%colvar, cell, particles=particle_set, &
     557        89526 :                                    pos=pos, fixd_list=fixd_list)
     558              :             lcolv(iconst)%sigma = diff_colvar(lcolv(iconst)%colvar, &
     559        89526 :                                               colv_list(iconst)%expected_value)
     560              :             fdotf_sum = eval_Jac_colvar(lcolv(iconst)%colvar, &
     561        89526 :                                         lcolv(iconst)%colvar_old, imass=imass)
     562        89526 :             del_lam = 2.0_dp*lcolv(iconst)%sigma/(dt*dt*fdotf_sum)
     563        89526 :             lcolv(iconst)%lambda = lcolv(iconst)%lambda + del_lam
     564              : 
     565              :             ! Update positions
     566              :             CALL update_con_colv(pos, dtsqby2, lcolv(iconst), &
     567              :                                  lambda=del_lam, &
     568        89526 :                                  imass=imass)
     569              :             ! Update velocities
     570              :             CALL update_con_colv(vel, dtby2, lcolv(iconst), &
     571              :                                  lambda=del_lam, &
     572       106879 :                                  imass=imass)
     573              :          END DO
     574              :       END IF
     575              :       ! computing the constraint and value of tolerance
     576       116999 :       DO iconst = 1, SIZE(colv_list)
     577        96495 :          IF (colv_list(iconst)%restraint%active) CYCLE
     578              :          CALL colvar_eval_mol_f(lcolv(iconst)%colvar, cell, particles=particle_set, &
     579        95541 :                                 pos=pos, fixd_list=fixd_list)
     580              :          lcolv(iconst)%sigma = diff_colvar(lcolv(iconst)%colvar, &
     581        95541 :                                            colv_list(iconst)%expected_value)
     582       116999 :          max_sigma = MAX(ABS(lcolv(iconst)%sigma), max_sigma)
     583              :       END DO
     584        20504 :    END SUBROUTINE shake_colv_low
     585              : 
     586              : ! **************************************************************************************************
     587              : !> \brief Real Shake subroutine - Low Level - for updating the TARGET value
     588              : !> \param dt ...
     589              : !> \param motion_section ...
     590              : !> \date 02.2008
     591              : !> \author Teodoro Laino [tlaino] - University of Zurich
     592              : ! **************************************************************************************************
     593        34108 :    SUBROUTINE shake_update_colv_targets(dt, motion_section)
     594              :       REAL(kind=dp), INTENT(in)                          :: dt
     595              :       TYPE(section_vals_type), POINTER                   :: motion_section
     596              : 
     597              :       INTEGER                                            :: irep, n_rep
     598              :       LOGICAL                                            :: do_update_colvar, explicit
     599              :       REAL(KIND=dp)                                      :: clv_target, limit, new_clv_target, value
     600              :       TYPE(section_vals_type), POINTER                   :: collective_sections
     601              : 
     602              : ! Update globally for restart
     603              : 
     604        17054 :       collective_sections => section_vals_get_subs_vals(motion_section, "CONSTRAINT%COLLECTIVE")
     605        17054 :       CALL section_vals_get(collective_sections, n_repetition=n_rep)
     606        17054 :       IF (n_rep /= 0) THEN
     607         8788 :          DO irep = 1, n_rep
     608              :             CALL section_vals_val_get(collective_sections, "TARGET_GROWTH", r_val=value, &
     609         5752 :                                       i_rep_section=irep)
     610         8788 :             IF (value /= 0.0_dp) THEN
     611              :                CALL section_vals_val_get(collective_sections, "TARGET", r_val=clv_target, &
     612          520 :                                          i_rep_section=irep)
     613          520 :                new_clv_target = clv_target + value*dt
     614              :                ! Check limits..
     615              :                CALL section_vals_val_get(collective_sections, "TARGET_LIMIT", explicit=explicit, &
     616          520 :                                          i_rep_section=irep)
     617          520 :                do_update_colvar = .TRUE.
     618          520 :                IF (explicit) THEN
     619              :                   CALL section_vals_val_get(collective_sections, "TARGET_LIMIT", r_val=limit, &
     620          320 :                                             i_rep_section=irep)
     621          320 :                   IF (value > 0.0_dp) THEN
     622          180 :                      IF (clv_target == limit) THEN
     623              :                         do_update_colvar = .FALSE.
     624          124 :                      ELSE IF (new_clv_target >= limit) THEN
     625            2 :                         new_clv_target = limit
     626              :                      END IF
     627              :                   ELSE
     628          140 :                      IF (clv_target == limit) THEN
     629              :                         do_update_colvar = .FALSE.
     630          118 :                      ELSE IF (new_clv_target <= limit) THEN
     631            2 :                         new_clv_target = limit
     632              :                      END IF
     633              :                   END IF
     634              :                END IF
     635              :                IF (do_update_colvar) THEN
     636              :                   CALL section_vals_val_set(collective_sections, "TARGET", r_val=new_clv_target, &
     637          442 :                                             i_rep_section=irep)
     638              :                END IF
     639              :             END IF
     640              :          END DO
     641              :       END IF
     642              : 
     643        17054 :    END SUBROUTINE shake_update_colv_targets
     644              : 
     645              : ! **************************************************************************************************
     646              : !> \brief Cache the actual target rate, including a partially clamped interval.
     647              : !> \param colv_list ...
     648              : !> \param dt ...
     649              : !> \param motion_section ...
     650              : !> \param initialize ...
     651              : ! **************************************************************************************************
     652        53424 :    SUBROUTINE shake_update_colv_low(colv_list, dt, motion_section, initialize)
     653              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     654              :       REAL(KIND=dp), INTENT(IN)                          :: dt
     655              :       TYPE(section_vals_type), POINTER                   :: motion_section
     656              :       LOGICAL, INTENT(IN), OPTIONAL                      :: initialize
     657              : 
     658              :       INTEGER                                            :: iconst
     659              :       LOGICAL                                            :: explicit, initial
     660              :       REAL(KIND=dp)                                      :: limit, next_target, old_target, speed
     661              :       TYPE(section_vals_type), POINTER                   :: collective_sections
     662              : 
     663        53424 :       initial = .FALSE.
     664        53424 :       IF (PRESENT(initialize)) initial = initialize
     665        53424 :       collective_sections => section_vals_get_subs_vals(motion_section, "CONSTRAINT%COLLECTIVE")
     666        61938 :       DO iconst = 1, SIZE(colv_list)
     667         8514 :          colv_list(iconst)%target_velocity = 0.0_dp
     668         8514 :          IF (colv_list(iconst)%expected_value_growth_speed == 0.0_dp) CYCLE
     669          534 :          old_target = colv_list(iconst)%expected_value
     670              :          CALL section_vals_val_get(collective_sections, "TARGET", &
     671              :                                    r_val=next_target, &
     672          534 :                                    i_rep_section=colv_list(iconst)%inp_seq_num)
     673          534 :          IF (initial) THEN
     674           14 :             speed = colv_list(iconst)%expected_value_growth_speed
     675           14 :             next_target = old_target + speed*dt
     676              :             CALL section_vals_val_get(collective_sections, "TARGET_LIMIT", explicit=explicit, &
     677           14 :                                       i_rep_section=colv_list(iconst)%inp_seq_num)
     678           14 :             IF (explicit) THEN
     679              :                CALL section_vals_val_get(collective_sections, "TARGET_LIMIT", r_val=limit, &
     680           10 :                                          i_rep_section=colv_list(iconst)%inp_seq_num)
     681           10 :                IF (speed > 0.0_dp) next_target = MIN(next_target, limit)
     682           10 :                IF (speed < 0.0_dp) next_target = MAX(next_target, limit)
     683              :             END IF
     684              :          ELSE
     685          520 :             colv_list(iconst)%expected_value = next_target
     686              :          END IF
     687        62472 :          colv_list(iconst)%target_velocity = (next_target - old_target)/dt
     688              :       END DO
     689              : 
     690        53424 :    END SUBROUTINE shake_update_colv_low
     691              : 
     692              : ! **************************************************************************************************
     693              : !> \brief Real Rattle - Low Level
     694              : !>      rattle algorithm for collective variables constraints
     695              : !>      updates the multiplier one molecule type at a time
     696              : !> \param fixd_list ...
     697              : !> \param colv_list ...
     698              : !> \param lcolv ...
     699              : !> \param particle_set ...
     700              : !> \param vel ...
     701              : !> \param dt ...
     702              : !> \param irattle ...
     703              : !> \param cell ...
     704              : !> \param imass ...
     705              : !> \param max_sigma ...
     706              : !> \par History
     707              : !>      none
     708              : !> \author Teodoro Laino [tlaino]
     709              : ! **************************************************************************************************
     710         9582 :    SUBROUTINE rattle_colv_low(fixd_list, colv_list, lcolv, &
     711         9582 :                               particle_set, vel, dt, irattle, cell, imass, max_sigma)
     712              : 
     713              :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     714              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     715              :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     716              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     717              :       REAL(KIND=dp), INTENT(INOUT)                       :: vel(:, :)
     718              :       REAL(kind=dp), INTENT(in)                          :: dt
     719              :       INTEGER, INTENT(IN)                                :: irattle
     720              :       TYPE(cell_type), POINTER                           :: cell
     721              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     722              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     723              : 
     724              :       INTEGER                                            :: iconst
     725              :       REAL(KIND=dp)                                      :: del_lam, dtby2, fdotf_sum
     726              : 
     727         9582 :       dtby2 = dt*.5_dp
     728         9582 :       IF (irattle == 1) THEN
     729        10150 :          DO iconst = 1, SIZE(colv_list)
     730         6951 :             IF (colv_list(iconst)%restraint%active) CYCLE
     731              :             ! Update colvar_old
     732              :             CALL colvar_eval_mol_f(lcolv(iconst)%colvar_old, cell, &
     733         6031 :                                    particles=particle_set, fixd_list=fixd_list)
     734              :             ! Update velocities
     735              :             CALL update_con_colv(vel, dtby2, lcolv(iconst), &
     736              :                                  lambda=lcolv(iconst)%lambda, &
     737        10150 :                                  imass=imass)
     738              :          END DO
     739              :       ELSE
     740        35888 :          DO iconst = 1, SIZE(colv_list)
     741        29505 :             IF (colv_list(iconst)%restraint%active) CYCLE
     742              :             lcolv(iconst)%sigma = rattle_con_eval(lcolv(iconst)%colvar_old, vel) - &
     743        29485 :                                   colv_list(iconst)%target_velocity
     744              :             fdotf_sum = eval_Jac_colvar(lcolv(iconst)%colvar_old, &
     745        29485 :                                         lcolv(iconst)%colvar_old, imass=imass)
     746        29485 :             del_lam = 2.0_dp*lcolv(iconst)%sigma/(dt*fdotf_sum)
     747        29485 :             lcolv(iconst)%lambda = lcolv(iconst)%lambda + del_lam
     748              : 
     749              :             ! Update velocities
     750              :             CALL update_con_colv(vel, dtby2, lcolv(iconst), &
     751              :                                  lambda=del_lam, &
     752        35888 :                                  imass=imass)
     753              :          END DO
     754              :       END IF
     755              : 
     756        46038 :       DO iconst = 1, SIZE(colv_list)
     757        36456 :          IF (colv_list(iconst)%restraint%active) CYCLE
     758              :          lcolv(iconst)%sigma = rattle_con_eval(lcolv(iconst)%colvar_old, vel) - &
     759        35516 :                                colv_list(iconst)%target_velocity
     760        46038 :          max_sigma = MAX(rattle_colv_residual(lcolv(iconst)%sigma, colv_list(iconst)), max_sigma)
     761              :       END DO
     762              : 
     763         9582 :    END SUBROUTINE rattle_colv_low
     764              : 
     765              : ! **************************************************************************************************
     766              : !> \brief Real shake_roll - Low Level
     767              : !>      shake algorithm (box allowed to change) for collective variables constraints
     768              : !>      updates the multiplier one molecule type at a time
     769              : !> \param fixd_list ...
     770              : !> \param colv_list ...
     771              : !> \param lcolv ...
     772              : !> \param particle_set ...
     773              : !> \param pos ...
     774              : !> \param vel ...
     775              : !> \param r_shake ...
     776              : !> \param v_shake ...
     777              : !> \param dt ...
     778              : !> \param ishake ...
     779              : !> \param cell ...
     780              : !> \param imass ...
     781              : !> \param max_sigma ...
     782              : !> \par History
     783              : !>      none
     784              : !> \author Teodoro Laino [tlaino]
     785              : ! **************************************************************************************************
     786        15773 :    SUBROUTINE shake_roll_colv_low(fixd_list, colv_list, lcolv, &
     787        31546 :                                   particle_set, pos, vel, r_shake, v_shake, dt, ishake, cell, &
     788        15773 :                                   imass, max_sigma)
     789              : 
     790              :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     791              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     792              :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     793              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     794              :       REAL(KIND=dp), INTENT(INOUT)                       :: pos(:, :), vel(:, :)
     795              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: r_shake, v_shake
     796              :       REAL(kind=dp), INTENT(in)                          :: dt
     797              :       INTEGER, INTENT(in)                                :: ishake
     798              :       TYPE(cell_type), POINTER                           :: cell
     799              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     800              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     801              : 
     802              :       INTEGER                                            :: iconst
     803              :       REAL(KIND=dp)                                      :: del_lam, dtby2, dtsqby2, fdotf_sum
     804              : 
     805        15773 :       dtsqby2 = dt*dt*.5_dp
     806        15773 :       dtby2 = dt*.5_dp
     807        15773 :       IF (ishake == 1) THEN
     808         8664 :          DO iconst = 1, SIZE(colv_list)
     809         7312 :             IF (colv_list(iconst)%restraint%active) CYCLE
     810              :             ! Update positions
     811              :             CALL update_con_colv(pos, dtsqby2, lcolv(iconst), &
     812              :                                  lambda=lcolv(iconst)%lambda, &
     813         7312 :                                  roll=.TRUE., rmat=r_shake, imass=imass)
     814              :             ! Update velocities
     815              :             CALL update_con_colv(vel, dtby2, lcolv(iconst), &
     816              :                                  lambda=lcolv(iconst)%lambda, &
     817         8664 :                                  roll=.TRUE., rmat=v_shake, imass=imass)
     818              :          END DO
     819              :       ELSE
     820       100275 :          DO iconst = 1, SIZE(colv_list)
     821        85854 :             IF (colv_list(iconst)%restraint%active) CYCLE
     822              :             ! Update colvar
     823              :             CALL colvar_eval_mol_f(lcolv(iconst)%colvar, cell, particles=particle_set, &
     824        85854 :                                    pos=pos, fixd_list=fixd_list)
     825              :             lcolv(iconst)%sigma = diff_colvar(lcolv(iconst)%colvar, &
     826        85854 :                                               colv_list(iconst)%expected_value)
     827              :             fdotf_sum = eval_Jac_colvar(lcolv(iconst)%colvar, &
     828              :                                         lcolv(iconst)%colvar_old, roll=.TRUE., rmat=r_shake, &
     829        85854 :                                         imass=imass)
     830        85854 :             del_lam = 2.0_dp*lcolv(iconst)%sigma/(dt*dt*fdotf_sum)
     831        85854 :             lcolv(iconst)%lambda = lcolv(iconst)%lambda + del_lam
     832              : 
     833              :             ! Update positions
     834              :             CALL update_con_colv(pos, dtsqby2, lcolv(iconst), &
     835              :                                  lambda=del_lam, &
     836        85854 :                                  roll=.TRUE., rmat=r_shake, imass=imass)
     837              :             ! Update velocities
     838              :             CALL update_con_colv(vel, dtby2, lcolv(iconst), &
     839              :                                  lambda=del_lam, &
     840       100275 :                                  roll=.TRUE., rmat=v_shake, imass=imass)
     841              :          END DO
     842              :       END IF
     843              :       ! computing the constraint and value of tolerance
     844       108939 :       DO iconst = 1, SIZE(colv_list)
     845        93166 :          IF (colv_list(iconst)%restraint%active) CYCLE
     846              :          CALL colvar_eval_mol_f(lcolv(iconst)%colvar, cell, particles=particle_set, &
     847        93166 :                                 pos=pos, fixd_list=fixd_list)
     848              :          lcolv(iconst)%sigma = diff_colvar(lcolv(iconst)%colvar, &
     849        93166 :                                            colv_list(iconst)%expected_value)
     850       108939 :          max_sigma = MAX(ABS(lcolv(iconst)%sigma), max_sigma)
     851              :       END DO
     852              : 
     853        15773 :    END SUBROUTINE shake_roll_colv_low
     854              : 
     855              : ! **************************************************************************************************
     856              : !> \brief Real Rattle_roll - Low Level
     857              : !>      rattle algorithm (box allowed to change) for collective variables constraints
     858              : !>      updates the multiplier one molecule type at a time
     859              : !> \param fixd_list ...
     860              : !> \param colv_list ...
     861              : !> \param lcolv ...
     862              : !> \param particle_set ...
     863              : !> \param vel ...
     864              : !> \param r_rattle ...
     865              : !> \param dt ...
     866              : !> \param irattle ...
     867              : !> \param veps ...
     868              : !> \param cell ...
     869              : !> \param imass ...
     870              : !> \param max_sigma ...
     871              : !> \par History
     872              : !>      none
     873              : !> \author Teodoro Laino [tlaino]
     874              : ! **************************************************************************************************
     875         5521 :    SUBROUTINE rattle_roll_colv_low(fixd_list, colv_list, lcolv, &
     876        11042 :                                    particle_set, vel, r_rattle, dt, irattle, veps, cell, &
     877         5521 :                                    imass, max_sigma)
     878              : 
     879              :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     880              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     881              :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     882              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     883              :       REAL(KIND=dp), INTENT(INOUT)                       :: vel(:, :)
     884              :       REAL(KIND=dp), INTENT(IN)                          :: r_rattle(:, :), dt
     885              :       INTEGER, INTENT(in)                                :: irattle
     886              :       REAL(KIND=dp), INTENT(IN)                          :: veps(:, :)
     887              :       TYPE(cell_type), POINTER                           :: cell
     888              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     889              :       REAL(KIND=dp), INTENT(INOUT)                       :: max_sigma
     890              : 
     891              :       INTEGER                                            :: iconst
     892              :       REAL(KIND=dp)                                      :: del_lam, dtby2, fdotf_sum
     893              : 
     894         5521 :       dtby2 = dt*.5_dp
     895         5521 :       IF (irattle == 1) THEN
     896         7957 :          DO iconst = 1, SIZE(colv_list)
     897         6670 :             IF (colv_list(iconst)%restraint%active) CYCLE
     898              :             ! Update colvar_old
     899              :             CALL colvar_eval_mol_f(lcolv(iconst)%colvar_old, cell, &
     900         6670 :                                    particles=particle_set, fixd_list=fixd_list)
     901              :             ! Update velocities
     902              :             CALL update_con_colv(vel, dtby2, lcolv(iconst), &
     903              :                                  lambda=lcolv(iconst)%lambda, &
     904         7957 :                                  imass=imass)
     905              :          END DO
     906              :       ELSE
     907        29110 :          DO iconst = 1, SIZE(colv_list)
     908        24876 :             IF (colv_list(iconst)%restraint%active) CYCLE
     909              :             lcolv(iconst)%sigma = rattle_con_eval(lcolv(iconst)%colvar_old, vel, &
     910              :                                                   roll=.TRUE., veps=veps, rmat=r_rattle, particles=particle_set) - &
     911        24876 :                                   colv_list(iconst)%target_velocity
     912              :             fdotf_sum = eval_Jac_colvar(lcolv(iconst)%colvar_old, &
     913              :                                         lcolv(iconst)%colvar_old, roll=.TRUE., &
     914        24876 :                                         rmat=r_rattle, imass=imass)
     915        24876 :             del_lam = 2.0_dp*lcolv(iconst)%sigma/(dt*fdotf_sum)
     916        24876 :             lcolv(iconst)%lambda = lcolv(iconst)%lambda + del_lam
     917              :             ! Update velocities
     918              :             CALL update_con_colv(vel, dtby2, lcolv(iconst), &
     919              :                                  lambda=del_lam, &
     920        29110 :                                  roll=.TRUE., rmat=r_rattle, imass=imass)
     921              :          END DO
     922              :       END IF
     923              :       ! computing the constraint and value of the tolerance
     924        37067 :       DO iconst = 1, SIZE(colv_list)
     925        31546 :          IF (colv_list(iconst)%restraint%active) CYCLE
     926              :          lcolv(iconst)%sigma = rattle_con_eval(lcolv(iconst)%colvar_old, vel, &
     927              :                                                roll=.TRUE., veps=veps, rmat=r_rattle, particles=particle_set) - &
     928        31546 :                                colv_list(iconst)%target_velocity
     929        37067 :          max_sigma = MAX(rattle_colv_residual(lcolv(iconst)%sigma, colv_list(iconst)), max_sigma)
     930              :       END DO
     931              : 
     932         5521 :    END SUBROUTINE rattle_roll_colv_low
     933              : 
     934              : ! **************************************************************************************************
     935              : !> \brief Require absolute and relative rate convergence for moving targets.
     936              : !> \param sigma ...
     937              : !> \param definition ...
     938              : !> \return ...
     939              : ! **************************************************************************************************
     940        67062 :    PURE FUNCTION rattle_colv_residual(sigma, definition) RESULT(residual)
     941              :       REAL(KIND=dp), INTENT(IN)                          :: sigma
     942              :       TYPE(colvar_constraint_type), INTENT(IN)           :: definition
     943              :       REAL(KIND=dp)                                      :: residual
     944              : 
     945        67062 :       residual = ABS(sigma)
     946              :       ! A slow imposed rate can be smaller than the legacy absolute velocity tolerance.
     947              :       ! Require relative rate convergence too, including the zero-rate limit transition.
     948        67062 :       IF (definition%expected_value_growth_speed /= 0.0_dp) THEN
     949          660 :          residual = MAX(residual, ABS(sigma/definition%expected_value_growth_speed))
     950              :       END IF
     951        67062 :    END FUNCTION rattle_colv_residual
     952              : 
     953              : ! **************************************************************************************************
     954              : !> \brief Update position/velocities
     955              : !> \param wrk ...
     956              : !> \param fac ...
     957              : !> \param lcolv ...
     958              : !> \param lambda ...
     959              : !> \param roll ...
     960              : !> \param rmat ...
     961              : !> \param imass ...
     962              : !> \par History
     963              : !>      Teodoro Laino [teo] created 04.2006
     964              : !> \author Teodoro Laino [tlaino]
     965              : ! **************************************************************************************************
     966       444476 :    SUBROUTINE update_con_colv(wrk, fac, lcolv, lambda, roll, rmat, imass)
     967              :       REAL(KIND=dp), INTENT(INOUT)                       :: wrk(:, :)
     968              :       REAL(KIND=dp), INTENT(IN)                          :: fac
     969              :       TYPE(local_colvar_constraint_type), INTENT(IN)     :: lcolv
     970              :       REAL(KIND=dp), INTENT(IN)                          :: lambda
     971              :       LOGICAL, INTENT(in), OPTIONAL                      :: roll
     972              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
     973              :          OPTIONAL                                        :: rmat
     974              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
     975              : 
     976              :       INTEGER                                            :: iatm, ind
     977              :       LOGICAL                                            :: my_roll
     978              :       REAL(KIND=dp), DIMENSION(3)                        :: f_roll
     979              : 
     980       444476 :       my_roll = .FALSE.
     981       444476 :       IF (PRESENT(roll)) THEN
     982       211208 :          my_roll = roll
     983       211208 :          IF (my_roll) THEN
     984       211208 :             CPASSERT(PRESENT(rmat))
     985              :          END IF
     986              :       END IF
     987      1344790 :       DO iatm = 1, SIZE(lcolv%colvar_old%i_atom)
     988       900314 :          ind = lcolv%colvar_old%i_atom(iatm)
     989              :          !
     990       900314 :          IF (my_roll) THEN
     991              :             ! If ROLL rotate forces
     992      5520684 :             f_roll = MATMUL(rmat, lcolv%colvar_old%dsdr(:, iatm))
     993              :          ELSE
     994      1902584 :             f_roll = lcolv%colvar_old%dsdr(:, iatm)
     995              :          END IF
     996      4045732 :          wrk(:, ind) = wrk(:, ind) - imass(ind)*fac*lambda*f_roll
     997              :       END DO
     998       444476 :    END SUBROUTINE update_con_colv
     999              : 
    1000              : ! **************************************************************************************************
    1001              : !> \brief Evaluates the Jacobian of the collective variables constraints
    1002              : !> \param colvar ...
    1003              : !> \param colvar_old ...
    1004              : !> \param roll ...
    1005              : !> \param rmat ...
    1006              : !> \param imass ...
    1007              : !> \return ...
    1008              : !> \par History
    1009              : !>      Teodoro Laino [teo] created 04.2006
    1010              : !> \author Teodoro Laino [tlaino]
    1011              : ! **************************************************************************************************
    1012       229741 :    FUNCTION eval_Jac_colvar(colvar, colvar_old, roll, rmat, imass) RESULT(res)
    1013              :       TYPE(colvar_type), POINTER                         :: colvar, colvar_old
    1014              :       LOGICAL, INTENT(IN), OPTIONAL                      :: roll
    1015              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
    1016              :          OPTIONAL                                        :: rmat
    1017              :       REAL(KIND=dp), DIMENSION(:)                        :: imass
    1018              :       REAL(KIND=dp)                                      :: res
    1019              : 
    1020              :       INTEGER                                            :: i, iatom
    1021              :       LOGICAL                                            :: my_roll
    1022              :       REAL(KIND=dp), DIMENSION(3)                        :: tmp1, tmp2, tmp3
    1023              : 
    1024       229741 :       my_roll = .FALSE.
    1025       229741 :       IF (PRESENT(roll)) THEN
    1026       110730 :          my_roll = roll
    1027       110730 :          IF (my_roll) THEN
    1028       110730 :             CPASSERT(PRESENT(rmat))
    1029              :          END IF
    1030              :       END IF
    1031              : 
    1032       229741 :       res = 0.0_dp
    1033              :       IF (my_roll) THEN
    1034       332989 :          DO i = 1, SIZE(colvar%i_atom)
    1035       222259 :             iatom = colvar%i_atom(i)
    1036       889036 :             tmp1 = colvar%dsdr(1:3, i)
    1037       889036 :             tmp3 = colvar_old%dsdr(1:3, i)
    1038      2889367 :             tmp2 = MATMUL(rmat, tmp3)
    1039       999766 :             res = res + DOT_PRODUCT(tmp1, tmp2)*imass(iatom)
    1040              :          END DO
    1041              :       ELSE
    1042       360079 :          DO i = 1, SIZE(colvar%i_atom)
    1043       241068 :             iatom = colvar%i_atom(i)
    1044       964272 :             tmp1 = colvar%dsdr(1:3, i)
    1045       964272 :             tmp2 = colvar_old%dsdr(1:3, i)
    1046      1083283 :             res = res + DOT_PRODUCT(tmp1, tmp2)*imass(iatom)
    1047              :          END DO
    1048              :       END IF
    1049              : 
    1050       229741 :    END FUNCTION eval_Jac_colvar
    1051              : 
    1052              : ! **************************************************************************************************
    1053              : !> \brief Evaluates the constraint for the rattle scheme
    1054              : !> \param colvar ...
    1055              : !> \param vel ...
    1056              : !> \param roll ...
    1057              : !> \param veps ...
    1058              : !> \param rmat ...
    1059              : !> \param particles ...
    1060              : !> \return ...
    1061              : !> \par History
    1062              : !>      Teodoro Laino [teo] created 04.2006
    1063              : !> \author Teodoro Laino [tlaino]
    1064              : ! **************************************************************************************************
    1065       121423 :    FUNCTION rattle_con_eval(colvar, vel, roll, veps, rmat, particles) RESULT(res)
    1066              :       TYPE(colvar_type), POINTER                         :: colvar
    1067              :       REAL(KIND=dp), INTENT(IN)                          :: vel(:, :)
    1068              :       LOGICAL, INTENT(IN), OPTIONAL                      :: roll
    1069              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
    1070              :          OPTIONAL                                        :: veps, rmat
    1071              :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
    1072              :          POINTER                                         :: particles
    1073              :       REAL(KIND=dp)                                      :: res
    1074              : 
    1075              :       INTEGER                                            :: iatm, ind
    1076              :       LOGICAL                                            :: my_roll
    1077              :       REAL(KIND=dp), DIMENSION(3)                        :: f_roll, pos, v_roll
    1078              : 
    1079       121423 :       my_roll = .FALSE.
    1080       121423 :       IF (PRESENT(roll)) THEN
    1081        56422 :          my_roll = roll
    1082        56422 :          IF (my_roll) THEN
    1083        56422 :             CPASSERT(PRESENT(rmat))
    1084        56422 :             CPASSERT(PRESENT(veps))
    1085        56422 :             CPASSERT(PRESENT(particles))
    1086              :          END IF
    1087              :       END IF
    1088       121423 :       res = 0.0_dp
    1089       369505 :       DO iatm = 1, SIZE(colvar%i_atom)
    1090       248082 :          ind = colvar%i_atom(iatm)
    1091       248082 :          IF (my_roll) THEN
    1092       456848 :             pos = particles(ind)%r
    1093      1484756 :             f_roll = MATMUL(rmat, colvar%dsdr(:, iatm))
    1094      1827392 :             v_roll = vel(:, ind) + MATMUL(veps, pos)
    1095              :          ELSE
    1096       535480 :             f_roll = colvar%dsdr(:, iatm)
    1097       535480 :             v_roll = vel(:, ind)
    1098              :          END IF
    1099      1113751 :          res = res + DOT_PRODUCT(f_roll, v_roll)
    1100              :       END DO
    1101              : 
    1102       121423 :    END FUNCTION rattle_con_eval
    1103              : 
    1104              : END MODULE constraint_clv
        

Generated by: LCOV version 2.0-1