LCOV - code coverage report
Current view: top level - src - constraint_util.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 99.2 % 266 264
Test Date: 2025-12-04 06:27:48 Functions: 100.0 % 9 9

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Contains routines useful for the application of constraints during MD
      10              : !> \par History
      11              : !>      none
      12              : ! **************************************************************************************************
      13              : MODULE constraint_util
      14              :    USE cell_types,                      ONLY: cell_type
      15              :    USE colvar_methods,                  ONLY: colvar_eval_mol_f
      16              :    USE distribution_1d_types,           ONLY: distribution_1d_type
      17              :    USE kinds,                           ONLY: dp
      18              :    USE message_passing,                 ONLY: mp_comm_type
      19              :    USE molecule_kind_types,             ONLY: colvar_constraint_type,&
      20              :                                               fixd_constraint_type,&
      21              :                                               g3x3_constraint_type,&
      22              :                                               g4x6_constraint_type,&
      23              :                                               get_molecule_kind,&
      24              :                                               molecule_kind_type
      25              :    USE molecule_types,                  ONLY: get_molecule,&
      26              :                                               global_constraint_type,&
      27              :                                               local_colvar_constraint_type,&
      28              :                                               local_constraint_type,&
      29              :                                               local_g3x3_constraint_type,&
      30              :                                               local_g4x6_constraint_type,&
      31              :                                               molecule_type
      32              :    USE particle_types,                  ONLY: particle_type
      33              :    USE virial_types,                    ONLY: virial_type
      34              : #include "./base/base_uses.f90"
      35              : 
      36              :    IMPLICIT NONE
      37              : 
      38              :    PRIVATE
      39              :    PUBLIC :: getold, &
      40              :              pv_constraint, &
      41              :              check_tol, &
      42              :              get_roll_matrix, &
      43              :              restore_temporary_set, &
      44              :              update_temporary_set
      45              : 
      46              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'constraint_util'
      47              : 
      48              : CONTAINS
      49              : 
      50              : ! **************************************************************************************************
      51              : !> \brief saves all of the old variables
      52              : !> \param gci ...
      53              : !> \param local_molecules ...
      54              : !> \param molecule_set ...
      55              : !> \param molecule_kind_set ...
      56              : !> \param particle_set ...
      57              : !> \param cell ...
      58              : !> \par History
      59              : !>      none
      60              : ! **************************************************************************************************
      61        16934 :    SUBROUTINE getold(gci, local_molecules, molecule_set, molecule_kind_set, &
      62              :                      particle_set, cell)
      63              : 
      64              :       TYPE(global_constraint_type), POINTER              :: gci
      65              :       TYPE(distribution_1d_type), POINTER                :: local_molecules
      66              :       TYPE(molecule_type), POINTER                       :: molecule_set(:)
      67              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind_set(:)
      68              :       TYPE(particle_type), POINTER                       :: particle_set(:)
      69              :       TYPE(cell_type), POINTER                           :: cell
      70              : 
      71              :       INTEGER                                            :: first_atom, i, ikind, imol, n3x3con, &
      72              :                                                             n4x6con, nkind, nmol_per_kind
      73        16934 :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
      74        16934 :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
      75        16934 :       TYPE(g3x3_constraint_type), POINTER                :: g3x3_list(:)
      76        16934 :       TYPE(g4x6_constraint_type), POINTER                :: g4x6_list(:)
      77        16934 :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
      78              :       TYPE(local_constraint_type), POINTER               :: lci
      79        16934 :       TYPE(local_g3x3_constraint_type), POINTER          :: lg3x3(:)
      80        16934 :       TYPE(local_g4x6_constraint_type), POINTER          :: lg4x6(:)
      81              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
      82              :       TYPE(molecule_type), POINTER                       :: molecule
      83              : 
      84        16934 :       NULLIFY (fixd_list)
      85        16934 :       nkind = SIZE(molecule_kind_set)
      86              :       ! Intramolecular constraints
      87        84474 :       MOL: DO ikind = 1, nkind
      88        67540 :          nmol_per_kind = local_molecules%n_el(ikind)
      89       396005 :          DO imol = 1, nmol_per_kind
      90       311531 :             i = local_molecules%list(ikind)%array(imol)
      91       311531 :             molecule => molecule_set(i)
      92       311531 :             molecule_kind => molecule%molecule_kind
      93              :             CALL get_molecule_kind(molecule_kind, ng3x3=n3x3con, ng4x6=n4x6con, &
      94              :                                    colv_list=colv_list, g3x3_list=g3x3_list, g4x6_list=g4x6_list, &
      95       311531 :                                    fixd_list=fixd_list)
      96       311531 :             CALL get_molecule(molecule, lci=lci)
      97       311531 :             IF (.NOT. ASSOCIATED(lci)) CYCLE
      98              :             CALL get_molecule(molecule, first_atom=first_atom, &
      99       311531 :                               lcolv=lcolv, lg3x3=lg3x3, lg4x6=lg4x6)
     100              :             CALL getold_low(n3x3con, n4x6con, colv_list, g3x3_list, g4x6_list, fixd_list, &
     101       690602 :                             lcolv, lg3x3, lg4x6, first_atom, particle_set, cell)
     102              :          END DO
     103              :       END DO MOL
     104              :       ! Intermolecular constraints
     105        16934 :       IF (gci%ntot > 0) THEN
     106         1150 :          n3x3con = gci%ng3x3
     107         1150 :          n4x6con = gci%ng4x6
     108         1150 :          colv_list => gci%colv_list
     109         1150 :          g3x3_list => gci%g3x3_list
     110         1150 :          g4x6_list => gci%g4x6_list
     111         1150 :          fixd_list => gci%fixd_list
     112         1150 :          lcolv => gci%lcolv
     113         1150 :          lg3x3 => gci%lg3x3
     114         1150 :          lg4x6 => gci%lg4x6
     115              :          CALL getold_low(n3x3con, n4x6con, colv_list, g3x3_list, g4x6_list, fixd_list, &
     116         1150 :                          lcolv, lg3x3, lg4x6, 1, particle_set, cell)
     117              :       END IF
     118        16934 :    END SUBROUTINE getold
     119              : 
     120              : ! **************************************************************************************************
     121              : !> \brief saves all of the old variables - Low Level
     122              : !> \param n3x3con ...
     123              : !> \param n4x6con ...
     124              : !> \param colv_list ...
     125              : !> \param g3x3_list ...
     126              : !> \param g4x6_list ...
     127              : !> \param fixd_list ...
     128              : !> \param lcolv ...
     129              : !> \param lg3x3 ...
     130              : !> \param lg4x6 ...
     131              : !> \param first_atom ...
     132              : !> \param particle_set ...
     133              : !> \param cell ...
     134              : !> \par History
     135              : !>      none
     136              : ! **************************************************************************************************
     137       312681 :    SUBROUTINE getold_low(n3x3con, n4x6con, colv_list, g3x3_list, g4x6_list, fixd_list, &
     138              :                          lcolv, lg3x3, lg4x6, first_atom, particle_set, cell)
     139              : 
     140              :       INTEGER, INTENT(IN)                                :: n3x3con, n4x6con
     141              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     142              :       TYPE(g3x3_constraint_type), POINTER                :: g3x3_list(:)
     143              :       TYPE(g4x6_constraint_type), POINTER                :: g4x6_list(:)
     144              :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     145              :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     146              :       TYPE(local_g3x3_constraint_type), POINTER          :: lg3x3(:)
     147              :       TYPE(local_g4x6_constraint_type), POINTER          :: lg4x6(:)
     148              :       INTEGER, INTENT(IN)                                :: first_atom
     149              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     150              :       TYPE(cell_type), POINTER                           :: cell
     151              : 
     152              :       INTEGER                                            :: iconst, index
     153              : 
     154       312681 :       IF (ASSOCIATED(colv_list)) THEN
     155              :          ! Collective constraints
     156        43227 :          DO iconst = 1, SIZE(colv_list)
     157              :             CALL colvar_eval_mol_f(lcolv(iconst)%colvar_old, cell, &
     158        43227 :                                    particles=particle_set, fixd_list=fixd_list)
     159              :          END DO
     160              :       END IF
     161              :       ! 3x3 constraints
     162       494908 :       DO iconst = 1, n3x3con
     163       182227 :          index = g3x3_list(iconst)%a + first_atom - 1
     164      1457816 :          lg3x3(iconst)%ra_old = particle_set(index)%r
     165       182227 :          index = g3x3_list(iconst)%b + first_atom - 1
     166      1457816 :          lg3x3(iconst)%rb_old = particle_set(index)%r
     167       182227 :          index = g3x3_list(iconst)%c + first_atom - 1
     168      1770497 :          lg3x3(iconst)%rc_old = particle_set(index)%r
     169              :       END DO
     170              :       ! 4x6 constraints
     171       313708 :       DO iconst = 1, n4x6con
     172         1027 :          index = g4x6_list(iconst)%a + first_atom - 1
     173         8216 :          lg4x6(iconst)%ra_old = particle_set(index)%r
     174         1027 :          index = g4x6_list(iconst)%b + first_atom - 1
     175         8216 :          lg4x6(iconst)%rb_old = particle_set(index)%r
     176         1027 :          index = g4x6_list(iconst)%c + first_atom - 1
     177         8216 :          lg4x6(iconst)%rc_old = particle_set(index)%r
     178         1027 :          index = g4x6_list(iconst)%d + first_atom - 1
     179       320897 :          lg4x6(iconst)%rd_old = particle_set(index)%r
     180              :       END DO
     181              : 
     182       312681 :    END SUBROUTINE getold_low
     183              : 
     184              : ! **************************************************************************************************
     185              : !> \brief ...
     186              : !> \param gci ...
     187              : !> \param local_molecules ...
     188              : !> \param molecule_set ...
     189              : !> \param molecule_kind_set ...
     190              : !> \param particle_set ...
     191              : !> \param virial ...
     192              : !> \param group ...
     193              : !> \par History
     194              : !>      none
     195              : ! **************************************************************************************************
     196        21178 :    SUBROUTINE pv_constraint(gci, local_molecules, molecule_set, molecule_kind_set, &
     197              :                             particle_set, virial, group)
     198              : 
     199              :       TYPE(global_constraint_type), POINTER              :: gci
     200              :       TYPE(distribution_1d_type), POINTER                :: local_molecules
     201              :       TYPE(molecule_type), POINTER                       :: molecule_set(:)
     202              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind_set(:)
     203              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     204              :       TYPE(virial_type), INTENT(INOUT)                   :: virial
     205              : 
     206              :       CLASS(mp_comm_type), INTENT(IN)                     :: group
     207              : 
     208              :       INTEGER                                            :: first_atom, i, ikind, imol, ng3x3, &
     209              :                                                             ng4x6, nkind, nmol_per_kind
     210              :       REAL(KIND=dp)                                      :: pv(3, 3)
     211        21178 :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     212        21178 :       TYPE(g3x3_constraint_type), POINTER                :: g3x3_list(:)
     213        21178 :       TYPE(g4x6_constraint_type), POINTER                :: g4x6_list(:)
     214        21178 :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     215              :       TYPE(local_constraint_type), POINTER               :: lci
     216        21178 :       TYPE(local_g3x3_constraint_type), POINTER          :: lg3x3(:)
     217        21178 :       TYPE(local_g4x6_constraint_type), POINTER          :: lg4x6(:)
     218              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     219              :       TYPE(molecule_type), POINTER                       :: molecule
     220              : 
     221        21178 :       pv = 0.0_dp
     222        21178 :       nkind = SIZE(molecule_kind_set)
     223              :       ! Intramolecular Constraints
     224        92988 :       MOL: DO ikind = 1, nkind
     225        71810 :          nmol_per_kind = local_molecules%n_el(ikind)
     226       660848 :          DO imol = 1, nmol_per_kind
     227       567860 :             i = local_molecules%list(ikind)%array(imol)
     228       567860 :             molecule => molecule_set(i)
     229       567860 :             molecule_kind => molecule%molecule_kind
     230              :             CALL get_molecule_kind(molecule_kind, ng3x3=ng3x3, &
     231              :                                    ng4x6=ng4x6, g3x3_list=g3x3_list, g4x6_list=g4x6_list, &
     232       567860 :                                    colv_list=colv_list)
     233       567860 :             CALL get_molecule(molecule, lci=lci)
     234       567860 :             IF (.NOT. ASSOCIATED(lci)) CYCLE
     235              :             CALL get_molecule(molecule, first_atom=first_atom, lg3x3=lg3x3, &
     236       567860 :                               lg4x6=lg4x6, lcolv=lcolv)
     237              :             CALL pv_constraint_low(ng3x3, ng4x6, g3x3_list, g4x6_list, colv_list, &
     238      1207530 :                                    first_atom, lg3x3, lg4x6, lcolv, particle_set, pv)
     239              :          END DO
     240              :       END DO MOL
     241              :       ! Intermolecular constraints
     242        21178 :       IF (gci%ntot > 0) THEN
     243         1120 :          ng3x3 = gci%ng3x3
     244         1120 :          ng4x6 = gci%ng4x6
     245         1120 :          colv_list => gci%colv_list
     246         1120 :          g3x3_list => gci%g3x3_list
     247         1120 :          g4x6_list => gci%g4x6_list
     248         1120 :          lcolv => gci%lcolv
     249         1120 :          lg3x3 => gci%lg3x3
     250         1120 :          lg4x6 => gci%lg4x6
     251              :          CALL pv_constraint_low(ng3x3, ng4x6, g3x3_list, g4x6_list, colv_list, &
     252         1120 :                                 1, lg3x3, lg4x6, lcolv, particle_set, pv)
     253              :       END IF
     254        21178 :       CALL group%sum(pv)
     255              :       ! Symmetrize PV
     256        21178 :       pv(1, 2) = 0.5_dp*(pv(1, 2) + pv(2, 1))
     257        21178 :       pv(2, 1) = pv(1, 2)
     258        21178 :       pv(1, 3) = 0.5_dp*(pv(1, 3) + pv(3, 1))
     259        21178 :       pv(3, 1) = pv(1, 3)
     260        21178 :       pv(3, 2) = 0.5_dp*(pv(3, 2) + pv(2, 3))
     261        21178 :       pv(2, 3) = pv(3, 2)
     262              :       ! Store in virial type
     263       275314 :       virial%pv_constraint = pv
     264              : 
     265        21178 :    END SUBROUTINE pv_constraint
     266              : 
     267              : ! **************************************************************************************************
     268              : !> \brief ...
     269              : !> \param ng3x3 ...
     270              : !> \param ng4x6 ...
     271              : !> \param g3x3_list ...
     272              : !> \param g4x6_list ...
     273              : !> \param colv_list ...
     274              : !> \param first_atom ...
     275              : !> \param lg3x3 ...
     276              : !> \param lg4x6 ...
     277              : !> \param lcolv ...
     278              : !> \param particle_set ...
     279              : !> \param pv ...
     280              : !> \par History
     281              : !>      none
     282              : ! **************************************************************************************************
     283       568980 :    SUBROUTINE pv_constraint_low(ng3x3, ng4x6, g3x3_list, g4x6_list, colv_list, &
     284              :                                 first_atom, lg3x3, lg4x6, lcolv, particle_set, pv)
     285              : 
     286              :       INTEGER, INTENT(IN)                                :: ng3x3, ng4x6
     287              :       TYPE(g3x3_constraint_type), POINTER                :: g3x3_list(:)
     288              :       TYPE(g4x6_constraint_type), POINTER                :: g4x6_list(:)
     289              :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     290              :       INTEGER, INTENT(IN)                                :: first_atom
     291              :       TYPE(local_g3x3_constraint_type), POINTER          :: lg3x3(:)
     292              :       TYPE(local_g4x6_constraint_type), POINTER          :: lg4x6(:)
     293              :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     294              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     295              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT)      :: pv
     296              : 
     297              :       INTEGER                                            :: iconst, index_a, index_b, index_c, &
     298              :                                                             index_d
     299              :       REAL(KIND=dp)                                      :: fc1(3), fc2(3), fc3(3), fc4(3), &
     300              :                                                             lambda_3x3(3), lambda_4x6(6)
     301              : 
     302       568980 :       IF (ASSOCIATED(colv_list)) THEN
     303              :          ! Colvar Constraints
     304        62284 :          DO iconst = 1, SIZE(colv_list)
     305        62284 :             CALL pv_colv_eval(pv, lcolv(iconst), particle_set)
     306              :          END DO
     307              :       END IF
     308              :       ! 3x3
     309      1000052 :       DO iconst = 1, ng3x3
     310              :          !  pv gets updated with FULL multiplier
     311      1724288 :          lambda_3x3 = lg3x3(iconst)%lambda
     312              : 
     313              :          fc1 = lambda_3x3(1)*lg3x3(iconst)%fa + &
     314      1724288 :                lambda_3x3(2)*lg3x3(iconst)%fb
     315              :          fc2 = -lambda_3x3(1)*lg3x3(iconst)%fa + &
     316      1724288 :                lambda_3x3(3)*lg3x3(iconst)%fc
     317              :          fc3 = -lambda_3x3(2)*lg3x3(iconst)%fb - &
     318      1724288 :                lambda_3x3(3)*lg3x3(iconst)%fc
     319       431072 :          index_a = g3x3_list(iconst)%a + first_atom - 1
     320       431072 :          index_b = g3x3_list(iconst)%b + first_atom - 1
     321       431072 :          index_c = g3x3_list(iconst)%c + first_atom - 1
     322              : 
     323              :          !pv(1,1)
     324       431072 :          pv(1, 1) = pv(1, 1) + fc1(1)*particle_set(index_a)%r(1)
     325       431072 :          pv(1, 1) = pv(1, 1) + fc2(1)*particle_set(index_b)%r(1)
     326       431072 :          pv(1, 1) = pv(1, 1) + fc3(1)*particle_set(index_c)%r(1)
     327              :          !pv(1,2)
     328       431072 :          pv(1, 2) = pv(1, 2) + fc1(1)*particle_set(index_a)%r(2)
     329       431072 :          pv(1, 2) = pv(1, 2) + fc2(1)*particle_set(index_b)%r(2)
     330       431072 :          pv(1, 2) = pv(1, 2) + fc3(1)*particle_set(index_c)%r(2)
     331              :          !pv(1,3)
     332       431072 :          pv(1, 3) = pv(1, 3) + fc1(1)*particle_set(index_a)%r(3)
     333       431072 :          pv(1, 3) = pv(1, 3) + fc2(1)*particle_set(index_b)%r(3)
     334       431072 :          pv(1, 3) = pv(1, 3) + fc3(1)*particle_set(index_c)%r(3)
     335              :          !pv(2,1)
     336       431072 :          pv(2, 1) = pv(2, 1) + fc1(2)*particle_set(index_a)%r(1)
     337       431072 :          pv(2, 1) = pv(2, 1) + fc2(2)*particle_set(index_b)%r(1)
     338       431072 :          pv(2, 1) = pv(2, 1) + fc3(2)*particle_set(index_c)%r(1)
     339              :          !pv(2,2)
     340       431072 :          pv(2, 2) = pv(2, 2) + fc1(2)*particle_set(index_a)%r(2)
     341       431072 :          pv(2, 2) = pv(2, 2) + fc2(2)*particle_set(index_b)%r(2)
     342       431072 :          pv(2, 2) = pv(2, 2) + fc3(2)*particle_set(index_c)%r(2)
     343              :          !pv(2,3)
     344       431072 :          pv(2, 3) = pv(2, 3) + fc1(2)*particle_set(index_a)%r(3)
     345       431072 :          pv(2, 3) = pv(2, 3) + fc2(2)*particle_set(index_b)%r(3)
     346       431072 :          pv(2, 3) = pv(2, 3) + fc3(2)*particle_set(index_c)%r(3)
     347              :          !pv(3,1)
     348       431072 :          pv(3, 1) = pv(3, 1) + fc1(3)*particle_set(index_a)%r(1)
     349       431072 :          pv(3, 1) = pv(3, 1) + fc2(3)*particle_set(index_b)%r(1)
     350       431072 :          pv(3, 1) = pv(3, 1) + fc3(3)*particle_set(index_c)%r(1)
     351              :          !pv(3,2)
     352       431072 :          pv(3, 2) = pv(3, 2) + fc1(3)*particle_set(index_a)%r(2)
     353       431072 :          pv(3, 2) = pv(3, 2) + fc2(3)*particle_set(index_b)%r(2)
     354       431072 :          pv(3, 2) = pv(3, 2) + fc3(3)*particle_set(index_c)%r(2)
     355              :          !pv(3,3)
     356       431072 :          pv(3, 3) = pv(3, 3) + fc1(3)*particle_set(index_a)%r(3)
     357       431072 :          pv(3, 3) = pv(3, 3) + fc2(3)*particle_set(index_b)%r(3)
     358      1000052 :          pv(3, 3) = pv(3, 3) + fc3(3)*particle_set(index_c)%r(3)
     359              :       END DO
     360              : 
     361              :       ! 4x6
     362       572437 :       DO iconst = 1, ng4x6
     363              :          !  pv gets updated with FULL multiplier
     364        24199 :          lambda_4x6 = lg4x6(iconst)%lambda
     365              : 
     366              :          fc1 = lambda_4x6(1)*lg4x6(iconst)%fa + &
     367              :                lambda_4x6(2)*lg4x6(iconst)%fb + &
     368        13828 :                lambda_4x6(3)*lg4x6(iconst)%fc
     369              :          fc2 = -lambda_4x6(1)*lg4x6(iconst)%fa + &
     370              :                lambda_4x6(4)*lg4x6(iconst)%fd + &
     371        13828 :                lambda_4x6(5)*lg4x6(iconst)%fe
     372              :          fc3 = -lambda_4x6(2)*lg4x6(iconst)%fb - &
     373              :                lambda_4x6(4)*lg4x6(iconst)%fd + &
     374        13828 :                lambda_4x6(6)*lg4x6(iconst)%ff
     375              :          fc4 = -lambda_4x6(3)*lg4x6(iconst)%fc - &
     376              :                lambda_4x6(5)*lg4x6(iconst)%fe - &
     377        13828 :                lambda_4x6(6)*lg4x6(iconst)%ff
     378         3457 :          index_a = g4x6_list(iconst)%a + first_atom - 1
     379         3457 :          index_b = g4x6_list(iconst)%b + first_atom - 1
     380         3457 :          index_c = g4x6_list(iconst)%c + first_atom - 1
     381         3457 :          index_d = g4x6_list(iconst)%d + first_atom - 1
     382              : 
     383              :          !pv(1,1)
     384         3457 :          pv(1, 1) = pv(1, 1) + fc1(1)*particle_set(index_a)%r(1)
     385         3457 :          pv(1, 1) = pv(1, 1) + fc2(1)*particle_set(index_b)%r(1)
     386         3457 :          pv(1, 1) = pv(1, 1) + fc3(1)*particle_set(index_c)%r(1)
     387         3457 :          pv(1, 1) = pv(1, 1) + fc4(1)*particle_set(index_d)%r(1)
     388              :          !pv(1,2)
     389         3457 :          pv(1, 2) = pv(1, 2) + fc1(1)*particle_set(index_a)%r(2)
     390         3457 :          pv(1, 2) = pv(1, 2) + fc2(1)*particle_set(index_b)%r(2)
     391         3457 :          pv(1, 2) = pv(1, 2) + fc3(1)*particle_set(index_c)%r(2)
     392         3457 :          pv(1, 2) = pv(1, 2) + fc4(1)*particle_set(index_d)%r(2)
     393              :          !pv(1,3)
     394         3457 :          pv(1, 3) = pv(1, 3) + fc1(1)*particle_set(index_a)%r(3)
     395         3457 :          pv(1, 3) = pv(1, 3) + fc2(1)*particle_set(index_b)%r(3)
     396         3457 :          pv(1, 3) = pv(1, 3) + fc3(1)*particle_set(index_c)%r(3)
     397         3457 :          pv(1, 3) = pv(1, 3) + fc4(1)*particle_set(index_d)%r(3)
     398              :          !pv(2,1)
     399         3457 :          pv(2, 1) = pv(2, 1) + fc1(2)*particle_set(index_a)%r(1)
     400         3457 :          pv(2, 1) = pv(2, 1) + fc2(2)*particle_set(index_b)%r(1)
     401         3457 :          pv(2, 1) = pv(2, 1) + fc3(2)*particle_set(index_c)%r(1)
     402         3457 :          pv(2, 1) = pv(2, 1) + fc4(2)*particle_set(index_d)%r(1)
     403              :          !pv(2,2)
     404         3457 :          pv(2, 2) = pv(2, 2) + fc1(2)*particle_set(index_a)%r(2)
     405         3457 :          pv(2, 2) = pv(2, 2) + fc2(2)*particle_set(index_b)%r(2)
     406         3457 :          pv(2, 2) = pv(2, 2) + fc3(2)*particle_set(index_c)%r(2)
     407         3457 :          pv(2, 2) = pv(2, 2) + fc4(2)*particle_set(index_d)%r(2)
     408              :          !pv(2,3)
     409         3457 :          pv(2, 3) = pv(2, 3) + fc1(2)*particle_set(index_a)%r(3)
     410         3457 :          pv(2, 3) = pv(2, 3) + fc2(2)*particle_set(index_b)%r(3)
     411         3457 :          pv(2, 3) = pv(2, 3) + fc3(2)*particle_set(index_c)%r(3)
     412         3457 :          pv(2, 3) = pv(2, 3) + fc4(2)*particle_set(index_d)%r(3)
     413              :          !pv(3,1)
     414         3457 :          pv(3, 1) = pv(3, 1) + fc1(3)*particle_set(index_a)%r(1)
     415         3457 :          pv(3, 1) = pv(3, 1) + fc2(3)*particle_set(index_b)%r(1)
     416         3457 :          pv(3, 1) = pv(3, 1) + fc3(3)*particle_set(index_c)%r(1)
     417         3457 :          pv(3, 1) = pv(3, 1) + fc4(3)*particle_set(index_d)%r(1)
     418              :          !pv(3,2)
     419         3457 :          pv(3, 2) = pv(3, 2) + fc1(3)*particle_set(index_a)%r(2)
     420         3457 :          pv(3, 2) = pv(3, 2) + fc2(3)*particle_set(index_b)%r(2)
     421         3457 :          pv(3, 2) = pv(3, 2) + fc3(3)*particle_set(index_c)%r(2)
     422         3457 :          pv(3, 2) = pv(3, 2) + fc4(3)*particle_set(index_d)%r(2)
     423              :          !pv(3,3)
     424         3457 :          pv(3, 3) = pv(3, 3) + fc1(3)*particle_set(index_a)%r(3)
     425         3457 :          pv(3, 3) = pv(3, 3) + fc2(3)*particle_set(index_b)%r(3)
     426         3457 :          pv(3, 3) = pv(3, 3) + fc3(3)*particle_set(index_c)%r(3)
     427       572437 :          pv(3, 3) = pv(3, 3) + fc4(3)*particle_set(index_d)%r(3)
     428              :       END DO
     429              : 
     430       568980 :    END SUBROUTINE pv_constraint_low
     431              : 
     432              : ! **************************************************************************************************
     433              : !> \brief ...
     434              : !> \param pv ...
     435              : !> \param lcolv ...
     436              : !> \param particle_set ...
     437              : !> \par History
     438              : !>      none
     439              : ! **************************************************************************************************
     440        25701 :    SUBROUTINE pv_colv_eval(pv, lcolv, particle_set)
     441              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT)      :: pv
     442              :       TYPE(local_colvar_constraint_type), INTENT(IN)     :: lcolv
     443              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     444              : 
     445              :       INTEGER                                            :: i, iatm, ind, j
     446              :       REAL(KIND=dp)                                      :: lambda, tmp
     447              :       REAL(KIND=dp), DIMENSION(3)                        :: f
     448              : 
     449        81829 :       DO iatm = 1, SIZE(lcolv%colvar_old%i_atom)
     450        56128 :          ind = lcolv%colvar_old%i_atom(iatm)
     451       224512 :          f = -lcolv%colvar_old%dsdr(:, iatm)
     452              :          !  pv gets updated with FULL multiplier
     453        56128 :          lambda = lcolv%lambda
     454       250213 :          DO i = 1, 3
     455       168384 :             tmp = lambda*particle_set(ind)%r(i)
     456       729664 :             DO j = 1, 3
     457       673536 :                pv(j, i) = pv(j, i) + f(j)*tmp
     458              :             END DO
     459              :          END DO
     460              :       END DO
     461              : 
     462        25701 :    END SUBROUTINE pv_colv_eval
     463              : 
     464              : ! **************************************************************************************************
     465              : !> \brief ...
     466              : !> \param roll_tol ...
     467              : !> \param iroll ...
     468              : !> \param char ...
     469              : !> \param matrix ...
     470              : !> \param veps ...
     471              : !> \par History
     472              : !>      none
     473              : ! **************************************************************************************************
     474         3620 :    SUBROUTINE check_tol(roll_tol, iroll, char, matrix, veps)
     475              : 
     476              :       REAL(KIND=dp), INTENT(OUT)                         :: roll_tol
     477              :       INTEGER, INTENT(INOUT)                             :: iroll
     478              :       CHARACTER(LEN=*), INTENT(IN)                       :: char
     479              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
     480              :          OPTIONAL                                        :: matrix, veps
     481              : 
     482              :       REAL(KIND=dp)                                      :: local_tol
     483              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: diff_rattle, diff_shake
     484              :       REAL(KIND=dp), DIMENSION(3, 3), SAVE               :: matrix_old, veps_old
     485              : 
     486         1826 :       SELECT CASE (char)
     487              :       CASE ('SHAKE')
     488         1826 :          IF (iroll == 1) THEN
     489         8814 :             matrix_old = matrix
     490          678 :             roll_tol = -1.E10_dp
     491              :          ELSE
     492              :             roll_tol = 0.0_dp
     493        14924 :             diff_shake = ABS(matrix_old - matrix)
     494        14924 :             local_tol = MAXVAL(diff_shake)
     495         1148 :             roll_tol = MAX(roll_tol, local_tol)
     496        14924 :             matrix_old = matrix
     497              :          END IF
     498         1826 :          iroll = iroll + 1
     499              :       CASE ('RATTLE')
     500         1794 :          IF (iroll == 1) THEN
     501         8814 :             veps_old = veps
     502          678 :             roll_tol = -1.E+10_dp
     503              :          ELSE
     504              :             roll_tol = 0.0_dp
     505              :             ! compute tolerance on veps
     506        14508 :             diff_rattle = ABS(veps - veps_old)
     507        14508 :             local_tol = MAXVAL(diff_rattle)
     508         1116 :             roll_tol = MAX(roll_tol, local_tol)
     509        14508 :             veps_old = veps
     510              :          END IF
     511         5414 :          iroll = iroll + 1
     512              :       END SELECT
     513              : 
     514         3620 :    END SUBROUTINE check_tol
     515              : 
     516              : ! **************************************************************************************************
     517              : !> \brief ...
     518              : !> \param char ...
     519              : !> \param r_shake ...
     520              : !> \param v_shake ...
     521              : !> \param vector_r ...
     522              : !> \param vector_v ...
     523              : !> \param u ...
     524              : !> \par History
     525              : !>      none
     526              : ! **************************************************************************************************
     527         3620 :    SUBROUTINE get_roll_matrix(char, r_shake, v_shake, vector_r, vector_v, u)
     528              : 
     529              :       CHARACTER(len=*), INTENT(IN)                       :: char
     530              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT), &
     531              :          OPTIONAL                                        :: r_shake, v_shake
     532              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), OPTIONAL  :: vector_r, vector_v
     533              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
     534              :          OPTIONAL                                        :: u
     535              : 
     536              :       INTEGER                                            :: i
     537              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: diag
     538              : 
     539        25532 :       IF (PRESENT(r_shake)) r_shake = 0.0_dp
     540        47060 :       IF (PRESENT(v_shake)) v_shake = 0.0_dp
     541         3620 :       diag = 0.0_dp
     542              : 
     543         1826 :       SELECT CASE (char)
     544              :       CASE ('SHAKE')
     545         1826 :          IF (PRESENT(u) .AND. PRESENT(vector_v) .AND. &
     546         1794 :              PRESENT(vector_r)) THEN
     547           20 :             diag(1, 1) = vector_r(1)
     548           20 :             diag(2, 2) = vector_r(2)
     549           20 :             diag(3, 3) = vector_r(3)
     550         2660 :             r_shake = MATMUL(MATMUL(u, diag), TRANSPOSE(u))
     551           20 :             diag(1, 1) = vector_v(1)
     552           20 :             diag(2, 2) = vector_v(2)
     553           20 :             diag(3, 3) = vector_v(3)
     554         2660 :             v_shake = MATMUL(MATMUL(u, diag), TRANSPOSE(u))
     555          800 :             diag = MATMUL(r_shake, v_shake)
     556          260 :             r_shake = diag
     557         1806 :          ELSEIF (.NOT. PRESENT(u) .AND. PRESENT(vector_v) .AND. &
     558              :                  PRESENT(vector_r)) THEN
     559         7224 :             DO i = 1, 3
     560         5418 :                r_shake(i, i) = vector_r(i)*vector_v(i)
     561         7224 :                v_shake(i, i) = vector_v(i)
     562              :             END DO
     563              :          ELSE
     564            0 :             CPABORT("Not sufficient parameters")
     565              :          END IF
     566              :       CASE ('RATTLE')
     567         3620 :          IF (PRESENT(u) .AND. PRESENT(vector_v)) THEN
     568           20 :             diag(1, 1) = vector_v(1)
     569           20 :             diag(2, 2) = vector_v(2)
     570           20 :             diag(3, 3) = vector_v(3)
     571         2660 :             v_shake = MATMUL(MATMUL(u, diag), TRANSPOSE(u))
     572         1774 :          ELSEIF (.NOT. PRESENT(u) .AND. PRESENT(vector_v)) THEN
     573         7096 :             DO i = 1, 3
     574         7096 :                v_shake(i, i) = vector_v(i)
     575              :             END DO
     576              :          ELSE
     577            0 :             CPABORT("Not sufficient parameters")
     578              :          END IF
     579              :       END SELECT
     580              : 
     581         3620 :    END SUBROUTINE get_roll_matrix
     582              : 
     583              : ! **************************************************************************************************
     584              : !> \brief ...
     585              : !> \param particle_set ...
     586              : !> \param local_particles ...
     587              : !> \param pos ...
     588              : !> \param vel ...
     589              : !> \par History
     590              : !>      Teodoro Laino [tlaino] 2007
     591              : ! **************************************************************************************************
     592         3345 :    SUBROUTINE restore_temporary_set(particle_set, local_particles, pos, vel)
     593              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     594              :       TYPE(distribution_1d_type), POINTER                :: local_particles
     595              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT), &
     596              :          OPTIONAL                                        :: pos, vel
     597              : 
     598              :       INTEGER                                            :: iparticle, iparticle_kind, &
     599              :                                                             iparticle_local, nparticle_local
     600         3345 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: wrk
     601              : 
     602        10035 :       ALLOCATE (wrk(SIZE(particle_set)))
     603       187160 :       wrk = .TRUE.
     604         8555 :       DO iparticle_kind = 1, SIZE(local_particles%n_el)
     605         5210 :          nparticle_local = local_particles%n_el(iparticle_kind)
     606       100608 :          DO iparticle_local = 1, nparticle_local
     607        92053 :             iparticle = local_particles%list(iparticle_kind)%array(iparticle_local)
     608        97263 :             wrk(iparticle) = .FALSE.
     609              :          END DO
     610              :       END DO
     611         3345 :       IF (PRESENT(vel)) THEN
     612       187160 :          DO iparticle = 1, SIZE(particle_set)
     613       187160 :             IF (wrk(iparticle)) THEN
     614       367048 :                vel(:, iparticle) = 0.0_dp
     615              :             END IF
     616              :          END DO
     617              :       END IF
     618         3345 :       IF (PRESENT(pos)) THEN
     619        98242 :          DO iparticle = 1, SIZE(particle_set)
     620        98242 :             IF (wrk(iparticle)) THEN
     621       192504 :                pos(:, iparticle) = 0.0_dp
     622              :             END IF
     623              :          END DO
     624              :       END IF
     625         3345 :       DEALLOCATE (wrk)
     626         3345 :    END SUBROUTINE restore_temporary_set
     627              : 
     628              : ! **************************************************************************************************
     629              : !> \brief ...
     630              : !> \param group ...
     631              : !> \param pos ...
     632              : !> \param vel ...
     633              : !> \par History
     634              : !>      Teodoro Laino [tlaino] 2007
     635              : ! **************************************************************************************************
     636         3345 :    SUBROUTINE update_temporary_set(group, pos, vel)
     637              :       CLASS(mp_comm_type), INTENT(IN)                     :: group
     638              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT), &
     639              :          OPTIONAL                                        :: pos, vel
     640              : 
     641         3345 :       IF (PRESENT(pos)) THEN
     642       773035 :          CALL group%sum(pos)
     643              :       END IF
     644         3345 :       IF (PRESENT(vel)) THEN
     645      1473865 :          CALL group%sum(vel)
     646              :       END IF
     647         3345 :    END SUBROUTINE update_temporary_set
     648              : 
     649           60 : END MODULE constraint_util
        

Generated by: LCOV version 2.0-1