LCOV - code coverage report
Current view: top level - src - colvar_utils.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:9843133) Lines: 281 336 83.6 %
Date: 2024-05-10 06:53:45 Functions: 8 9 88.9 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief evaluations of colvar for internal coordinates schemes
      10             : !> \par History
      11             : !>      05-2007 created [tlaino]
      12             : !> \author Teodoro Laino - Zurich University (2007) [tlaino]
      13             : ! **************************************************************************************************
      14             : MODULE colvar_utils
      15             :    USE cell_types,                      ONLY: cell_type
      16             :    USE colvar_methods,                  ONLY: colvar_eval_mol_f
      17             :    USE colvar_types,                    ONLY: &
      18             :         colvar_counters, colvar_setup, colvar_type, coord_colvar_id, distance_from_path_colvar_id, &
      19             :         gyration_colvar_id, mindist_colvar_id, population_colvar_id, reaction_path_colvar_id, &
      20             :         rmsd_colvar_id
      21             :    USE cp_subsys_types,                 ONLY: cp_subsys_get,&
      22             :                                               cp_subsys_type
      23             :    USE distribution_1d_types,           ONLY: distribution_1d_type
      24             :    USE force_env_types,                 ONLY: force_env_get,&
      25             :                                               force_env_type
      26             :    USE input_constants,                 ONLY: rmsd_all,&
      27             :                                               rmsd_list
      28             :    USE kinds,                           ONLY: dp
      29             :    USE mathlib,                         ONLY: invert_matrix
      30             :    USE memory_utilities,                ONLY: reallocate
      31             :    USE molecule_kind_list_types,        ONLY: molecule_kind_list_type
      32             :    USE molecule_kind_types,             ONLY: colvar_constraint_type,&
      33             :                                               fixd_constraint_type,&
      34             :                                               get_molecule_kind,&
      35             :                                               molecule_kind_type
      36             :    USE molecule_list_types,             ONLY: molecule_list_type
      37             :    USE molecule_types,                  ONLY: get_molecule,&
      38             :                                               global_constraint_type,&
      39             :                                               local_colvar_constraint_type,&
      40             :                                               molecule_type
      41             :    USE particle_list_types,             ONLY: particle_list_type
      42             :    USE particle_types,                  ONLY: particle_type
      43             :    USE rmsd,                            ONLY: rmsd3
      44             :    USE string_utilities,                ONLY: uppercase
      45             :    USE util,                            ONLY: sort
      46             : #include "./base/base_uses.f90"
      47             : 
      48             :    IMPLICIT NONE
      49             : 
      50             :    PRIVATE
      51             :    PUBLIC :: number_of_colvar, &
      52             :              eval_colvar, &
      53             :              set_colvars_target, &
      54             :              get_clv_force, &
      55             :              post_process_colvar
      56             : 
      57             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'colvar_utils'
      58             : 
      59             : CONTAINS
      60             : 
      61             : ! **************************************************************************************************
      62             : !> \brief Gives back the number of colvar defined for a force_eval
      63             : !> \param force_env ...
      64             : !> \param only_intra_colvar ...
      65             : !> \param unique ...
      66             : !> \return ...
      67             : !> \author Teodoro Laino 05.2007 [tlaino] - Zurich University
      68             : ! **************************************************************************************************
      69         198 :    FUNCTION number_of_colvar(force_env, only_intra_colvar, unique) RESULT(ntot)
      70             :       TYPE(force_env_type), POINTER                      :: force_env
      71             :       LOGICAL, INTENT(IN), OPTIONAL                      :: only_intra_colvar, unique
      72             :       INTEGER                                            :: ntot
      73             : 
      74             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'number_of_colvar'
      75             : 
      76             :       INTEGER                                            :: handle, ikind, imol
      77             :       LOGICAL                                            :: my_unique, skip_inter_colvar
      78             :       TYPE(colvar_counters)                              :: ncolv
      79             :       TYPE(cp_subsys_type), POINTER                      :: subsys
      80             :       TYPE(global_constraint_type), POINTER              :: gci
      81             :       TYPE(molecule_kind_list_type), POINTER             :: molecule_kinds
      82         198 :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind, molecule_kind_set(:)
      83             :       TYPE(molecule_list_type), POINTER                  :: molecules
      84         198 :       TYPE(molecule_type), POINTER                       :: molecule, molecule_set(:)
      85             : 
      86         198 :       NULLIFY (subsys, molecules, molecule_kind, molecule, molecule_set, gci)
      87         198 :       CALL timeset(routineN, handle)
      88         198 :       skip_inter_colvar = .FALSE.
      89         198 :       my_unique = .FALSE.
      90         198 :       IF (PRESENT(only_intra_colvar)) skip_inter_colvar = only_intra_colvar
      91         198 :       IF (PRESENT(unique)) my_unique = unique
      92         198 :       ntot = 0
      93         198 :       CALL force_env_get(force_env=force_env, subsys=subsys)
      94             :       CALL cp_subsys_get(subsys=subsys, molecules=molecules, gci=gci, &
      95         198 :                          molecule_kinds=molecule_kinds)
      96             : 
      97         198 :       molecule_set => molecules%els
      98             :       ! Intramolecular Colvar
      99         198 :       IF (my_unique) THEN
     100          34 :          molecule_kind_set => molecule_kinds%els
     101         472 :          DO ikind = 1, molecule_kinds%n_els
     102         438 :             molecule_kind => molecule_kind_set(ikind)
     103         438 :             CALL get_molecule_kind(molecule_kind, ncolv=ncolv)
     104         472 :             ntot = ntot + ncolv%ntot
     105             :          END DO
     106             :       ELSE
     107        2456 :          MOL: DO imol = 1, SIZE(molecule_set)
     108        2292 :             molecule => molecule_set(imol)
     109        2292 :             molecule_kind => molecule%molecule_kind
     110             : 
     111             :             CALL get_molecule_kind(molecule_kind, &
     112        2292 :                                    ncolv=ncolv)
     113        2456 :             ntot = ntot + ncolv%ntot
     114             :          END DO MOL
     115             :       END IF
     116             :       ! Intermolecular Colvar
     117         198 :       IF (.NOT. skip_inter_colvar) THEN
     118         104 :          IF (ASSOCIATED(gci)) THEN
     119         104 :             ntot = ntot + gci%ncolv%ntot
     120             :          END IF
     121             :       END IF
     122         198 :       CALL timestop(handle)
     123             : 
     124         198 :    END FUNCTION number_of_colvar
     125             : 
     126             : ! **************************************************************************************************
     127             : !> \brief Set the value of target for constraints/restraints
     128             : !> \param targets ...
     129             : !> \param force_env ...
     130             : !> \author Teodoro Laino 05.2007 [tlaino] - Zurich University
     131             : ! **************************************************************************************************
     132          60 :    SUBROUTINE set_colvars_target(targets, force_env)
     133             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: targets
     134             :       TYPE(force_env_type), POINTER                      :: force_env
     135             : 
     136             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'set_colvars_target'
     137             : 
     138             :       INTEGER                                            :: handle, i, ikind, ind, nkind
     139             :       TYPE(cell_type), POINTER                           :: cell
     140             :       TYPE(colvar_constraint_type), DIMENSION(:), &
     141          60 :          POINTER                                         :: colv_list
     142             :       TYPE(colvar_counters)                              :: ncolv
     143             :       TYPE(cp_subsys_type), POINTER                      :: subsys
     144             :       TYPE(global_constraint_type), POINTER              :: gci
     145             :       TYPE(molecule_kind_list_type), POINTER             :: molecule_kinds
     146             :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     147             : 
     148          60 :       NULLIFY (cell, subsys, molecule_kinds, molecule_kind, gci, colv_list)
     149          60 :       CALL timeset(routineN, handle)
     150          60 :       CALL force_env_get(force_env=force_env, subsys=subsys, cell=cell)
     151          60 :       CALL cp_subsys_get(subsys=subsys, gci=gci, molecule_kinds=molecule_kinds)
     152             : 
     153          60 :       nkind = molecule_kinds%n_els
     154             :       ! Set Target for Intramolecular Colvars
     155         120 :       MOL: DO ikind = 1, nkind
     156          60 :          molecule_kind => molecule_kinds%els(ikind)
     157             :          CALL get_molecule_kind(molecule_kind, &
     158             :                                 colv_list=colv_list, &
     159          60 :                                 ncolv=ncolv)
     160         120 :          IF (ncolv%ntot /= 0) THEN
     161         120 :             DO i = 1, SIZE(colv_list)
     162          60 :                ind = colv_list(i)%inp_seq_num
     163         120 :                colv_list(i)%expected_value = targets(ind)
     164             :             END DO
     165             :          END IF
     166             :       END DO MOL
     167             :       ! Set Target for Intermolecular Colvars
     168          60 :       IF (ASSOCIATED(gci)) THEN
     169          60 :          IF (gci%ncolv%ntot /= 0) THEN
     170           0 :             colv_list => gci%colv_list
     171           0 :             DO i = 1, SIZE(colv_list)
     172           0 :                ind = colv_list(i)%inp_seq_num
     173           0 :                colv_list(i)%expected_value = targets(ind)
     174             :             END DO
     175             :          END IF
     176             :       END IF
     177          60 :       CALL timestop(handle)
     178             : 
     179          60 :    END SUBROUTINE set_colvars_target
     180             : 
     181             : ! **************************************************************************************************
     182             : !> \brief Computes the values of colvars and the Wilson matrix B and its invers A
     183             : !> \param force_env ...
     184             : !> \param coords ...
     185             : !> \param cvalues ...
     186             : !> \param Bmatrix ...
     187             : !> \param MassI ...
     188             : !> \param Amatrix ...
     189             : !> \author Teodoro Laino 05.2007 [tlaino] - Zurich University
     190             : ! **************************************************************************************************
     191          94 :    SUBROUTINE eval_colvar(force_env, coords, cvalues, Bmatrix, MassI, Amatrix)
     192             : 
     193             :       TYPE(force_env_type), POINTER                      :: force_env
     194             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), OPTIONAL  :: coords
     195             :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: cvalues
     196             :       REAL(KIND=dp), DIMENSION(:, :), OPTIONAL, POINTER  :: Bmatrix
     197             :       REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER     :: MassI
     198             :       REAL(KIND=dp), DIMENSION(:, :), OPTIONAL, POINTER  :: Amatrix
     199             : 
     200             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'eval_colvar'
     201             : 
     202             :       INTEGER                                            :: handle, i, ikind, imol, n_tot, natom, &
     203             :                                                             nkind, nmol_per_kind, offset
     204          94 :       INTEGER, DIMENSION(:), POINTER                     :: map, wrk
     205             :       LOGICAL                                            :: check
     206             :       REAL(KIND=dp)                                      :: inv_error
     207          94 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: bwrk, Gmatrix, Gmatrix_i
     208          94 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rwrk
     209             :       TYPE(cell_type), POINTER                           :: cell
     210             :       TYPE(colvar_counters)                              :: ncolv
     211             :       TYPE(cp_subsys_type), POINTER                      :: subsys
     212             :       TYPE(distribution_1d_type), POINTER                :: local_molecules
     213             :       TYPE(global_constraint_type), POINTER              :: gci
     214             :       TYPE(molecule_kind_list_type), POINTER             :: molecule_kinds
     215             :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     216             :       TYPE(molecule_list_type), POINTER                  :: molecules
     217          94 :       TYPE(molecule_type), POINTER                       :: molecule, molecule_set(:)
     218             :       TYPE(particle_list_type), POINTER                  :: particles
     219          94 :       TYPE(particle_type), POINTER                       :: particle_set(:)
     220             : 
     221          94 :       NULLIFY (cell, subsys, local_molecules, molecule_kinds, &
     222          94 :                molecules, molecule_kind, molecule, &
     223          94 :                molecule_set, particles, particle_set, gci)
     224          94 :       IF (PRESENT(Bmatrix)) THEN
     225          86 :          check = ASSOCIATED(Bmatrix)
     226          86 :          CPASSERT(check)
     227      423782 :          Bmatrix = 0.0_dp
     228             :       END IF
     229          94 :       CALL timeset(routineN, handle)
     230         282 :       ALLOCATE (map(SIZE(cvalues)))
     231        1410 :       map = HUGE(0) ! init all, since used in a sort, but not all set in parallel.
     232          94 :       CALL force_env_get(force_env=force_env, subsys=subsys, cell=cell)
     233          94 :       n_tot = 0
     234        1410 :       cvalues = 0.0_dp
     235             :       CALL cp_subsys_get(subsys=subsys, &
     236             :                          particles=particles, &
     237             :                          molecules=molecules, &
     238             :                          local_molecules=local_molecules, &
     239             :                          gci=gci, &
     240          94 :                          molecule_kinds=molecule_kinds)
     241             : 
     242          94 :       nkind = molecule_kinds%n_els
     243          94 :       particle_set => particles%els
     244          94 :       molecule_set => molecules%els
     245             :       ! Intramolecular Colvars
     246          94 :       IF (number_of_colvar(force_env, only_intra_colvar=.TRUE.) /= 0) THEN
     247         474 :          MOL: DO ikind = 1, nkind
     248         380 :             nmol_per_kind = local_molecules%n_el(ikind)
     249         698 :             DO imol = 1, nmol_per_kind
     250         224 :                i = local_molecules%list(ikind)%array(imol)
     251         224 :                molecule => molecule_set(i)
     252         224 :                molecule_kind => molecule%molecule_kind
     253             : 
     254             :                CALL get_molecule_kind(molecule_kind, &
     255         224 :                                       ncolv=ncolv)
     256         224 :                offset = get_colvar_offset(i, molecule_set)
     257             :                ! Collective variables
     258         828 :                IF (ncolv%ntot /= 0) THEN
     259             :                   CALL eval_colv_int(molecule, particle_set, coords, cell, cvalues, &
     260         328 :                                      Bmatrix, offset, n_tot, map)
     261             :                END IF
     262             :             END DO
     263             :          END DO MOL
     264          94 :          CALL force_env%para_env%sum(n_tot)
     265        2726 :          CALL force_env%para_env%sum(cvalues)
     266      847486 :          IF (PRESENT(Bmatrix)) CALL force_env%para_env%sum(Bmatrix)
     267             :       END IF
     268          94 :       offset = n_tot
     269             :       ! Intermolecular Colvars
     270          94 :       IF (ASSOCIATED(gci)) THEN
     271          94 :          IF (gci%ncolv%ntot /= 0) THEN
     272             :             CALL eval_colv_ext(gci, particle_set, coords, cell, cvalues, &
     273           0 :                                Bmatrix, offset, n_tot, map)
     274             :          END IF
     275             :       END IF
     276          94 :       CPASSERT(n_tot == SIZE(cvalues))
     277             :       ! Sort values of Collective Variables according the order of the input
     278             :       ! sections
     279         188 :       ALLOCATE (wrk(SIZE(cvalues)))
     280         282 :       ALLOCATE (rwrk(SIZE(cvalues)))
     281          94 :       CALL sort(map, SIZE(map), wrk)
     282        1410 :       rwrk = cvalues
     283        1410 :       DO i = 1, SIZE(wrk)
     284        1410 :          cvalues(i) = rwrk(wrk(i))
     285             :       END DO
     286             :       ! check and sort on Bmatrix
     287          94 :       IF (PRESENT(Bmatrix)) THEN
     288          86 :          check = n_tot == SIZE(Bmatrix, 2)
     289          86 :          CPASSERT(check)
     290         344 :          ALLOCATE (bwrk(SIZE(Bmatrix, 1), SIZE(Bmatrix, 2)))
     291      423782 :          bwrk(:, :) = Bmatrix
     292        1394 :          DO i = 1, SIZE(wrk)
     293      423782 :             Bmatrix(:, i) = bwrk(:, wrk(i))
     294             :          END DO
     295          86 :          DEALLOCATE (bwrk)
     296             :       END IF
     297          94 :       DEALLOCATE (rwrk)
     298          94 :       DEALLOCATE (wrk)
     299          94 :       DEALLOCATE (map)
     300             :       ! Construction of the Amatrix
     301          94 :       IF (PRESENT(Bmatrix) .AND. PRESENT(Amatrix)) THEN
     302          60 :          CPASSERT(ASSOCIATED(Amatrix))
     303          60 :          check = SIZE(Bmatrix, 1) == SIZE(Amatrix, 2)
     304          60 :          CPASSERT(check)
     305          60 :          check = SIZE(Bmatrix, 2) == SIZE(Amatrix, 1)
     306          60 :          CPASSERT(check)
     307         240 :          ALLOCATE (Gmatrix(n_tot, n_tot))
     308         180 :          ALLOCATE (Gmatrix_i(n_tot, n_tot))
     309        6540 :          Gmatrix(:, :) = MATMUL(TRANSPOSE(Bmatrix), Bmatrix)
     310          60 :          CALL invert_matrix(Gmatrix, Gmatrix_i, inv_error)
     311          60 :          IF (ABS(inv_error) > 1.0E-8_dp) &
     312           0 :             CPWARN("Error in inverting the Gmatrix larger than 1.0E-8!")
     313       30720 :          Amatrix = MATMUL(Gmatrix_i, TRANSPOSE(Bmatrix))
     314          60 :          DEALLOCATE (Gmatrix_i)
     315         120 :          DEALLOCATE (Gmatrix)
     316             :       END IF
     317          94 :       IF (PRESENT(MassI)) THEN
     318          86 :          natom = SIZE(particle_set)
     319          86 :          CPASSERT(ASSOCIATED(MassI))
     320          86 :          CPASSERT(SIZE(MassI) == natom*3)
     321        4018 :          DO i = 1, natom
     322        3932 :             MassI((i - 1)*3 + 1) = 1.0_dp/particle_set(i)%atomic_kind%mass
     323        3932 :             MassI((i - 1)*3 + 2) = 1.0_dp/particle_set(i)%atomic_kind%mass
     324        4018 :             MassI((i - 1)*3 + 3) = 1.0_dp/particle_set(i)%atomic_kind%mass
     325             :          END DO
     326             :       END IF
     327          94 :       CALL timestop(handle)
     328             : 
     329         274 :    END SUBROUTINE eval_colvar
     330             : 
     331             : ! **************************************************************************************************
     332             : !> \brief Computes the offset of the colvar for the specific molecule
     333             : !> \param i ...
     334             : !> \param molecule_set ...
     335             : !> \return ...
     336             : !> \author Teodoro Laino 05.2007 [tlaino] - Zurich University
     337             : ! **************************************************************************************************
     338         224 :    FUNCTION get_colvar_offset(i, molecule_set) RESULT(offset)
     339             :       INTEGER, INTENT(IN)                                :: i
     340             :       TYPE(molecule_type), POINTER                       :: molecule_set(:)
     341             :       INTEGER                                            :: offset
     342             : 
     343             :       INTEGER                                            :: j
     344             :       TYPE(colvar_counters)                              :: ncolv
     345             :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     346             :       TYPE(molecule_type), POINTER                       :: molecule
     347             : 
     348         224 :       offset = 0
     349        1082 :       DO j = 1, i - 1
     350         858 :          molecule => molecule_set(j)
     351         858 :          molecule_kind => molecule%molecule_kind
     352             :          CALL get_molecule_kind(molecule_kind, &
     353         858 :                                 ncolv=ncolv)
     354        1082 :          offset = offset + ncolv%ntot
     355             :       END DO
     356             : 
     357         224 :    END FUNCTION get_colvar_offset
     358             : 
     359             : ! **************************************************************************************************
     360             : !> \brief Computes Intramolecular colvar
     361             : !> \param molecule ...
     362             : !> \param particle_set ...
     363             : !> \param coords ...
     364             : !> \param cell ...
     365             : !> \param cvalues ...
     366             : !> \param Bmatrix ...
     367             : !> \param offset ...
     368             : !> \param n_tot ...
     369             : !> \param map ...
     370             : !> \author Teodoro Laino 05.2007 [tlaino] - Zurich University
     371             : ! **************************************************************************************************
     372         198 :    SUBROUTINE eval_colv_int(molecule, particle_set, coords, cell, cvalues, &
     373             :                             Bmatrix, offset, n_tot, map)
     374             : 
     375             :       TYPE(molecule_type), POINTER                       :: molecule
     376             :       TYPE(particle_type), POINTER                       :: particle_set(:)
     377             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), OPTIONAL  :: coords
     378             :       TYPE(cell_type), POINTER                           :: cell
     379             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: cvalues
     380             :       REAL(KIND=dp), DIMENSION(:, :), OPTIONAL, POINTER  :: Bmatrix
     381             :       INTEGER, INTENT(IN)                                :: offset
     382             :       INTEGER, INTENT(INOUT)                             :: n_tot
     383             :       INTEGER, DIMENSION(:), POINTER                     :: map
     384             : 
     385         198 :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     386         198 :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     387         198 :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     388             :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     389             : 
     390         198 :       NULLIFY (fixd_list)
     391             : 
     392         198 :       molecule_kind => molecule%molecule_kind
     393         198 :       CALL get_molecule_kind(molecule_kind, colv_list=colv_list, fixd_list=fixd_list)
     394         198 :       CALL get_molecule(molecule, lcolv=lcolv)
     395             :       CALL eval_colv_low(colv_list, fixd_list, lcolv, particle_set, &
     396         328 :                          coords, cell, cvalues, Bmatrix, offset, n_tot, map)
     397             : 
     398         198 :    END SUBROUTINE eval_colv_int
     399             : 
     400             : ! **************************************************************************************************
     401             : !> \brief Computes Intermolecular colvar
     402             : !> \param gci ...
     403             : !> \param particle_set ...
     404             : !> \param coords ...
     405             : !> \param cell ...
     406             : !> \param cvalues ...
     407             : !> \param Bmatrix ...
     408             : !> \param offset ...
     409             : !> \param n_tot ...
     410             : !> \param map ...
     411             : !> \author Teodoro Laino 05.2007 [tlaino] - Zurich University
     412             : ! **************************************************************************************************
     413           0 :    SUBROUTINE eval_colv_ext(gci, particle_set, coords, cell, cvalues, &
     414             :                             Bmatrix, offset, n_tot, map)
     415             :       TYPE(global_constraint_type), POINTER              :: gci
     416             :       TYPE(particle_type), POINTER                       :: particle_set(:)
     417             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), OPTIONAL  :: coords
     418             :       TYPE(cell_type), POINTER                           :: cell
     419             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: cvalues
     420             :       REAL(KIND=dp), DIMENSION(:, :), OPTIONAL, POINTER  :: Bmatrix
     421             :       INTEGER, INTENT(IN)                                :: offset
     422             :       INTEGER, INTENT(INOUT)                             :: n_tot
     423             :       INTEGER, DIMENSION(:), POINTER                     :: map
     424             : 
     425             :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     426             :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     427             :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     428             : 
     429           0 :       colv_list => gci%colv_list
     430           0 :       fixd_list => gci%fixd_list
     431           0 :       lcolv => gci%lcolv
     432             :       CALL eval_colv_low(colv_list, fixd_list, lcolv, particle_set, &
     433           0 :                          coords, cell, cvalues, Bmatrix, offset, n_tot, map)
     434             : 
     435           0 :    END SUBROUTINE eval_colv_ext
     436             : 
     437             : ! **************************************************************************************************
     438             : !> \brief Real evaluation of colvar and of the Wilson-Eliashevich Matrix
     439             : !>      B_ik : i: internal  coordinates
     440             : !>             k: cartesian coordinates
     441             : !> \param colv_list ...
     442             : !> \param fixd_list ...
     443             : !> \param lcolv ...
     444             : !> \param particle_set ...
     445             : !> \param coords ...
     446             : !> \param cell ...
     447             : !> \param cvalues ...
     448             : !> \param Bmatrix ...
     449             : !> \param offset ...
     450             : !> \param n_tot ...
     451             : !> \param map ...
     452             : !> \author Teodoro Laino 05.2007 [tlaino] - Zurich University
     453             : ! **************************************************************************************************
     454         198 :    SUBROUTINE eval_colv_low(colv_list, fixd_list, lcolv, particle_set, coords, &
     455         198 :                             cell, cvalues, Bmatrix, offset, n_tot, map)
     456             : 
     457             :       TYPE(colvar_constraint_type), POINTER              :: colv_list(:)
     458             :       TYPE(fixd_constraint_type), DIMENSION(:), POINTER  :: fixd_list
     459             :       TYPE(local_colvar_constraint_type), POINTER        :: lcolv(:)
     460             :       TYPE(particle_type), POINTER                       :: particle_set(:)
     461             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), OPTIONAL  :: coords
     462             :       TYPE(cell_type), POINTER                           :: cell
     463             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: cvalues
     464             :       REAL(KIND=dp), DIMENSION(:, :), OPTIONAL, POINTER  :: Bmatrix
     465             :       INTEGER, INTENT(IN)                                :: offset
     466             :       INTEGER, INTENT(INOUT)                             :: n_tot
     467             :       INTEGER, DIMENSION(:), POINTER                     :: map
     468             : 
     469             :       INTEGER                                            :: iatm, iconst, ind, ival
     470             : 
     471         198 :       ival = offset
     472         890 :       DO iconst = 1, SIZE(colv_list)
     473         692 :          n_tot = n_tot + 1
     474         692 :          ival = ival + 1
     475             :          ! Update colvar
     476         692 :          IF (PRESENT(coords)) THEN
     477             :             CALL colvar_eval_mol_f(lcolv(iconst)%colvar, cell, particles=particle_set, &
     478         204 :                                    pos=RESHAPE(coords, (/3, SIZE(particle_set)/)), fixd_list=fixd_list)
     479             :          ELSE
     480             :             CALL colvar_eval_mol_f(lcolv(iconst)%colvar, cell, particles=particle_set, &
     481         624 :                                    fixd_list=fixd_list)
     482             :          END IF
     483         692 :          cvalues(ival) = lcolv(iconst)%colvar%ss
     484         692 :          map(ival) = colv_list(iconst)%inp_seq_num
     485             :          ! Build the Wilson-Eliashevich Matrix
     486         890 :          IF (PRESENT(Bmatrix)) THEN
     487        2172 :             DO iatm = 1, SIZE(lcolv(iconst)%colvar%i_atom)
     488        1488 :                ind = (lcolv(iconst)%colvar%i_atom(iatm) - 1)*3
     489        1488 :                Bmatrix(ind + 1, ival) = lcolv(iconst)%colvar%dsdr(1, iatm)
     490        1488 :                Bmatrix(ind + 2, ival) = lcolv(iconst)%colvar%dsdr(2, iatm)
     491        2172 :                Bmatrix(ind + 3, ival) = lcolv(iconst)%colvar%dsdr(3, iatm)
     492             :             END DO
     493             :          END IF
     494             :       END DO
     495             : 
     496         198 :    END SUBROUTINE eval_colv_low
     497             : 
     498             : ! **************************************************************************************************
     499             : !> \brief Computes the forces in the frame of collective variables, and additional
     500             : !>        also the local metric tensor
     501             : !> \param force_env ...
     502             : !> \param forces ...
     503             : !> \param coords ...
     504             : !> \param nsize_xyz ...
     505             : !> \param nsize_int ...
     506             : !> \param cvalues ...
     507             : !> \param Mmatrix ...
     508             : !> \author Teodoro Laino 05.2007
     509             : ! **************************************************************************************************
     510          86 :    SUBROUTINE get_clv_force(force_env, forces, coords, nsize_xyz, nsize_int, cvalues, &
     511          86 :                             Mmatrix)
     512             :       TYPE(force_env_type), POINTER                      :: force_env
     513             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT), &
     514             :          OPTIONAL                                        :: forces, coords
     515             :       INTEGER, INTENT(IN)                                :: nsize_xyz, nsize_int
     516             :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: cvalues, Mmatrix
     517             : 
     518             :       INTEGER                                            :: i, j, k
     519             :       REAL(KIND=dp)                                      :: tmp
     520          86 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: MassI, wrk
     521          86 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: Amatrix, Bmatrix
     522             : 
     523         344 :       ALLOCATE (Bmatrix(nsize_xyz, nsize_int))
     524         258 :       ALLOCATE (MassI(nsize_xyz))
     525             :       ! Transform gradients if requested
     526          86 :       IF (PRESENT(forces)) THEN
     527         180 :          ALLOCATE (wrk(nsize_int))
     528         180 :          ALLOCATE (Amatrix(nsize_int, nsize_xyz))
     529             :          ! Compute the transformation matrices and the inverse mass diagonal Matrix
     530          60 :          CALL eval_colvar(force_env, coords, cvalues, Bmatrix, MassI, Amatrix)
     531       15540 :          wrk = MATMUL(Amatrix, forces)
     532        3120 :          forces = 0.0_dp
     533         120 :          forces(1:nsize_int) = wrk
     534          60 :          DEALLOCATE (Amatrix)
     535          60 :          DEALLOCATE (wrk)
     536             :       ELSE
     537             :          ! Compute the transformation matrices and the inverse mass diagonal Matrix
     538          52 :          CALL eval_colvar(force_env, coords, cvalues, Bmatrix, MassI)
     539             :       END IF
     540             :       ! Compute the Metric Tensor
     541        1394 :       DO i = 1, nsize_int
     542       32030 :          DO j = 1, i
     543             :             tmp = 0.0_dp
     544    10307232 :             DO k = 1, nsize_xyz
     545    10307232 :                tmp = tmp + Bmatrix(k, j)*MassI(k)*Bmatrix(k, i)
     546             :             END DO
     547       30636 :             Mmatrix((i - 1)*nsize_int + j) = tmp
     548       31944 :             Mmatrix((j - 1)*nsize_int + i) = tmp
     549             :          END DO
     550             :       END DO
     551          86 :       DEALLOCATE (MassI)
     552          86 :       DEALLOCATE (Bmatrix)
     553          86 :    END SUBROUTINE get_clv_force
     554             : 
     555             : ! **************************************************************************************************
     556             : !> \brief Complete the description of the COORDINATION colvar when
     557             : !>      defined using KINDS
     558             : !> \param colvar ...
     559             : !> \param particles ...
     560             : !> \par History
     561             : !>      1.2009 Fabio Sterpone : Added a part for population
     562             : !>     10.2014 Moved out of colvar_types.F [Ole Schuett]
     563             : !> \author Teodoro Laino - 07.2007
     564             : ! **************************************************************************************************
     565         912 :    SUBROUTINE post_process_colvar(colvar, particles)
     566             :       TYPE(colvar_type), POINTER                         :: colvar
     567             :       TYPE(particle_type), DIMENSION(:), OPTIONAL, &
     568             :          POINTER                                         :: particles
     569             : 
     570             :       CHARACTER(len=3)                                   :: name_kind
     571             :       INTEGER                                            :: i, ii, j, natoms, nkinds, nr_frame, stat
     572             : 
     573         912 :       natoms = SIZE(particles)
     574         912 :       IF (colvar%type_id == coord_colvar_id) THEN
     575          54 :          IF (colvar%coord_param%use_kinds_from .OR. colvar%coord_param%use_kinds_to) THEN
     576             :             ! Atoms from
     577           6 :             IF (colvar%coord_param%use_kinds_from) THEN
     578           6 :                colvar%coord_param%use_kinds_from = .FALSE.
     579           6 :                nkinds = SIZE(colvar%coord_param%c_kinds_from)
     580          30 :                DO i = 1, natoms
     581          54 :                   DO j = 1, nkinds
     582          24 :                      name_kind = TRIM(particles(i)%atomic_kind%name)
     583          24 :                      CALL uppercase(name_kind)
     584          48 :                      IF (TRIM(colvar%coord_param%c_kinds_from(j)) == name_kind) THEN
     585           8 :                         CALL reallocate(colvar%coord_param%i_at_from, 1, colvar%coord_param%n_atoms_from + 1)
     586           8 :                         colvar%coord_param%n_atoms_from = colvar%coord_param%n_atoms_from + 1
     587           8 :                         colvar%coord_param%i_at_from(colvar%coord_param%n_atoms_from) = i
     588             :                      END IF
     589             :                   END DO
     590             :                END DO
     591           6 :                stat = colvar%coord_param%n_atoms_from
     592           6 :                CPASSERT(stat /= 0)
     593             :             END IF
     594             :             ! Atoms to
     595           6 :             IF (colvar%coord_param%use_kinds_to) THEN
     596           6 :                colvar%coord_param%use_kinds_to = .FALSE.
     597           6 :                nkinds = SIZE(colvar%coord_param%c_kinds_to)
     598          30 :                DO i = 1, natoms
     599          54 :                   DO j = 1, nkinds
     600          24 :                      name_kind = TRIM(particles(i)%atomic_kind%name)
     601          24 :                      CALL uppercase(name_kind)
     602          48 :                      IF (TRIM(colvar%coord_param%c_kinds_to(j)) == name_kind) THEN
     603          10 :                         CALL reallocate(colvar%coord_param%i_at_to, 1, colvar%coord_param%n_atoms_to + 1)
     604          10 :                         colvar%coord_param%n_atoms_to = colvar%coord_param%n_atoms_to + 1
     605          10 :                         colvar%coord_param%i_at_to(colvar%coord_param%n_atoms_to) = i
     606             :                      END IF
     607             :                   END DO
     608             :                END DO
     609           6 :                stat = colvar%coord_param%n_atoms_to
     610           6 :                CPASSERT(stat /= 0)
     611             :             END IF
     612             :             ! Atoms to b
     613           6 :             IF (colvar%coord_param%use_kinds_to_b) THEN
     614           2 :                colvar%coord_param%use_kinds_to_b = .FALSE.
     615           2 :                nkinds = SIZE(colvar%coord_param%c_kinds_to_b)
     616           8 :                DO i = 1, natoms
     617          14 :                   DO j = 1, nkinds
     618           6 :                      name_kind = TRIM(particles(i)%atomic_kind%name)
     619           6 :                      CALL uppercase(name_kind)
     620          12 :                      IF (TRIM(colvar%coord_param%c_kinds_to_b(j)) == name_kind) THEN
     621           2 :                         CALL reallocate(colvar%coord_param%i_at_to_b, 1, colvar%coord_param%n_atoms_to_b + 1)
     622           2 :                         colvar%coord_param%n_atoms_to_b = colvar%coord_param%n_atoms_to_b + 1
     623           2 :                         colvar%coord_param%i_at_to_b(colvar%coord_param%n_atoms_to_b) = i
     624             :                      END IF
     625             :                   END DO
     626             :                END DO
     627           2 :                stat = colvar%coord_param%n_atoms_to_b
     628           2 :                CPASSERT(stat /= 0)
     629             :             END IF
     630             : 
     631             :             ! Setup the colvar
     632           6 :             CALL colvar_setup(colvar)
     633             :          END IF
     634             :       END IF
     635             : 
     636         912 :       IF (colvar%type_id == mindist_colvar_id) THEN
     637           0 :          IF (colvar%mindist_param%use_kinds_from .OR. colvar%mindist_param%use_kinds_to) THEN
     638             :             ! Atoms from
     639           0 :             IF (colvar%mindist_param%use_kinds_from) THEN
     640           0 :                colvar%mindist_param%use_kinds_from = .FALSE.
     641           0 :                nkinds = SIZE(colvar%mindist_param%k_coord_from)
     642           0 :                DO i = 1, natoms
     643           0 :                   DO j = 1, nkinds
     644           0 :                      name_kind = TRIM(particles(i)%atomic_kind%name)
     645           0 :                      CALL uppercase(name_kind)
     646           0 :                      IF (TRIM(colvar%mindist_param%k_coord_from(j)) == name_kind) THEN
     647           0 :                         CALL reallocate(colvar%mindist_param%i_coord_from, 1, colvar%mindist_param%n_coord_from + 1)
     648           0 :                         colvar%mindist_param%n_coord_from = colvar%mindist_param%n_coord_from + 1
     649           0 :                         colvar%mindist_param%i_coord_from(colvar%mindist_param%n_coord_from) = i
     650             :                      END IF
     651             :                   END DO
     652             :                END DO
     653           0 :                stat = colvar%mindist_param%n_coord_from
     654           0 :                CPASSERT(stat /= 0)
     655             :             END IF
     656             :             ! Atoms to
     657           0 :             IF (colvar%mindist_param%use_kinds_to) THEN
     658           0 :                colvar%mindist_param%use_kinds_to = .FALSE.
     659           0 :                nkinds = SIZE(colvar%mindist_param%k_coord_to)
     660           0 :                DO i = 1, natoms
     661           0 :                   DO j = 1, nkinds
     662           0 :                      name_kind = TRIM(particles(i)%atomic_kind%name)
     663           0 :                      CALL uppercase(name_kind)
     664           0 :                      IF (TRIM(colvar%mindist_param%k_coord_to(j)) == name_kind) THEN
     665           0 :                         CALL reallocate(colvar%mindist_param%i_coord_to, 1, colvar%mindist_param%n_coord_to + 1)
     666           0 :                         colvar%mindist_param%n_coord_to = colvar%mindist_param%n_coord_to + 1
     667           0 :                         colvar%mindist_param%i_coord_to(colvar%mindist_param%n_coord_to) = i
     668             :                      END IF
     669             :                   END DO
     670             :                END DO
     671           0 :                stat = colvar%mindist_param%n_coord_to
     672           0 :                CPASSERT(stat /= 0)
     673             :             END IF
     674             :             ! Setup the colvar
     675           0 :             CALL colvar_setup(colvar)
     676             :          END IF
     677             :       END IF
     678             : 
     679         912 :       IF (colvar%type_id == population_colvar_id) THEN
     680             : 
     681           8 :          IF (colvar%population_param%use_kinds_from .OR. colvar%population_param%use_kinds_to) THEN
     682             :             ! Atoms from
     683           8 :             IF (colvar%population_param%use_kinds_from) THEN
     684           0 :                colvar%population_param%use_kinds_from = .FALSE.
     685           0 :                nkinds = SIZE(colvar%population_param%c_kinds_from)
     686           0 :                DO i = 1, natoms
     687           0 :                   DO j = 1, nkinds
     688           0 :                      name_kind = TRIM(particles(i)%atomic_kind%name)
     689           0 :                      CALL uppercase(name_kind)
     690           0 :                      IF (TRIM(colvar%population_param%c_kinds_from(j)) == name_kind) THEN
     691           0 :                         CALL reallocate(colvar%population_param%i_at_from, 1, colvar%population_param%n_atoms_from + 1)
     692           0 :                         colvar%population_param%n_atoms_from = colvar%population_param%n_atoms_from + 1
     693           0 :                         colvar%population_param%i_at_from(colvar%population_param%n_atoms_from) = i
     694             :                      END IF
     695             :                   END DO
     696             :                END DO
     697           0 :                stat = colvar%population_param%n_atoms_from
     698           0 :                CPASSERT(stat /= 0)
     699             :             END IF
     700             :             ! Atoms to
     701           8 :             IF (colvar%population_param%use_kinds_to) THEN
     702           8 :                colvar%population_param%use_kinds_to = .FALSE.
     703           8 :                nkinds = SIZE(colvar%population_param%c_kinds_to)
     704          32 :                DO i = 1, natoms
     705          56 :                   DO j = 1, nkinds
     706          24 :                      name_kind = TRIM(particles(i)%atomic_kind%name)
     707          24 :                      CALL uppercase(name_kind)
     708          48 :                      IF (TRIM(colvar%population_param%c_kinds_to(j)) == name_kind) THEN
     709          16 :                         CALL reallocate(colvar%population_param%i_at_to, 1, colvar%population_param%n_atoms_to + 1)
     710          16 :                         colvar%population_param%n_atoms_to = colvar%population_param%n_atoms_to + 1
     711          16 :                         colvar%population_param%i_at_to(colvar%population_param%n_atoms_to) = i
     712             :                      END IF
     713             :                   END DO
     714             :                END DO
     715           8 :                stat = colvar%population_param%n_atoms_to
     716           8 :                CPASSERT(stat /= 0)
     717             :             END IF
     718             :             ! Setup the colvar
     719           8 :             CALL colvar_setup(colvar)
     720             :          END IF
     721             : 
     722             :       END IF
     723             : 
     724         912 :       IF (colvar%type_id == gyration_colvar_id) THEN
     725             : 
     726           2 :          IF (colvar%gyration_param%use_kinds) THEN
     727             :             ! Atoms from
     728             :             IF (colvar%gyration_param%use_kinds) THEN
     729           2 :                colvar%gyration_param%use_kinds = .FALSE.
     730           2 :                nkinds = SIZE(colvar%gyration_param%c_kinds)
     731          28 :                DO i = 1, natoms
     732          54 :                   DO j = 1, nkinds
     733          26 :                      name_kind = TRIM(particles(i)%atomic_kind%name)
     734          26 :                      CALL uppercase(name_kind)
     735          52 :                      IF (TRIM(colvar%gyration_param%c_kinds(j)) == name_kind) THEN
     736          26 :                         CALL reallocate(colvar%gyration_param%i_at, 1, colvar%gyration_param%n_atoms + 1)
     737          26 :                         colvar%gyration_param%n_atoms = colvar%gyration_param%n_atoms + 1
     738          26 :                         colvar%gyration_param%i_at(colvar%gyration_param%n_atoms) = i
     739             :                      END IF
     740             :                   END DO
     741             :                END DO
     742           2 :                stat = colvar%gyration_param%n_atoms
     743           2 :                CPASSERT(stat /= 0)
     744             :             END IF
     745             :             ! Setup the colvar
     746           2 :             CALL colvar_setup(colvar)
     747             :          END IF
     748             :       END IF
     749             : 
     750         912 :       IF (colvar%type_id == rmsd_colvar_id) THEN
     751           4 :          IF (colvar%rmsd_param%subset == rmsd_all .OR. colvar%rmsd_param%subset == rmsd_list) THEN
     752             :             ! weights are masses
     753          28 :             DO i = 1, SIZE(colvar%rmsd_param%i_rmsd)
     754          24 :                ii = colvar%rmsd_param%i_rmsd(i)
     755          28 :                colvar%rmsd_param%weights(ii) = particles(ii)%atomic_kind%mass
     756             :             END DO
     757             :          END IF
     758             : 
     759           4 :          IF (colvar%rmsd_param%align_frames) THEN
     760           0 :             nr_frame = SIZE(colvar%rmsd_param%r_ref, 2)
     761           0 :             DO i = 2, nr_frame
     762             :                CALL rmsd3(particles, colvar%rmsd_param%r_ref(:, i), colvar%rmsd_param%r_ref(:, 1), -1, &
     763           0 :                           rotate=.TRUE.)
     764             :             END DO
     765             :          END IF
     766             : 
     767             :       END IF
     768             : 
     769         912 :       IF (colvar%type_id == distance_from_path_colvar_id .OR. colvar%type_id == reaction_path_colvar_id) THEN
     770          20 :          IF (colvar%reaction_path_param%dist_rmsd .OR. colvar%reaction_path_param%rmsd) THEN
     771           8 :             IF (colvar%reaction_path_param%align_frames) THEN
     772           8 :                nr_frame = colvar%reaction_path_param%nr_frames
     773          40 :                DO i = 2, nr_frame
     774             :                   CALL rmsd3(particles, colvar%reaction_path_param%r_ref(:, i), colvar%reaction_path_param%r_ref(:, 1), -1, &
     775          40 :                              rotate=.TRUE.)
     776             :                END DO
     777             :             END IF
     778             :          END IF
     779             :       END IF
     780             : 
     781         912 :    END SUBROUTINE post_process_colvar
     782             : 
     783          60 : END MODULE colvar_utils

Generated by: LCOV version 1.15