LCOV - code coverage report
Current view: top level - src - force_fields_all.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:8ebf9ad) Lines: 93.3 % 1673 1561
Test Date: 2026-01-22 06:43:13 Functions: 100.0 % 25 25

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \par History
      10              : !>      Splitting and cleaning the original force_field_pack - May 2007
      11              : !>      Teodoro Laino - Zurich University
      12              : !> \author CJM
      13              : ! **************************************************************************************************
      14              : MODULE force_fields_all
      15              : 
      16              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      17              :                                               get_atomic_kind,&
      18              :                                               get_atomic_kind_set,&
      19              :                                               set_atomic_kind
      20              :    USE atoms_input,                     ONLY: read_shell_coord_input
      21              :    USE cell_types,                      ONLY: cell_type
      22              :    USE cp_linked_list_input,            ONLY: cp_sll_val_next,&
      23              :                                               cp_sll_val_type
      24              :    USE cp_log_handling,                 ONLY: cp_to_string
      25              :    USE damping_dipole_types,            ONLY: damping_p_create,&
      26              :                                               damping_p_type,&
      27              :                                               tang_toennies
      28              :    USE ewald_environment_types,         ONLY: ewald_env_get,&
      29              :                                               ewald_env_set,&
      30              :                                               ewald_environment_type
      31              :    USE external_potential_types,        ONLY: fist_potential_type,&
      32              :                                               get_potential,&
      33              :                                               set_potential
      34              :    USE force_field_kind_types,          ONLY: &
      35              :         allocate_bend_kind_set, allocate_bond_kind_set, allocate_impr_kind_set, &
      36              :         allocate_opbend_kind_set, allocate_torsion_kind_set, allocate_ub_kind_set, bend_kind_type, &
      37              :         bond_kind_type, do_ff_amber, do_ff_charmm, do_ff_g87, do_ff_g96, do_ff_undef, &
      38              :         impr_kind_type, opbend_kind_type, torsion_kind_type, ub_kind_type
      39              :    USE force_field_types,               ONLY: amber_info_type,&
      40              :                                               charmm_info_type,&
      41              :                                               force_field_type,&
      42              :                                               gromos_info_type,&
      43              :                                               input_info_type
      44              :    USE input_constants,                 ONLY: do_qmmm_none
      45              :    USE input_cp2k_binary_restarts,      ONLY: read_binary_cs_coordinates
      46              :    USE input_section_types,             ONLY: section_vals_get,&
      47              :                                               section_vals_get_subs_vals,&
      48              :                                               section_vals_list_get,&
      49              :                                               section_vals_type,&
      50              :                                               section_vals_val_get
      51              :    USE input_val_types,                 ONLY: val_get,&
      52              :                                               val_type
      53              :    USE kinds,                           ONLY: default_path_length,&
      54              :                                               default_string_length,&
      55              :                                               dp
      56              :    USE mathconstants,                   ONLY: sqrthalf
      57              :    USE memory_utilities,                ONLY: reallocate
      58              :    USE molecule_kind_types,             ONLY: &
      59              :         bend_type, bond_type, get_molecule_kind, impr_type, molecule_kind_type, opbend_type, &
      60              :         set_molecule_kind, shell_type, torsion_type, ub_type
      61              :    USE molecule_types,                  ONLY: get_molecule,&
      62              :                                               molecule_type
      63              :    USE pair_potential,                  ONLY: get_nonbond_storage,&
      64              :                                               spline_nonbond_control
      65              :    USE pair_potential_coulomb,          ONLY: potential_coulomb
      66              :    USE pair_potential_types,            ONLY: &
      67              :         ace_type, allegro_type, deepmd_type, ea_type, lj_charmm_type, lj_type, nequip_type, &
      68              :         nn_type, nosh_nosh, nosh_sh, pair_potential_lj_create, pair_potential_pp_create, &
      69              :         pair_potential_pp_type, pair_potential_single_add, pair_potential_single_clean, &
      70              :         pair_potential_single_copy, pair_potential_single_type, sh_sh, siepmann_type, tersoff_type
      71              :    USE particle_types,                  ONLY: allocate_particle_set,&
      72              :                                               particle_type
      73              :    USE physcon,                         ONLY: bohr
      74              :    USE qmmm_ff_fist,                    ONLY: qmmm_ff_precond_only_qm
      75              :    USE qmmm_types_low,                  ONLY: qmmm_env_mm_type
      76              :    USE shell_potential_types,           ONLY: shell_kind_type
      77              :    USE splines_types,                   ONLY: spline_data_p_release,&
      78              :                                               spline_data_p_retain,&
      79              :                                               spline_data_p_type,&
      80              :                                               spline_env_release,&
      81              :                                               spline_environment_type
      82              :    USE string_utilities,                ONLY: compress,&
      83              :                                               integer_to_string,&
      84              :                                               uppercase
      85              : #include "./base/base_uses.f90"
      86              : 
      87              :    IMPLICIT NONE
      88              : 
      89              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'force_fields_all'
      90              : 
      91              :    PRIVATE
      92              :    LOGICAL, PARAMETER                   :: debug_this_module = .FALSE.
      93              : 
      94              :    PUBLIC :: force_field_unique_bond, &
      95              :              force_field_unique_bend, &
      96              :              force_field_unique_ub, &
      97              :              force_field_unique_tors, &
      98              :              force_field_unique_impr, &
      99              :              force_field_unique_opbend, &
     100              :              force_field_pack_bond, &
     101              :              force_field_pack_bend, &
     102              :              force_field_pack_ub, &
     103              :              force_field_pack_tors, &
     104              :              force_field_pack_impr, &
     105              :              force_field_pack_opbend, &
     106              :              force_field_pack_charge, &
     107              :              force_field_pack_charges, &
     108              :              force_field_pack_radius, &
     109              :              force_field_pack_pol, &
     110              :              force_field_pack_shell, &
     111              :              force_field_pack_nonbond14, &
     112              :              force_field_pack_nonbond, &
     113              :              force_field_pack_splines, &
     114              :              force_field_pack_eicut, &
     115              :              force_field_pack_damp
     116              : 
     117              : CONTAINS
     118              : 
     119              : ! **************************************************************************************************
     120              : !> \brief Determine the number of unique bond kind and allocate bond_kind_set
     121              : !> \param particle_set ...
     122              : !> \param molecule_kind_set ...
     123              : !> \param molecule_set ...
     124              : !> \param ff_type ...
     125              : !> \param iw ...
     126              : ! **************************************************************************************************
     127         2645 :    SUBROUTINE force_field_unique_bond(particle_set, molecule_kind_set, molecule_set, ff_type, iw)
     128              : 
     129              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     130              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     131              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     132              :       TYPE(force_field_type), INTENT(INOUT)              :: ff_type
     133              :       INTEGER, INTENT(IN)                                :: iw
     134              : 
     135              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_unique_bond'
     136              : 
     137              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_a2, name_atm_b, &
     138              :                                                             name_atm_b2
     139              :       INTEGER                                            :: atm_a, atm_b, counter, first, handle2, &
     140              :                                                             i, j, k, last, natom, nbond
     141         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
     142         2645 :       INTEGER, POINTER                                   :: map_bond_kind(:)
     143              :       LOGICAL                                            :: found
     144              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     145         2645 :       TYPE(bond_kind_type), DIMENSION(:), POINTER        :: bond_kind_set
     146         2645 :       TYPE(bond_type), DIMENSION(:), POINTER             :: bond_list
     147              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     148              :       TYPE(molecule_type), POINTER                       :: molecule
     149              : 
     150         2645 :       CALL timeset(routineN, handle2)
     151              : 
     152         2645 :       IF (iw > 0) THEN
     153              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
     154          239 :             "FORCEFIELD| Checking for unique bond terms"
     155              :       END IF
     156              : 
     157        75469 :       DO i = 1, SIZE(molecule_kind_set)
     158        72824 :          molecule_kind => molecule_kind_set(i)
     159              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
     160              :                                 molecule_list=molecule_list, &
     161              :                                 natom=natom, &
     162        72824 :                                 nbond=nbond, bond_list=bond_list)
     163        72824 :          molecule => molecule_set(molecule_list(1))
     164        72824 :          CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
     165       148293 :          IF (nbond > 0) THEN
     166        88293 :             ALLOCATE (map_bond_kind(nbond))
     167        29431 :             counter = 0
     168        29431 :             IF ((ff_type%ff_type == do_ff_g96) .OR. (ff_type%ff_type == do_ff_g87)) THEN
     169          148 :                DO j = 1, nbond
     170          148 :                   map_bond_kind(j) = j
     171              :                END DO
     172           20 :                counter = nbond
     173              :             ELSE
     174       144226 :                DO j = 1, nbond
     175       114815 :                   atm_a = bond_list(j)%a
     176       114815 :                   atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     177              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     178       114815 :                                        name=name_atm_a)
     179       114815 :                   atm_b = bond_list(j)%b
     180       114815 :                   atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     181              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     182       114815 :                                        name=name_atm_b)
     183       114815 :                   found = .FALSE.
     184       483445 :                   DO k = 1, j - 1
     185       416664 :                      atm_a = bond_list(k)%a
     186       416664 :                      atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     187              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     188       416664 :                                           name=name_atm_a2)
     189       416664 :                      atm_b = bond_list(k)%b
     190       416664 :                      atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     191              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     192       416664 :                                           name=name_atm_b2)
     193              :                      IF ((((name_atm_a) == (name_atm_a2)) .AND. &
     194       416664 :                           ((name_atm_b) == (name_atm_b2))) .OR. &
     195              :                          (((name_atm_a) == (name_atm_b2)) .AND. &
     196        66781 :                           ((name_atm_b) == (name_atm_a2)))) THEN
     197        48034 :                         found = .TRUE.
     198        48034 :                         map_bond_kind(j) = map_bond_kind(k)
     199              :                         EXIT
     200              :                      END IF
     201              :                   END DO
     202        29411 :                   IF (.NOT. found) THEN
     203        66781 :                      counter = counter + 1
     204        66781 :                      map_bond_kind(j) = counter
     205              :                   END IF
     206              :                END DO
     207              :             END IF
     208        29431 :             NULLIFY (bond_kind_set)
     209        29431 :             CALL allocate_bond_kind_set(bond_kind_set, counter)
     210       144374 :             DO j = 1, nbond
     211       144374 :                bond_list(j)%bond_kind => bond_kind_set(map_bond_kind(j))
     212              :             END DO
     213              :             CALL set_molecule_kind(molecule_kind=molecule_kind, &
     214        29431 :                                    bond_kind_set=bond_kind_set, bond_list=bond_list)
     215        29431 :             DEALLOCATE (map_bond_kind)
     216              :          END IF
     217              :       END DO
     218         2645 :       CALL timestop(handle2)
     219              : 
     220         2645 :    END SUBROUTINE force_field_unique_bond
     221              : 
     222              : ! **************************************************************************************************
     223              : !> \brief Determine the number of unique bend kind and allocate bend_kind_set
     224              : !> \param particle_set ...
     225              : !> \param molecule_kind_set ...
     226              : !> \param molecule_set ...
     227              : !> \param ff_type ...
     228              : !> \param iw ...
     229              : ! **************************************************************************************************
     230         2645 :    SUBROUTINE force_field_unique_bend(particle_set, molecule_kind_set, molecule_set, ff_type, iw)
     231              : 
     232              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     233              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     234              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     235              :       TYPE(force_field_type), INTENT(INOUT)              :: ff_type
     236              :       INTEGER, INTENT(IN)                                :: iw
     237              : 
     238              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_unique_bend'
     239              : 
     240              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_a2, name_atm_b, &
     241              :                                                             name_atm_b2, name_atm_c, name_atm_c2
     242              :       INTEGER                                            :: atm_a, atm_b, atm_c, counter, first, &
     243              :                                                             handle2, i, j, k, last, natom, nbend
     244         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
     245         2645 :       INTEGER, POINTER                                   :: map_bend_kind(:)
     246              :       LOGICAL                                            :: found
     247              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     248         2645 :       TYPE(bend_kind_type), DIMENSION(:), POINTER        :: bend_kind_set
     249         2645 :       TYPE(bend_type), DIMENSION(:), POINTER             :: bend_list
     250              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     251              :       TYPE(molecule_type), POINTER                       :: molecule
     252              : 
     253         2645 :       CALL timeset(routineN, handle2)
     254              : 
     255         2645 :       IF (iw > 0) THEN
     256              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
     257          239 :             "FORCEFIELD| Checking for unique bend terms"
     258              :       END IF
     259              : 
     260        75469 :       DO i = 1, SIZE(molecule_kind_set)
     261        72824 :          molecule_kind => molecule_kind_set(i)
     262              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
     263              :                                 molecule_list=molecule_list, &
     264              :                                 natom=natom, &
     265        72824 :                                 nbend=nbend, bend_list=bend_list)
     266        72824 :          molecule => molecule_set(molecule_list(1))
     267        72824 :          CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
     268       148293 :          IF (nbend > 0) THEN
     269        87303 :             ALLOCATE (map_bend_kind(nbend))
     270        29101 :             counter = 0
     271        29101 :             IF ((ff_type%ff_type == do_ff_g96) .OR. (ff_type%ff_type == do_ff_g87)) THEN
     272          168 :                DO j = 1, nbend
     273          168 :                   map_bend_kind(j) = j
     274              :                END DO
     275           12 :                counter = nbend
     276              :             ELSE
     277       169563 :                DO j = 1, nbend
     278       140474 :                   atm_a = bend_list(j)%a
     279       140474 :                   atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     280              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     281       140474 :                                        name=name_atm_a)
     282       140474 :                   atm_b = bend_list(j)%b
     283       140474 :                   atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     284              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     285       140474 :                                        name=name_atm_b)
     286       140474 :                   atm_c = bend_list(j)%c
     287       140474 :                   atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
     288              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     289       140474 :                                        name=name_atm_c)
     290       140474 :                   found = .FALSE.
     291      2499737 :                   DO k = 1, j - 1
     292      2404937 :                      atm_a = bend_list(k)%a
     293      2404937 :                      atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     294              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     295      2404937 :                                           name=name_atm_a2)
     296      2404937 :                      atm_b = bend_list(k)%b
     297      2404937 :                      atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     298              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     299      2404937 :                                           name=name_atm_b2)
     300      2404937 :                      atm_c = bend_list(k)%c
     301      2404937 :                      atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
     302              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     303      2404937 :                                           name=name_atm_c2)
     304              :                      IF ((((name_atm_a) == (name_atm_a2)) .AND. &
     305              :                           ((name_atm_b) == (name_atm_b2)) .AND. &
     306      2404937 :                           ((name_atm_c) == (name_atm_c2))) .OR. &
     307              :                          (((name_atm_a) == (name_atm_c2)) .AND. &
     308              :                           ((name_atm_b) == (name_atm_b2)) .AND. &
     309        94800 :                           ((name_atm_c) == (name_atm_a2)))) THEN
     310        45674 :                         found = .TRUE.
     311        45674 :                         map_bend_kind(j) = map_bend_kind(k)
     312              :                         EXIT
     313              :                      END IF
     314              :                   END DO
     315        29089 :                   IF (.NOT. found) THEN
     316        94800 :                      counter = counter + 1
     317        94800 :                      map_bend_kind(j) = counter
     318              :                   END IF
     319              :                END DO
     320              :             END IF
     321        29101 :             NULLIFY (bend_kind_set)
     322        29101 :             CALL allocate_bend_kind_set(bend_kind_set, counter)
     323       169731 :             DO j = 1, nbend
     324       169731 :                bend_list(j)%bend_kind => bend_kind_set(map_bend_kind(j))
     325              :             END DO
     326              :             CALL set_molecule_kind(molecule_kind=molecule_kind, &
     327        29101 :                                    bend_kind_set=bend_kind_set, bend_list=bend_list)
     328        29101 :             DEALLOCATE (map_bend_kind)
     329              :          END IF
     330              :       END DO
     331              : 
     332         2645 :       CALL timestop(handle2)
     333              : 
     334         2645 :    END SUBROUTINE force_field_unique_bend
     335              : 
     336              : ! **************************************************************************************************
     337              : !> \brief Determine the number of unique Urey-Bradley kind and allocate ub_kind_set
     338              : !> \param particle_set ...
     339              : !> \param molecule_kind_set ...
     340              : !> \param molecule_set ...
     341              : !> \param iw ...
     342              : ! **************************************************************************************************
     343         2645 :    SUBROUTINE force_field_unique_ub(particle_set, molecule_kind_set, molecule_set, iw)
     344              : 
     345              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     346              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     347              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     348              :       INTEGER, INTENT(IN)                                :: iw
     349              : 
     350              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_unique_ub'
     351              : 
     352              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_a2, name_atm_b, &
     353              :                                                             name_atm_b2, name_atm_c, name_atm_c2
     354              :       INTEGER                                            :: atm_a, atm_b, atm_c, counter, first, &
     355              :                                                             handle2, i, j, k, last, natom, nub
     356         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
     357         2645 :       INTEGER, POINTER                                   :: map_ub_kind(:)
     358              :       LOGICAL                                            :: found
     359              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     360              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     361              :       TYPE(molecule_type), POINTER                       :: molecule
     362         2645 :       TYPE(ub_kind_type), DIMENSION(:), POINTER          :: ub_kind_set
     363         2645 :       TYPE(ub_type), DIMENSION(:), POINTER               :: ub_list
     364              : 
     365         2645 :       CALL timeset(routineN, handle2)
     366              : 
     367         2645 :       IF (iw > 0) THEN
     368              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
     369          239 :             "FORCEFIELD| Checking for unique Urey-Bradley terms"
     370              :       END IF
     371              : 
     372        75469 :       DO i = 1, SIZE(molecule_kind_set)
     373        72824 :          molecule_kind => molecule_kind_set(i)
     374              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
     375              :                                 molecule_list=molecule_list, &
     376              :                                 natom=natom, &
     377        72824 :                                 nub=nub, ub_list=ub_list)
     378        72824 :          molecule => molecule_set(molecule_list(1))
     379        72824 :          CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
     380       148293 :          IF (nub > 0) THEN
     381        87261 :             ALLOCATE (map_ub_kind(nub))
     382        29087 :             counter = 0
     383       169559 :             DO j = 1, nub
     384       140472 :                atm_a = ub_list(j)%a
     385       140472 :                atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     386              :                CALL get_atomic_kind(atomic_kind=atomic_kind, &
     387       140472 :                                     name=name_atm_a)
     388       140472 :                atm_b = ub_list(j)%b
     389       140472 :                atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     390              :                CALL get_atomic_kind(atomic_kind=atomic_kind, &
     391       140472 :                                     name=name_atm_b)
     392       140472 :                atm_c = ub_list(j)%c
     393       140472 :                atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
     394              :                CALL get_atomic_kind(atomic_kind=atomic_kind, &
     395       140472 :                                     name=name_atm_c)
     396       140472 :                found = .FALSE.
     397      2499735 :                DO k = 1, j - 1
     398      2404937 :                   atm_a = ub_list(k)%a
     399      2404937 :                   atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     400              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     401      2404937 :                                        name=name_atm_a2)
     402      2404937 :                   atm_b = ub_list(k)%b
     403      2404937 :                   atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     404              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     405      2404937 :                                        name=name_atm_b2)
     406      2404937 :                   atm_c = ub_list(k)%c
     407      2404937 :                   atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
     408              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     409      2404937 :                                        name=name_atm_c2)
     410              :                   IF ((((name_atm_a) == (name_atm_a2)) .AND. &
     411              :                        ((name_atm_b) == (name_atm_b2)) .AND. &
     412      2404937 :                        ((name_atm_c) == (name_atm_c2))) .OR. &
     413              :                       (((name_atm_a) == (name_atm_c2)) .AND. &
     414              :                        ((name_atm_b) == (name_atm_b2)) .AND. &
     415        94798 :                        ((name_atm_c) == (name_atm_a2)))) THEN
     416        45674 :                      found = .TRUE.
     417        45674 :                      map_ub_kind(j) = map_ub_kind(k)
     418              :                      EXIT
     419              :                   END IF
     420              :                END DO
     421        29087 :                IF (.NOT. found) THEN
     422        94798 :                   counter = counter + 1
     423        94798 :                   map_ub_kind(j) = counter
     424              :                END IF
     425              :             END DO
     426        29087 :             CALL allocate_ub_kind_set(ub_kind_set, counter)
     427       169559 :             DO j = 1, nub
     428       169559 :                ub_list(j)%ub_kind => ub_kind_set(map_ub_kind(j))
     429              :             END DO
     430              :             CALL set_molecule_kind(molecule_kind=molecule_kind, &
     431        29087 :                                    ub_kind_set=ub_kind_set, ub_list=ub_list)
     432        29087 :             DEALLOCATE (map_ub_kind)
     433              :          END IF
     434              :       END DO
     435         2645 :       CALL timestop(handle2)
     436              : 
     437         2645 :    END SUBROUTINE force_field_unique_ub
     438              : 
     439              : ! **************************************************************************************************
     440              : !> \brief Determine the number of unique torsion kind and allocate torsion_kind_set
     441              : !> \param particle_set ...
     442              : !> \param molecule_kind_set ...
     443              : !> \param molecule_set ...
     444              : !> \param ff_type ...
     445              : !> \param iw ...
     446              : ! **************************************************************************************************
     447         2645 :    SUBROUTINE force_field_unique_tors(particle_set, molecule_kind_set, molecule_set, ff_type, iw)
     448              : 
     449              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     450              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     451              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     452              :       TYPE(force_field_type), INTENT(INOUT)              :: ff_type
     453              :       INTEGER, INTENT(IN)                                :: iw
     454              : 
     455              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_unique_tors'
     456              : 
     457              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_a2, name_atm_b, &
     458              :                                                             name_atm_b2, name_atm_c, name_atm_c2, &
     459              :                                                             name_atm_d, name_atm_d2
     460              :       INTEGER                                            :: atm_a, atm_b, atm_c, atm_d, counter, &
     461              :                                                             first, handle2, i, j, k, last, natom, &
     462              :                                                             ntorsion
     463         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
     464         2645 :       INTEGER, POINTER                                   :: map_torsion_kind(:)
     465              :       LOGICAL                                            :: chk_reverse, found
     466              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     467              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     468              :       TYPE(molecule_type), POINTER                       :: molecule
     469         2645 :       TYPE(torsion_kind_type), DIMENSION(:), POINTER     :: torsion_kind_set
     470         2645 :       TYPE(torsion_type), DIMENSION(:), POINTER          :: torsion_list
     471              : 
     472         2645 :       CALL timeset(routineN, handle2)
     473              : 
     474         2645 :       IF (iw > 0) THEN
     475              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
     476          239 :             "FORCEFIELD| Checking for unique torsion terms"
     477              :       END IF
     478              : 
     479              :       ! Now decide whether we need to check D-C-B-A type combination in addtion to usual A-B-C-D
     480              :       ! We don't need it for Amber FF
     481         2645 :       chk_reverse = (ff_type%ff_type /= do_ff_amber)
     482              : 
     483        75469 :       DO i = 1, SIZE(molecule_kind_set)
     484        72824 :          molecule_kind => molecule_kind_set(i)
     485              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
     486              :                                 molecule_list=molecule_list, &
     487              :                                 natom=natom, &
     488        72824 :                                 ntorsion=ntorsion, torsion_list=torsion_list)
     489        72824 :          molecule => molecule_set(molecule_list(1))
     490        72824 :          CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
     491       148293 :          IF (ntorsion > 0) THEN
     492        16602 :             ALLOCATE (map_torsion_kind(ntorsion))
     493         5534 :             counter = 0
     494         5534 :             IF ((ff_type%ff_type == do_ff_g96) .OR. (ff_type%ff_type == do_ff_g87)) THEN
     495          320 :                DO j = 1, ntorsion
     496          320 :                   map_torsion_kind(j) = j
     497              :                END DO
     498            8 :                counter = ntorsion
     499              :             ELSE
     500       162887 :                DO j = 1, ntorsion
     501       157361 :                   atm_a = torsion_list(j)%a
     502       157361 :                   atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     503              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     504       157361 :                                        name=name_atm_a)
     505       157361 :                   atm_b = torsion_list(j)%b
     506       157361 :                   atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     507              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     508       157361 :                                        name=name_atm_b)
     509       157361 :                   atm_c = torsion_list(j)%c
     510       157361 :                   atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
     511              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     512       157361 :                                        name=name_atm_c)
     513       157361 :                   atm_d = torsion_list(j)%d
     514       157361 :                   atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
     515              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     516       157361 :                                        name=name_atm_d)
     517       157361 :                   found = .FALSE.
     518      2932946 :                   DO k = 1, j - 1
     519      2840585 :                      atm_a = torsion_list(k)%a
     520      2840585 :                      atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     521              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     522      2840585 :                                           name=name_atm_a2)
     523      2840585 :                      atm_b = torsion_list(k)%b
     524      2840585 :                      atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     525              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     526      2840585 :                                           name=name_atm_b2)
     527      2840585 :                      atm_c = torsion_list(k)%c
     528      2840585 :                      atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
     529              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     530      2840585 :                                           name=name_atm_c2)
     531      2840585 :                      atm_d = torsion_list(k)%d
     532      2840585 :                      atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
     533              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     534      2840585 :                                           name=name_atm_d2)
     535              :                      IF ((((name_atm_a) == (name_atm_a2)) .AND. &
     536              :                           ((name_atm_b) == (name_atm_b2)) .AND. &
     537              :                           ((name_atm_c) == (name_atm_c2)) .AND. &
     538      2840585 :                           ((name_atm_d) == (name_atm_d2))) .OR. &
     539              :                          (chk_reverse .AND. &
     540              :                           ((name_atm_a) == (name_atm_d2)) .AND. &
     541              :                           ((name_atm_b) == (name_atm_c2)) .AND. &
     542              :                           ((name_atm_c) == (name_atm_b2)) .AND. &
     543        92361 :                           ((name_atm_d) == (name_atm_a2)))) THEN
     544        65000 :                         found = .TRUE.
     545        65000 :                         map_torsion_kind(j) = map_torsion_kind(k)
     546              :                         EXIT
     547              :                      END IF
     548              :                   END DO
     549         5526 :                   IF (.NOT. found) THEN
     550        92361 :                      counter = counter + 1
     551        92361 :                      map_torsion_kind(j) = counter
     552              :                   END IF
     553              :                END DO
     554              :             END IF
     555         5534 :             NULLIFY (torsion_kind_set)
     556         5534 :             CALL allocate_torsion_kind_set(torsion_kind_set, counter)
     557       163207 :             DO j = 1, ntorsion
     558       163207 :                torsion_list(j)%torsion_kind => torsion_kind_set(map_torsion_kind(j))
     559              :             END DO
     560              :             CALL set_molecule_kind(molecule_kind=molecule_kind, &
     561         5534 :                                    torsion_kind_set=torsion_kind_set, torsion_list=torsion_list)
     562         5534 :             DEALLOCATE (map_torsion_kind)
     563              :          END IF
     564              :       END DO
     565              : 
     566         2645 :       CALL timestop(handle2)
     567              : 
     568         2645 :    END SUBROUTINE force_field_unique_tors
     569              : 
     570              : ! **************************************************************************************************
     571              : !> \brief Determine the number of unique impr kind and allocate impr_kind_set
     572              : !> \param particle_set ...
     573              : !> \param molecule_kind_set ...
     574              : !> \param molecule_set ...
     575              : !> \param ff_type ...
     576              : !> \param iw ...
     577              : ! **************************************************************************************************
     578         2645 :    SUBROUTINE force_field_unique_impr(particle_set, molecule_kind_set, molecule_set, ff_type, iw)
     579              : 
     580              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     581              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     582              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     583              :       TYPE(force_field_type), INTENT(INOUT)              :: ff_type
     584              :       INTEGER, INTENT(IN)                                :: iw
     585              : 
     586              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_unique_impr'
     587              : 
     588              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_a2, name_atm_b, &
     589              :                                                             name_atm_b2, name_atm_c, name_atm_c2, &
     590              :                                                             name_atm_d, name_atm_d2
     591              :       INTEGER                                            :: atm_a, atm_b, atm_c, atm_d, counter, &
     592              :                                                             first, handle2, i, j, k, last, natom, &
     593              :                                                             nimpr
     594         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
     595         2645 :       INTEGER, POINTER                                   :: map_impr_kind(:)
     596              :       LOGICAL                                            :: found
     597              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     598         2645 :       TYPE(impr_kind_type), DIMENSION(:), POINTER        :: impr_kind_set
     599         2645 :       TYPE(impr_type), DIMENSION(:), POINTER             :: impr_list
     600              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     601              :       TYPE(molecule_type), POINTER                       :: molecule
     602              : 
     603         2645 :       CALL timeset(routineN, handle2)
     604              : 
     605         2645 :       IF (iw > 0) THEN
     606              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
     607          239 :             "FORCEFIELD| Checking for unique improper terms"
     608              :       END IF
     609              : 
     610        75469 :       DO i = 1, SIZE(molecule_kind_set)
     611        72824 :          molecule_kind => molecule_kind_set(i)
     612              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
     613              :                                 molecule_list=molecule_list, &
     614              :                                 natom=natom, &
     615        72824 :                                 nimpr=nimpr, impr_list=impr_list)
     616        72824 :          molecule => molecule_set(molecule_list(1))
     617              : 
     618        72824 :          CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
     619              : 
     620       148293 :          IF (nimpr > 0) THEN
     621         5016 :             ALLOCATE (map_impr_kind(nimpr))
     622         1672 :             counter = 0
     623         1672 :             IF ((ff_type%ff_type == do_ff_g96) .OR. (ff_type%ff_type == do_ff_g87)) THEN
     624            0 :                DO j = 1, nimpr
     625            0 :                   map_impr_kind(j) = j
     626              :                END DO
     627            0 :                counter = nimpr
     628              :             ELSE
     629         6984 :                DO j = 1, nimpr
     630         5312 :                   atm_a = impr_list(j)%a
     631         5312 :                   atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     632              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     633         5312 :                                        name=name_atm_a)
     634         5312 :                   atm_b = impr_list(j)%b
     635         5312 :                   atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     636              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     637         5312 :                                        name=name_atm_b)
     638         5312 :                   atm_c = impr_list(j)%c
     639         5312 :                   atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
     640              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     641         5312 :                                        name=name_atm_c)
     642         5312 :                   atm_d = impr_list(j)%d
     643         5312 :                   atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
     644              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     645         5312 :                                        name=name_atm_d)
     646         5312 :                   found = .FALSE.
     647        18542 :                   DO k = 1, j - 1
     648        13834 :                      atm_a = impr_list(k)%a
     649        13834 :                      atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     650              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     651        13834 :                                           name=name_atm_a2)
     652        13834 :                      atm_b = impr_list(k)%b
     653        13834 :                      atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     654              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     655        13834 :                                           name=name_atm_b2)
     656        13834 :                      atm_c = impr_list(k)%c
     657        13834 :                      atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
     658              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     659        13834 :                                           name=name_atm_c2)
     660        13834 :                      atm_d = impr_list(k)%d
     661        13834 :                      atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
     662              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     663        13834 :                                           name=name_atm_d2)
     664              :                      IF ((((name_atm_a) == (name_atm_a2)) .AND. &
     665              :                           ((name_atm_b) == (name_atm_b2)) .AND. &
     666              :                           ((name_atm_c) == (name_atm_c2)) .AND. &
     667        13834 :                           ((name_atm_d) == (name_atm_d2))) .OR. &
     668              :                          (((name_atm_a) == (name_atm_a2)) .AND. &
     669              :                           ((name_atm_b) == (name_atm_b2)) .AND. &
     670              :                           ((name_atm_c) == (name_atm_d2)) .AND. &
     671         4708 :                           ((name_atm_d) == (name_atm_c2)))) THEN
     672          604 :                         found = .TRUE.
     673          604 :                         map_impr_kind(j) = map_impr_kind(k)
     674              :                         EXIT
     675              :                      END IF
     676              :                   END DO
     677         1672 :                   IF (.NOT. found) THEN
     678         4708 :                      counter = counter + 1
     679         4708 :                      map_impr_kind(j) = counter
     680              :                   END IF
     681              :                END DO
     682              :             END IF
     683         1672 :             NULLIFY (impr_kind_set)
     684         1672 :             CALL allocate_impr_kind_set(impr_kind_set, counter)
     685         6984 :             DO j = 1, nimpr
     686         6984 :                impr_list(j)%impr_kind => impr_kind_set(map_impr_kind(j))
     687              :             END DO
     688              :             CALL set_molecule_kind(molecule_kind=molecule_kind, &
     689         1672 :                                    impr_kind_set=impr_kind_set, impr_list=impr_list)
     690         1672 :             DEALLOCATE (map_impr_kind)
     691              :          END IF
     692              :       END DO
     693         2645 :       CALL timestop(handle2)
     694              : 
     695         2645 :    END SUBROUTINE force_field_unique_impr
     696              : 
     697              : ! **************************************************************************************************
     698              : !> \brief Determine the number of unique opbend kind and allocate opbend_kind_set
     699              : !>        based on the present impropers. With each improper, there also
     700              : !>        corresponds a opbend
     701              : !> \param particle_set ...
     702              : !> \param molecule_kind_set ...
     703              : !> \param molecule_set ...
     704              : !> \param ff_type ...
     705              : !> \param iw ...
     706              : ! **************************************************************************************************
     707         2645 :    SUBROUTINE force_field_unique_opbend(particle_set, molecule_kind_set, molecule_set, ff_type, iw)
     708              : 
     709              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     710              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     711              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     712              :       TYPE(force_field_type), INTENT(INOUT)              :: ff_type
     713              :       INTEGER, INTENT(IN)                                :: iw
     714              : 
     715              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_unique_opbend'
     716              : 
     717              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_a2, name_atm_b, &
     718              :                                                             name_atm_b2, name_atm_c, name_atm_c2, &
     719              :                                                             name_atm_d, name_atm_d2
     720              :       INTEGER                                            :: atm_a, atm_b, atm_c, atm_d, counter, &
     721              :                                                             first, handle2, i, j, k, last, natom, &
     722              :                                                             nopbend
     723         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
     724         2645 :       INTEGER, POINTER                                   :: map_opbend_kind(:)
     725              :       LOGICAL                                            :: found
     726              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     727              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     728              :       TYPE(molecule_type), POINTER                       :: molecule
     729         2645 :       TYPE(opbend_kind_type), DIMENSION(:), POINTER      :: opbend_kind_set
     730         2645 :       TYPE(opbend_type), DIMENSION(:), POINTER           :: opbend_list
     731              : 
     732         2645 :       CALL timeset(routineN, handle2)
     733              : 
     734         2645 :       IF (iw > 0) THEN
     735              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
     736          239 :             "FORCEFIELD| Checking for unique out-of-plane bend terms"
     737              :       END IF
     738              : 
     739        75469 :       DO i = 1, SIZE(molecule_kind_set)
     740        72824 :          molecule_kind => molecule_kind_set(i)
     741              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
     742              :                                 molecule_list=molecule_list, &
     743              :                                 natom=natom, &
     744        72824 :                                 nopbend=nopbend, opbend_list=opbend_list)
     745        72824 :          molecule => molecule_set(molecule_list(1))
     746        72824 :          CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
     747       148293 :          IF (nopbend > 0) THEN
     748         5016 :             ALLOCATE (map_opbend_kind(nopbend))
     749         1672 :             counter = 0
     750         1672 :             IF ((ff_type%ff_type == do_ff_g96) .OR. (ff_type%ff_type == do_ff_g87)) THEN
     751            0 :                DO j = 1, nopbend
     752            0 :                   map_opbend_kind(j) = j
     753              :                END DO
     754            0 :                counter = nopbend
     755              :             ELSE
     756         6984 :                DO j = 1, nopbend
     757         5312 :                   atm_a = opbend_list(j)%a
     758         5312 :                   atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     759              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     760         5312 :                                        name=name_atm_a)
     761         5312 :                   atm_b = opbend_list(j)%b
     762         5312 :                   atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     763              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     764         5312 :                                        name=name_atm_b)
     765         5312 :                   atm_c = opbend_list(j)%c
     766         5312 :                   atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
     767              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     768         5312 :                                        name=name_atm_c)
     769         5312 :                   atm_d = opbend_list(j)%d
     770         5312 :                   atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
     771              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
     772         5312 :                                        name=name_atm_d)
     773         5312 :                   found = .FALSE.
     774        18542 :                   DO k = 1, j - 1
     775        13834 :                      atm_a = opbend_list(k)%a
     776        13834 :                      atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     777              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     778        13834 :                                           name=name_atm_a2)
     779        13834 :                      atm_b = opbend_list(k)%b
     780        13834 :                      atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     781              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     782        13834 :                                           name=name_atm_b2)
     783        13834 :                      atm_c = opbend_list(k)%c
     784        13834 :                      atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
     785              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     786        13834 :                                           name=name_atm_c2)
     787        13834 :                      atm_d = opbend_list(k)%d
     788        13834 :                      atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
     789              :                      CALL get_atomic_kind(atomic_kind=atomic_kind, &
     790        13834 :                                           name=name_atm_d2)
     791              :                      IF ((((name_atm_a) == (name_atm_a2)) .AND. &
     792              :                           ((name_atm_b) == (name_atm_b2)) .AND. &
     793              :                           ((name_atm_c) == (name_atm_c2)) .AND. &
     794        13834 :                           ((name_atm_d) == (name_atm_d2))) .OR. &
     795              :                          (((name_atm_a) == (name_atm_a2)) .AND. &
     796              :                           ((name_atm_b) == (name_atm_c2)) .AND. &
     797              :                           ((name_atm_c) == (name_atm_b2)) .AND. &
     798         4708 :                           ((name_atm_d) == (name_atm_d2)))) THEN
     799          604 :                         found = .TRUE.
     800          604 :                         map_opbend_kind(j) = map_opbend_kind(k)
     801              :                         EXIT
     802              :                      END IF
     803              :                   END DO
     804         1672 :                   IF (.NOT. found) THEN
     805         4708 :                      counter = counter + 1
     806         4708 :                      map_opbend_kind(j) = counter
     807              :                   END IF
     808              :                END DO
     809              :             END IF
     810         1672 :             NULLIFY (opbend_kind_set)
     811         1672 :             CALL allocate_opbend_kind_set(opbend_kind_set, counter)
     812         6984 :             DO j = 1, nopbend
     813         6984 :                opbend_list(j)%opbend_kind => opbend_kind_set(map_opbend_kind(j))
     814              :             END DO
     815              :             CALL set_molecule_kind(molecule_kind=molecule_kind, &
     816         1672 :                                    opbend_kind_set=opbend_kind_set, opbend_list=opbend_list)
     817         1672 :             DEALLOCATE (map_opbend_kind)
     818              :          END IF
     819              :       END DO
     820         2645 :       CALL timestop(handle2)
     821              : 
     822         2645 :    END SUBROUTINE force_field_unique_opbend
     823              : 
     824              : ! **************************************************************************************************
     825              : !> \brief Pack in bonds information needed for the force_field
     826              : !> \param particle_set ...
     827              : !> \param molecule_kind_set ...
     828              : !> \param molecule_set ...
     829              : !> \param fatal ...
     830              : !> \param Ainfo ...
     831              : !> \param chm_info ...
     832              : !> \param inp_info ...
     833              : !> \param gro_info ...
     834              : !> \param amb_info ...
     835              : !> \param iw ...
     836              : ! **************************************************************************************************
     837         2645 :    SUBROUTINE force_field_pack_bond(particle_set, molecule_kind_set, molecule_set, fatal, Ainfo, &
     838              :                                     chm_info, inp_info, gro_info, amb_info, iw)
     839              : 
     840              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     841              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
     842              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     843              :       LOGICAL                                            :: fatal
     844              :       CHARACTER(LEN=default_string_length), &
     845              :          DIMENSION(:), POINTER                           :: Ainfo
     846              :       TYPE(charmm_info_type), POINTER                    :: chm_info
     847              :       TYPE(input_info_type), POINTER                     :: inp_info
     848              :       TYPE(gromos_info_type), POINTER                    :: gro_info
     849              :       TYPE(amber_info_type), POINTER                     :: amb_info
     850              :       INTEGER, INTENT(IN)                                :: iw
     851              : 
     852              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_bond'
     853              : 
     854              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_b
     855              :       INTEGER                                            :: atm_a, atm_b, first, handle2, i, itype, &
     856              :                                                             j, k, last, natom, nbond
     857         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
     858              :       LOGICAL                                            :: found, only_qm
     859              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     860         2645 :       TYPE(bond_type), DIMENSION(:), POINTER             :: bond_list
     861              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
     862              :       TYPE(molecule_type), POINTER                       :: molecule
     863              : 
     864         2645 :       CALL timeset(routineN, handle2)
     865              : 
     866         2645 :       IF (iw > 0) THEN
     867              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
     868          239 :             "FORCEFIELD| Checking for bond terms"
     869              :       END IF
     870              : 
     871        75469 :       DO i = 1, SIZE(molecule_kind_set)
     872        72824 :          molecule_kind => molecule_kind_set(i)
     873              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
     874              :                                 molecule_list=molecule_list, &
     875              :                                 natom=natom, &
     876        72824 :                                 nbond=nbond, bond_list=bond_list)
     877        72824 :          molecule => molecule_set(molecule_list(1))
     878        72824 :          CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
     879       187767 :          DO j = 1, nbond
     880       114943 :             atm_a = bond_list(j)%a
     881       114943 :             atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
     882              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
     883       114943 :                                  name=name_atm_a)
     884       114943 :             atm_b = bond_list(j)%b
     885       114943 :             atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
     886              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
     887       114943 :                                  name=name_atm_b)
     888       114943 :             found = .FALSE.
     889       114943 :             only_qm = qmmm_ff_precond_only_qm(id1=name_atm_a, id2=name_atm_b)
     890       114943 :             CALL uppercase(name_atm_a)
     891       114943 :             CALL uppercase(name_atm_b)
     892              : 
     893              :             ! loop over params from GROMOS
     894       114943 :             IF (ASSOCIATED(gro_info%bond_k)) THEN
     895          128 :                k = SIZE(gro_info%bond_k)
     896          128 :                itype = bond_list(j)%itype
     897          128 :                IF (itype <= k) THEN
     898          104 :                   bond_list(j)%bond_kind%k(1) = gro_info%bond_k(itype)
     899          104 :                   bond_list(j)%bond_kind%r0 = gro_info%bond_r0(itype)
     900              :                ELSE
     901           24 :                   itype = itype - k
     902           24 :                   bond_list(j)%bond_kind%k(1) = gro_info%solvent_k(itype)
     903           24 :                   bond_list(j)%bond_kind%r0 = gro_info%solvent_r0(itype)
     904              :                END IF
     905          128 :                bond_list(j)%bond_kind%id_type = gro_info%ff_gromos_type
     906          128 :                bond_list(j)%id_type = gro_info%ff_gromos_type
     907          128 :                found = .TRUE.
     908              :             END IF
     909              : 
     910              :             ! loop over params from CHARMM
     911       114943 :             IF (ASSOCIATED(chm_info%bond_a)) THEN
     912      1449348 :                DO k = 1, SIZE(chm_info%bond_a)
     913              :                   IF ((((chm_info%bond_a(k)) == (name_atm_a)) .AND. &
     914      1449324 :                        ((chm_info%bond_b(k)) == (name_atm_b))) .OR. &
     915              :                       (((chm_info%bond_a(k)) == (name_atm_b)) .AND. &
     916           24 :                        ((chm_info%bond_b(k)) == (name_atm_a)))) THEN
     917        41447 :                      bond_list(j)%bond_kind%id_type = do_ff_charmm
     918        41447 :                      bond_list(j)%bond_kind%k(1) = chm_info%bond_k(k)
     919        41447 :                      bond_list(j)%bond_kind%r0 = chm_info%bond_r0(k)
     920        41447 :                      CALL issue_duplications(found, "Bond", name_atm_a, name_atm_b)
     921        41447 :                      found = .TRUE.
     922        41447 :                      EXIT
     923              :                   END IF
     924              :                END DO
     925              :             END IF
     926              : 
     927              :             ! loop over params from AMBER
     928       114943 :             IF (ASSOCIATED(amb_info%bond_a)) THEN
     929      5716862 :                DO k = 1, SIZE(amb_info%bond_a)
     930              :                   IF ((((amb_info%bond_a(k)) == (name_atm_a)) .AND. &
     931      5716862 :                        ((amb_info%bond_b(k)) == (name_atm_b))) .OR. &
     932              :                       (((amb_info%bond_a(k)) == (name_atm_b)) .AND. &
     933            0 :                        ((amb_info%bond_b(k)) == (name_atm_a)))) THEN
     934        64808 :                      bond_list(j)%bond_kind%id_type = do_ff_amber
     935        64808 :                      bond_list(j)%bond_kind%k(1) = amb_info%bond_k(k)
     936        64808 :                      bond_list(j)%bond_kind%r0 = amb_info%bond_r0(k)
     937        64808 :                      CALL issue_duplications(found, "Bond", name_atm_a, name_atm_b)
     938        64808 :                      found = .TRUE.
     939        64808 :                      EXIT
     940              :                   END IF
     941              :                END DO
     942              :             END IF
     943              : 
     944              :             ! always have the input param last to overwrite all the other ones
     945       114943 :             IF (ASSOCIATED(inp_info%bond_a)) THEN
     946        10440 :                DO k = 1, SIZE(inp_info%bond_a)
     947              :                   IF ((((inp_info%bond_a(k)) == (name_atm_a)) .AND. &
     948        10394 :                        ((inp_info%bond_b(k)) == (name_atm_b))) .OR. &
     949              :                       (((inp_info%bond_a(k)) == (name_atm_b)) .AND. &
     950           46 :                        ((inp_info%bond_b(k)) == (name_atm_a)))) THEN
     951         8568 :                      bond_list(j)%bond_kind%id_type = inp_info%bond_kind(k)
     952        59976 :                      bond_list(j)%bond_kind%k(:) = inp_info%bond_k(:, k)
     953         8568 :                      bond_list(j)%bond_kind%r0 = inp_info%bond_r0(k)
     954         8568 :                      bond_list(j)%bond_kind%cs = inp_info%bond_cs(k)
     955         8568 :                      CALL issue_duplications(found, "Bond", name_atm_a, name_atm_b)
     956         8568 :                      found = .TRUE.
     957         8568 :                      EXIT
     958              :                   END IF
     959              :                END DO
     960              :             END IF
     961              : 
     962       114943 :             IF (.NOT. found) CALL store_FF_missing_par(atm1=TRIM(name_atm_a), &
     963              :                                                        atm2=TRIM(name_atm_b), &
     964              :                                                        fatal=fatal, &
     965              :                                                        type_name="Bond", &
     966           16 :                                                        array=Ainfo)
     967              :             ! QM/MM modifications
     968       187767 :             IF (only_qm) THEN
     969         2082 :                bond_list(j)%id_type = do_ff_undef
     970         2082 :                bond_list(j)%bond_kind%id_type = do_ff_undef
     971              :             END IF
     972              :          END DO
     973              : 
     974              :          CALL set_molecule_kind(molecule_kind=molecule_kind, &
     975       148293 :                                 bond_list=bond_list)
     976              : 
     977              :       END DO
     978              : 
     979         2645 :       CALL timestop(handle2)
     980              : 
     981         2645 :    END SUBROUTINE force_field_pack_bond
     982              : 
     983              : ! **************************************************************************************************
     984              : !> \brief Pack in bends information needed for the force_field
     985              : !> \param particle_set ...
     986              : !> \param molecule_kind_set ...
     987              : !> \param molecule_set ...
     988              : !> \param fatal ...
     989              : !> \param Ainfo ...
     990              : !> \param chm_info ...
     991              : !> \param inp_info ...
     992              : !> \param gro_info ...
     993              : !> \param amb_info ...
     994              : !> \param iw ...
     995              : ! **************************************************************************************************
     996         2645 :    SUBROUTINE force_field_pack_bend(particle_set, molecule_kind_set, molecule_set, fatal, Ainfo, &
     997              :                                     chm_info, inp_info, gro_info, amb_info, iw)
     998              : 
     999              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1000              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
    1001              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
    1002              :       LOGICAL                                            :: fatal
    1003              :       CHARACTER(LEN=default_string_length), &
    1004              :          DIMENSION(:), POINTER                           :: Ainfo
    1005              :       TYPE(charmm_info_type), POINTER                    :: chm_info
    1006              :       TYPE(input_info_type), POINTER                     :: inp_info
    1007              :       TYPE(gromos_info_type), POINTER                    :: gro_info
    1008              :       TYPE(amber_info_type), POINTER                     :: amb_info
    1009              :       INTEGER, INTENT(IN)                                :: iw
    1010              : 
    1011              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_bend'
    1012              : 
    1013              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_b, name_atm_c
    1014              :       INTEGER                                            :: atm_a, atm_b, atm_c, first, handle2, i, &
    1015              :                                                             itype, j, k, l, last, natom, nbend
    1016         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
    1017              :       LOGICAL                                            :: found, only_qm
    1018              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    1019         2645 :       TYPE(bend_type), DIMENSION(:), POINTER             :: bend_list
    1020              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
    1021              :       TYPE(molecule_type), POINTER                       :: molecule
    1022              : 
    1023         2645 :       CALL timeset(routineN, handle2)
    1024              : 
    1025         2645 :       IF (iw > 0) THEN
    1026              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
    1027          239 :             "FORCEFIELD| Checking for bend terms"
    1028              :       END IF
    1029              : 
    1030        75469 :       DO i = 1, SIZE(molecule_kind_set)
    1031        72824 :          molecule_kind => molecule_kind_set(i)
    1032              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
    1033              :                                 molecule_list=molecule_list, &
    1034              :                                 natom=natom, &
    1035        72824 :                                 nbend=nbend, bend_list=bend_list)
    1036        72824 :          molecule => molecule_set(molecule_list(1))
    1037        72824 :          CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
    1038       213454 :          DO j = 1, nbend
    1039       140630 :             atm_a = bend_list(j)%a
    1040       140630 :             atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
    1041              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1042       140630 :                                  name=name_atm_a)
    1043       140630 :             atm_b = bend_list(j)%b
    1044       140630 :             atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
    1045              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1046       140630 :                                  name=name_atm_b)
    1047       140630 :             atm_c = bend_list(j)%c
    1048       140630 :             atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
    1049              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1050       140630 :                                  name=name_atm_c)
    1051       140630 :             found = .FALSE.
    1052       140630 :             only_qm = qmmm_ff_precond_only_qm(id1=name_atm_a, id2=name_atm_b, id3=name_atm_c)
    1053       140630 :             CALL uppercase(name_atm_a)
    1054       140630 :             CALL uppercase(name_atm_b)
    1055       140630 :             CALL uppercase(name_atm_c)
    1056              : 
    1057              :             ! loop over params from GROMOS
    1058       140630 :             IF (ASSOCIATED(gro_info%bend_k)) THEN
    1059          156 :                k = SIZE(gro_info%bend_k)
    1060          156 :                itype = bend_list(j)%itype
    1061          156 :                IF (itype > 0) THEN
    1062          156 :                   bend_list(j)%bend_kind%k = gro_info%bend_k(itype)
    1063          156 :                   bend_list(j)%bend_kind%theta0 = gro_info%bend_theta0(itype)
    1064              :                ELSE
    1065            0 :                   bend_list(j)%bend_kind%k = gro_info%bend_k(itype/k)
    1066            0 :                   bend_list(j)%bend_kind%theta0 = gro_info%bend_theta0(itype/k)
    1067              :                END IF
    1068          156 :                bend_list(j)%bend_kind%id_type = gro_info%ff_gromos_type
    1069          156 :                bend_list(j)%id_type = gro_info%ff_gromos_type
    1070          156 :                found = .TRUE.
    1071              :             END IF
    1072              : 
    1073              :             ! loop over params from CHARMM
    1074       140630 :             IF (ASSOCIATED(chm_info%bend_a)) THEN
    1075      6045171 :                DO k = 1, SIZE(chm_info%bend_a)
    1076              :                   IF ((((chm_info%bend_a(k)) == (name_atm_a)) .AND. &
    1077              :                        ((chm_info%bend_b(k)) == (name_atm_b)) .AND. &
    1078      6045097 :                        ((chm_info%bend_c(k)) == (name_atm_c))) .OR. &
    1079              :                       (((chm_info%bend_a(k)) == (name_atm_c)) .AND. &
    1080              :                        ((chm_info%bend_b(k)) == (name_atm_b)) .AND. &
    1081           74 :                        ((chm_info%bend_c(k)) == (name_atm_a)))) THEN
    1082        67523 :                      bend_list(j)%bend_kind%id_type = do_ff_charmm
    1083        67523 :                      bend_list(j)%bend_kind%k = chm_info%bend_k(k)
    1084        67523 :                      bend_list(j)%bend_kind%theta0 = chm_info%bend_theta0(k)
    1085              :                      CALL issue_duplications(found, "Bend", name_atm_a, name_atm_b, &
    1086        67523 :                                              name_atm_c)
    1087        67523 :                      found = .TRUE.
    1088        67523 :                      EXIT
    1089              :                   END IF
    1090              :                END DO
    1091              :             END IF
    1092              : 
    1093              :             ! loop over params from AMBER
    1094       140630 :             IF (ASSOCIATED(amb_info%bend_a)) THEN
    1095     10981138 :                DO k = 1, SIZE(amb_info%bend_a)
    1096              :                   IF ((((amb_info%bend_a(k)) == (name_atm_a)) .AND. &
    1097              :                        ((amb_info%bend_b(k)) == (name_atm_b)) .AND. &
    1098     10981138 :                        ((amb_info%bend_c(k)) == (name_atm_c))) .OR. &
    1099              :                       (((amb_info%bend_a(k)) == (name_atm_c)) .AND. &
    1100              :                        ((amb_info%bend_b(k)) == (name_atm_b)) .AND. &
    1101            0 :                        ((amb_info%bend_c(k)) == (name_atm_a)))) THEN
    1102        59540 :                      bend_list(j)%bend_kind%id_type = do_ff_amber
    1103        59540 :                      bend_list(j)%bend_kind%k = amb_info%bend_k(k)
    1104        59540 :                      bend_list(j)%bend_kind%theta0 = amb_info%bend_theta0(k)
    1105              :                      CALL issue_duplications(found, "Bend", name_atm_a, name_atm_b, &
    1106        59540 :                                              name_atm_c)
    1107        59540 :                      found = .TRUE.
    1108        59540 :                      EXIT
    1109              :                   END IF
    1110              :                END DO
    1111              :             END IF
    1112              : 
    1113              :             ! always have the input param last to overwrite all the other ones
    1114       140630 :             IF (ASSOCIATED(inp_info%bend_a)) THEN
    1115        28429 :                DO k = 1, SIZE(inp_info%bend_a)
    1116              :                   IF ((((inp_info%bend_a(k)) == (name_atm_a)) .AND. &
    1117              :                        ((inp_info%bend_b(k)) == (name_atm_b)) .AND. &
    1118        28413 :                        ((inp_info%bend_c(k)) == (name_atm_c))) .OR. &
    1119              :                       (((inp_info%bend_a(k)) == (name_atm_c)) .AND. &
    1120              :                        ((inp_info%bend_b(k)) == (name_atm_b)) .AND. &
    1121           16 :                        ((inp_info%bend_c(k)) == (name_atm_a)))) THEN
    1122        13411 :                      bend_list(j)%bend_kind%id_type = inp_info%bend_kind(k)
    1123        13411 :                      bend_list(j)%bend_kind%k = inp_info%bend_k(k)
    1124        13411 :                      bend_list(j)%bend_kind%theta0 = inp_info%bend_theta0(k)
    1125        13411 :                      bend_list(j)%bend_kind%cb = inp_info%bend_cb(k)
    1126        13411 :                      bend_list(j)%bend_kind%r012 = inp_info%bend_r012(k)
    1127        13411 :                      bend_list(j)%bend_kind%r032 = inp_info%bend_r032(k)
    1128        13411 :                      bend_list(j)%bend_kind%kbs12 = inp_info%bend_kbs12(k)
    1129        13411 :                      bend_list(j)%bend_kind%kbs32 = inp_info%bend_kbs32(k)
    1130        13411 :                      bend_list(j)%bend_kind%kss = inp_info%bend_kss(k)
    1131        13411 :                      bend_list(j)%bend_kind%legendre%order = inp_info%bend_legendre(k)%order
    1132        13411 :                      IF (bend_list(j)%bend_kind%legendre%order /= 0) THEN
    1133        13411 :                         IF (ASSOCIATED(bend_list(j)%bend_kind%legendre%coeffs)) THEN
    1134        11086 :                            DEALLOCATE (bend_list(j)%bend_kind%legendre%coeffs)
    1135              :                         END IF
    1136        40233 :                         ALLOCATE (bend_list(j)%bend_kind%legendre%coeffs(bend_list(j)%bend_kind%legendre%order))
    1137        27062 :                         DO l = 1, bend_list(j)%bend_kind%legendre%order
    1138        27062 :                            bend_list(j)%bend_kind%legendre%coeffs(l) = inp_info%bend_legendre(k)%coeffs(l)
    1139              :                         END DO
    1140              :                      END IF
    1141              :                      CALL issue_duplications(found, "Bend", name_atm_a, name_atm_b, &
    1142        13411 :                                              name_atm_c)
    1143        13411 :                      found = .TRUE.
    1144        13411 :                      EXIT
    1145              :                   END IF
    1146              :                END DO
    1147              :             END IF
    1148              : 
    1149       140630 :             IF (.NOT. found) CALL store_FF_missing_par(atm1=TRIM(name_atm_a), &
    1150              :                                                        atm2=TRIM(name_atm_b), &
    1151              :                                                        atm3=TRIM(name_atm_c), &
    1152              :                                                        fatal=fatal, &
    1153              :                                                        type_name="Angle", &
    1154            8 :                                                        array=Ainfo)
    1155              :             ! QM/MM modifications
    1156       213454 :             IF (only_qm) THEN
    1157         1918 :                bend_list(j)%id_type = do_ff_undef
    1158         1918 :                bend_list(j)%bend_kind%id_type = do_ff_undef
    1159              :             END IF
    1160              :          END DO
    1161              :          CALL set_molecule_kind(molecule_kind=molecule_kind, &
    1162       148293 :                                 bend_list=bend_list)
    1163              :       END DO
    1164         2645 :       CALL timestop(handle2)
    1165              : 
    1166         2645 :    END SUBROUTINE force_field_pack_bend
    1167              : 
    1168              : ! **************************************************************************************************
    1169              : !> \brief Pack in Urey-Bradley information needed for the force_field
    1170              : !> \param particle_set ...
    1171              : !> \param molecule_kind_set ...
    1172              : !> \param molecule_set ...
    1173              : !> \param Ainfo ...
    1174              : !> \param chm_info ...
    1175              : !> \param inp_info ...
    1176              : !> \param iw ...
    1177              : ! **************************************************************************************************
    1178         2645 :    SUBROUTINE force_field_pack_ub(particle_set, molecule_kind_set, molecule_set, &
    1179              :                                   Ainfo, chm_info, inp_info, iw)
    1180              : 
    1181              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1182              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
    1183              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
    1184              :       CHARACTER(LEN=default_string_length), &
    1185              :          DIMENSION(:), POINTER                           :: Ainfo
    1186              :       TYPE(charmm_info_type), POINTER                    :: chm_info
    1187              :       TYPE(input_info_type), POINTER                     :: inp_info
    1188              :       INTEGER                                            :: iw
    1189              : 
    1190              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_ub'
    1191              : 
    1192              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_b, name_atm_c
    1193              :       INTEGER                                            :: atm_a, atm_b, atm_c, first, handle2, i, &
    1194              :                                                             j, k, last, natom, nub
    1195         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
    1196              :       LOGICAL                                            :: found, only_qm
    1197              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    1198              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
    1199              :       TYPE(molecule_type), POINTER                       :: molecule
    1200         2645 :       TYPE(ub_type), DIMENSION(:), POINTER               :: ub_list
    1201              : 
    1202         2645 :       CALL timeset(routineN, handle2)
    1203              : 
    1204         2645 :       IF (iw > 0) THEN
    1205              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
    1206          239 :             "FORCEFIELD| Checking for Urey-Bradley (UB) terms"
    1207              :       END IF
    1208              : 
    1209        75469 :       DO i = 1, SIZE(molecule_kind_set)
    1210        72824 :          molecule_kind => molecule_kind_set(i)
    1211              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
    1212              :                                 molecule_list=molecule_list, &
    1213              :                                 natom=natom, &
    1214        72824 :                                 nub=nub, ub_list=ub_list)
    1215        72824 :          molecule => molecule_set(molecule_list(1))
    1216        72824 :          CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
    1217       213296 :          DO j = 1, nub
    1218       140472 :             atm_a = ub_list(j)%a
    1219       140472 :             atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
    1220              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1221       140472 :                                  name=name_atm_a)
    1222       140472 :             atm_b = ub_list(j)%b
    1223       140472 :             atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
    1224              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1225       140472 :                                  name=name_atm_b)
    1226       140472 :             atm_c = ub_list(j)%c
    1227       140472 :             atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
    1228              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1229       140472 :                                  name=name_atm_c)
    1230       140472 :             found = .FALSE.
    1231       140472 :             only_qm = qmmm_ff_precond_only_qm(id1=name_atm_a, id2=name_atm_b, id3=name_atm_c)
    1232       140472 :             CALL uppercase(name_atm_a)
    1233       140472 :             CALL uppercase(name_atm_b)
    1234       140472 :             CALL uppercase(name_atm_c)
    1235              : 
    1236              :             ! Loop over params from GROMOS
    1237              :             ! ikuo - None that I know...
    1238              : 
    1239              :             ! Loop over params from CHARMM
    1240       140472 :             IF (ASSOCIATED(chm_info%ub_a)) THEN
    1241      3842528 :                DO k = 1, SIZE(chm_info%ub_a)
    1242              :                   IF ((((chm_info%ub_a(k)) == (name_atm_a)) .AND. &
    1243              :                        ((chm_info%ub_b(k)) == (name_atm_b)) .AND. &
    1244      3818446 :                        ((chm_info%ub_c(k)) == (name_atm_c))) .OR. &
    1245              :                       (((chm_info%ub_a(k)) == (name_atm_c)) .AND. &
    1246              :                        ((chm_info%ub_b(k)) == (name_atm_b)) .AND. &
    1247        24082 :                        ((chm_info%ub_c(k)) == (name_atm_a)))) THEN
    1248        20692 :                      ub_list(j)%ub_kind%id_type = do_ff_charmm
    1249        20692 :                      ub_list(j)%ub_kind%k(1) = chm_info%ub_k(k)
    1250        20692 :                      ub_list(j)%ub_kind%r0 = chm_info%ub_r0(k)
    1251        20692 :                      IF (iw > 0) THEN
    1252              :                         WRITE (UNIT=iw, FMT="(T2,A)") &
    1253              :                            "FORCEFIELD| Found Urey-Bradley term (CHARMM) for the atomic kinds "// &
    1254          138 :                            TRIM(name_atm_a)//", "//TRIM(name_atm_b)//" and "//TRIM(name_atm_c)
    1255              :                      END IF
    1256              :                      CALL issue_duplications(found, "Urey-Bradley", name_atm_a, &
    1257        20692 :                                              name_atm_b, name_atm_c)
    1258        20692 :                      found = .TRUE.
    1259        20692 :                      EXIT
    1260              :                   END IF
    1261              :                END DO
    1262              :             END IF
    1263              : 
    1264              :             ! Loop over params from AMBER
    1265              :             ! teo - None that I know...
    1266              : 
    1267              :             ! Always have the input param last to overwrite all the other ones
    1268       140472 :             IF (ASSOCIATED(inp_info%ub_a)) THEN
    1269        50200 :                DO k = 1, SIZE(inp_info%ub_a)
    1270              :                   IF ((((inp_info%ub_a(k)) == (name_atm_a)) .AND. &
    1271              :                        ((inp_info%ub_b(k)) == (name_atm_b)) .AND. &
    1272        36781 :                        ((inp_info%ub_c(k)) == (name_atm_c))) .OR. &
    1273              :                       (((inp_info%ub_a(k)) == (name_atm_c)) .AND. &
    1274              :                        ((inp_info%ub_b(k)) == (name_atm_b)) .AND. &
    1275        13419 :                        ((inp_info%ub_c(k)) == (name_atm_a)))) THEN
    1276            8 :                      ub_list(j)%ub_kind%id_type = inp_info%ub_kind(k)
    1277           56 :                      ub_list(j)%ub_kind%k(:) = inp_info%ub_k(:, k)
    1278            8 :                      ub_list(j)%ub_kind%r0 = inp_info%ub_r0(k)
    1279            8 :                      IF (iw > 0) THEN
    1280              :                         WRITE (UNIT=iw, FMT="(T2,A)") &
    1281              :                            "FORCEFIELD| Found Urey-Bradley term (input) for the atomic kinds "// &
    1282            0 :                            TRIM(name_atm_a)//", "//TRIM(name_atm_b)//" and "//TRIM(name_atm_c)
    1283              :                      END IF
    1284              :                      CALL issue_duplications(found, "Urey-Bradley", name_atm_a, &
    1285            8 :                                              name_atm_b, name_atm_c)
    1286            8 :                      found = .TRUE.
    1287            8 :                      EXIT
    1288              :                   END IF
    1289              :                END DO
    1290              :             END IF
    1291              : 
    1292       140472 :             IF (.NOT. found) THEN
    1293              :                CALL store_FF_missing_par(atm1=TRIM(name_atm_a), &
    1294              :                                          atm2=TRIM(name_atm_b), &
    1295              :                                          atm3=TRIM(name_atm_c), &
    1296              :                                          type_name="Urey-Bradley", &
    1297       119772 :                                          array=Ainfo)
    1298       119772 :                ub_list(j)%id_type = do_ff_undef
    1299       119772 :                ub_list(j)%ub_kind%id_type = do_ff_undef
    1300       479088 :                ub_list(j)%ub_kind%k = 0.0_dp
    1301       119772 :                ub_list(j)%ub_kind%r0 = 0.0_dp
    1302              :             END IF
    1303              : 
    1304              :             ! QM/MM modifications
    1305       213296 :             IF (only_qm) THEN
    1306         1918 :                ub_list(j)%id_type = do_ff_undef
    1307         1918 :                ub_list(j)%ub_kind%id_type = do_ff_undef
    1308              :             END IF
    1309              :          END DO
    1310              : 
    1311              :          CALL set_molecule_kind(molecule_kind=molecule_kind, &
    1312       148293 :                                 ub_list=ub_list)
    1313              : 
    1314              :       END DO
    1315              : 
    1316         2645 :       CALL timestop(handle2)
    1317              : 
    1318         2645 :    END SUBROUTINE force_field_pack_ub
    1319              : 
    1320              : ! **************************************************************************************************
    1321              : !> \brief Pack in torsion information needed for the force_field
    1322              : !> \param particle_set ...
    1323              : !> \param molecule_kind_set ...
    1324              : !> \param molecule_set ...
    1325              : !> \param Ainfo ...
    1326              : !> \param chm_info ...
    1327              : !> \param inp_info ...
    1328              : !> \param gro_info ...
    1329              : !> \param amb_info ...
    1330              : !> \param iw ...
    1331              : ! **************************************************************************************************
    1332         2645 :    SUBROUTINE force_field_pack_tors(particle_set, molecule_kind_set, molecule_set, &
    1333              :                                     Ainfo, chm_info, inp_info, gro_info, amb_info, iw)
    1334              : 
    1335              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1336              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
    1337              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
    1338              :       CHARACTER(LEN=default_string_length), &
    1339              :          DIMENSION(:), POINTER                           :: Ainfo
    1340              :       TYPE(charmm_info_type), POINTER                    :: chm_info
    1341              :       TYPE(input_info_type), POINTER                     :: inp_info
    1342              :       TYPE(gromos_info_type), POINTER                    :: gro_info
    1343              :       TYPE(amber_info_type), POINTER                     :: amb_info
    1344              :       INTEGER, INTENT(IN)                                :: iw
    1345              : 
    1346              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_tors'
    1347              : 
    1348              :       CHARACTER(LEN=default_string_length)               :: ldum, molecule_name, name_atm_a, &
    1349              :                                                             name_atm_b, name_atm_c, name_atm_d
    1350              :       INTEGER                                            :: atm_a, atm_b, atm_c, atm_d, first, &
    1351              :                                                             handle2, i, imul, itype, j, k, k_end, &
    1352              :                                                             k_start, last, natom, ntorsion, &
    1353              :                                                             raw_parm_id
    1354              :       INTEGER, DIMENSION(4)                              :: glob_atm_id
    1355         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
    1356              :       LOGICAL                                            :: found, only_qm
    1357              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    1358              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
    1359              :       TYPE(molecule_type), POINTER                       :: molecule
    1360         2645 :       TYPE(torsion_type), DIMENSION(:), POINTER          :: torsion_list
    1361              : 
    1362         2645 :       CALL timeset(routineN, handle2)
    1363              : 
    1364         2645 :       IF (iw > 0) THEN
    1365              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
    1366          239 :             "FORCEFIELD| Checking for torsion terms"
    1367              :       END IF
    1368              : 
    1369        75469 :       DO i = 1, SIZE(molecule_kind_set)
    1370        72824 :          molecule_kind => molecule_kind_set(i)
    1371              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
    1372              :                                 molecule_list=molecule_list, &
    1373              :                                 name=molecule_name, &
    1374              :                                 natom=natom, &
    1375              :                                 ntorsion=ntorsion, &
    1376        72824 :                                 torsion_list=torsion_list)
    1377        72824 :          molecule => molecule_set(molecule_list(1))
    1378              :          CALL get_molecule(molecule=molecule, &
    1379              :                            first_atom=first, &
    1380        72824 :                            last_atom=last)
    1381       230497 :          DO j = 1, ntorsion
    1382       230497 :             IF (torsion_list(j)%torsion_kind%id_type == do_ff_undef) THEN
    1383       116171 :                atm_a = torsion_list(j)%a
    1384       116171 :                atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
    1385              :                CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1386       116171 :                                     name=name_atm_a)
    1387       116171 :                atm_b = torsion_list(j)%b
    1388       116171 :                atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
    1389              :                CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1390       116171 :                                     name=name_atm_b)
    1391       116171 :                atm_c = torsion_list(j)%c
    1392       116171 :                atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
    1393              :                CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1394       116171 :                                     name=name_atm_c)
    1395       116171 :                atm_d = torsion_list(j)%d
    1396       116171 :                atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
    1397              :                CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1398       116171 :                                     name=name_atm_d)
    1399       116171 :                found = .FALSE.
    1400       116171 :                only_qm = qmmm_ff_precond_only_qm(id1=name_atm_a, id2=name_atm_b, id3=name_atm_c, id4=name_atm_d)
    1401       116171 :                CALL uppercase(name_atm_a)
    1402       116171 :                CALL uppercase(name_atm_b)
    1403       116171 :                CALL uppercase(name_atm_c)
    1404       116171 :                CALL uppercase(name_atm_d)
    1405              : 
    1406              :                ! Loop over params from GROMOS
    1407       116171 :                IF (ASSOCIATED(gro_info%torsion_k)) THEN
    1408          312 :                   k = SIZE(gro_info%torsion_k)
    1409          312 :                   itype = torsion_list(j)%itype
    1410          312 :                   IF (itype > 0) THEN
    1411          312 :                      CALL reallocate(torsion_list(j)%torsion_kind%k, 1, 1)
    1412          312 :                      CALL reallocate(torsion_list(j)%torsion_kind%m, 1, 1)
    1413          312 :                      CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, 1)
    1414          312 :                      torsion_list(j)%torsion_kind%nmul = 1
    1415          312 :                      torsion_list(j)%torsion_kind%m(1) = gro_info%torsion_m(itype)
    1416          312 :                      torsion_list(j)%torsion_kind%k(1) = gro_info%torsion_k(itype)
    1417          312 :                      torsion_list(j)%torsion_kind%phi0(1) = gro_info%torsion_phi0(itype)
    1418              :                   ELSE
    1419            0 :                      CALL reallocate(torsion_list(j)%torsion_kind%k, 1, 1)
    1420            0 :                      CALL reallocate(torsion_list(j)%torsion_kind%m, 1, 1)
    1421            0 :                      CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, 1)
    1422            0 :                      torsion_list(j)%torsion_kind%nmul = 1
    1423            0 :                      torsion_list(j)%torsion_kind%m(1) = gro_info%torsion_m(itype/k)
    1424            0 :                      torsion_list(j)%torsion_kind%k(1) = gro_info%torsion_k(itype/k)
    1425            0 :                      torsion_list(j)%torsion_kind%phi0(1) = gro_info%torsion_phi0(itype/k)
    1426              :                   END IF
    1427          312 :                   torsion_list(j)%torsion_kind%id_type = gro_info%ff_gromos_type
    1428          312 :                   torsion_list(j)%id_type = gro_info%ff_gromos_type
    1429          312 :                   found = .TRUE.
    1430          312 :                   imul = torsion_list(j)%torsion_kind%nmul
    1431              :                END IF
    1432              : 
    1433              :                ! Loop over params from CHARMM
    1434       116171 :                IF (ASSOCIATED(chm_info%torsion_a)) THEN
    1435     20328202 :                   DO k = 1, SIZE(chm_info%torsion_a)
    1436              :                      IF ((((chm_info%torsion_a(k)) == (name_atm_a)) .AND. &
    1437              :                           ((chm_info%torsion_b(k)) == (name_atm_b)) .AND. &
    1438              :                           ((chm_info%torsion_c(k)) == (name_atm_c)) .AND. &
    1439     20273793 :                           ((chm_info%torsion_d(k)) == (name_atm_d))) .OR. &
    1440              :                          (((chm_info%torsion_a(k)) == (name_atm_d)) .AND. &
    1441              :                           ((chm_info%torsion_b(k)) == (name_atm_c)) .AND. &
    1442              :                           ((chm_info%torsion_c(k)) == (name_atm_b)) .AND. &
    1443        54409 :                           ((chm_info%torsion_d(k)) == (name_atm_a)))) THEN
    1444        44224 :                         imul = torsion_list(j)%torsion_kind%nmul + 1
    1445        44224 :                         CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
    1446        44224 :                         CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
    1447        44224 :                         CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
    1448        44224 :                         torsion_list(j)%torsion_kind%id_type = do_ff_charmm
    1449        44224 :                         torsion_list(j)%torsion_kind%k(imul) = chm_info%torsion_k(k)
    1450        44224 :                         torsion_list(j)%torsion_kind%m(imul) = chm_info%torsion_m(k)
    1451        44224 :                         torsion_list(j)%torsion_kind%phi0(imul) = chm_info%torsion_phi0(k)
    1452        44224 :                         torsion_list(j)%torsion_kind%nmul = imul
    1453        44224 :                         found = .TRUE.
    1454              :                      END IF
    1455              :                   END DO
    1456              : 
    1457        54409 :                   IF (.NOT. found) THEN
    1458      6901506 :                      DO k = 1, SIZE(chm_info%torsion_a)
    1459              :                         IF ((((chm_info%torsion_a(k)) == ("X")) .AND. &
    1460              :                              ((chm_info%torsion_b(k)) == (name_atm_b)) .AND. &
    1461              :                              ((chm_info%torsion_c(k)) == (name_atm_c)) .AND. &
    1462      6886624 :                              ((chm_info%torsion_d(k)) == ("X"))) .OR. &
    1463              :                             (((chm_info%torsion_a(k)) == ("X")) .AND. &
    1464              :                              ((chm_info%torsion_b(k)) == (name_atm_c)) .AND. &
    1465              :                              ((chm_info%torsion_c(k)) == (name_atm_b)) .AND. &
    1466        14882 :                              ((chm_info%torsion_d(k)) == ("X")))) THEN
    1467        12990 :                            imul = torsion_list(j)%torsion_kind%nmul + 1
    1468        12990 :                            CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
    1469        12990 :                            CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
    1470        12990 :                            CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
    1471        12990 :                            torsion_list(j)%torsion_kind%id_type = do_ff_charmm
    1472        12990 :                            torsion_list(j)%torsion_kind%k(imul) = chm_info%torsion_k(k)
    1473        12990 :                            torsion_list(j)%torsion_kind%m(imul) = chm_info%torsion_m(k)
    1474        12990 :                            torsion_list(j)%torsion_kind%phi0(imul) = chm_info%torsion_phi0(k)
    1475        12990 :                            torsion_list(j)%torsion_kind%nmul = imul
    1476        12990 :                            found = .TRUE.
    1477              :                         END IF
    1478              :                      END DO
    1479              :                   END IF
    1480              :                END IF
    1481              : 
    1482              :                ! Loop over params from AMBER
    1483              :                ! Assign real parameters from Amber PRMTOP file using global atom indices
    1484              :                ! Type-based assignment is prone to errors
    1485       116171 :                IF (ASSOCIATED(amb_info%torsion_a)) THEN
    1486              :                   ! Get global atom indices
    1487        45098 :                   glob_atm_id(1) = atm_a + first - 1
    1488        45098 :                   glob_atm_id(2) = atm_b + first - 1
    1489        45098 :                   glob_atm_id(3) = atm_c + first - 1
    1490        45098 :                   glob_atm_id(4) = atm_d + first - 1
    1491              : 
    1492              :                   ! Search sorted array of raw torsion parameters
    1493              :                   ! The array can be too long for linear lookup
    1494              :                   ! Use binary search for first atom index
    1495        45098 :                   k_start = bsearch_leftmost_2d(amb_info%raw_torsion_id, glob_atm_id(1))
    1496        45098 :                   k_end = UBOUND(amb_info%raw_torsion_id, DIM=2)
    1497              : 
    1498              :                   ! If not found, skip the loop
    1499        45098 :                   IF (k_start /= 0) THEN
    1500              : 
    1501       207356 :                      DO k = k_start, k_end
    1502       207332 :                         IF (glob_atm_id(1) < amb_info%raw_torsion_id(1, k)) EXIT
    1503       613232 :                         IF (ANY((glob_atm_id - amb_info%raw_torsion_id(1:4, k)) /= 0)) CYCLE
    1504              : 
    1505        40364 :                         raw_parm_id = amb_info%raw_torsion_id(5, k)
    1506        40364 :                         imul = torsion_list(j)%torsion_kind%nmul + 1
    1507        40364 :                         CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
    1508        40364 :                         CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
    1509        40364 :                         CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
    1510        40364 :                         torsion_list(j)%torsion_kind%id_type = do_ff_amber
    1511        40364 :                         torsion_list(j)%torsion_kind%k(imul) = amb_info%raw_torsion_k(raw_parm_id)
    1512        40364 :                         torsion_list(j)%torsion_kind%m(imul) = NINT(amb_info%raw_torsion_m(raw_parm_id))
    1513        40364 :                         torsion_list(j)%torsion_kind%phi0(imul) = amb_info%raw_torsion_phi0(raw_parm_id)
    1514        40364 :                         torsion_list(j)%torsion_kind%nmul = imul
    1515       207356 :                         found = .TRUE.
    1516              :                      END DO
    1517              : 
    1518              :                   END IF
    1519              : 
    1520              :                END IF
    1521              : 
    1522              :                ! Always have the input param last to overwrite all the other ones
    1523       116171 :                IF (ASSOCIATED(inp_info%torsion_a)) THEN
    1524          192 :                   DO k = 1, SIZE(inp_info%torsion_a)
    1525              :                      IF ((((inp_info%torsion_a(k)) == (name_atm_a)) .AND. &
    1526              :                           ((inp_info%torsion_b(k)) == (name_atm_b)) .AND. &
    1527              :                           ((inp_info%torsion_c(k)) == (name_atm_c)) .AND. &
    1528          166 :                           ((inp_info%torsion_d(k)) == (name_atm_d))) .OR. &
    1529              :                          (((inp_info%torsion_a(k)) == (name_atm_d)) .AND. &
    1530              :                           ((inp_info%torsion_b(k)) == (name_atm_c)) .AND. &
    1531              :                           ((inp_info%torsion_c(k)) == (name_atm_b)) .AND. &
    1532           26 :                           ((inp_info%torsion_d(k)) == (name_atm_a)))) THEN
    1533           38 :                         imul = torsion_list(j)%torsion_kind%nmul + 1
    1534           38 :                         CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
    1535           38 :                         CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
    1536           38 :                         CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
    1537           38 :                         torsion_list(j)%torsion_kind%id_type = inp_info%torsion_kind(k)
    1538           38 :                         torsion_list(j)%torsion_kind%k(imul) = inp_info%torsion_k(k)
    1539           38 :                         torsion_list(j)%torsion_kind%m(imul) = inp_info%torsion_m(k)
    1540           38 :                         torsion_list(j)%torsion_kind%phi0(imul) = inp_info%torsion_phi0(k)
    1541           38 :                         torsion_list(j)%torsion_kind%nmul = imul
    1542           38 :                         found = .TRUE.
    1543              :                      END IF
    1544              :                   END DO
    1545              :                END IF
    1546              : 
    1547       116171 :                IF (found) THEN
    1548        80089 :                   ldum = cp_to_string(imul)
    1549        80089 :                   IF (iw > 0) THEN
    1550         1518 :                      IF (imul < 1) THEN
    1551              :                         WRITE (UNIT=iw, FMT="(T2,A)") &
    1552            0 :                            "FORCEFIELD| No torsion term found"
    1553         1518 :                      ELSE IF (imul == 1) THEN
    1554              :                         WRITE (UNIT=iw, FMT="(T2,A)") &
    1555              :                            "FORCEFIELD| Found torsion term for the atomic kinds "// &
    1556              :                            TRIM(name_atm_a)//", "//TRIM(name_atm_b)// &
    1557              :                            ", "//TRIM(name_atm_c)// &
    1558         1389 :                            " and "//TRIM(name_atm_d)
    1559              :                      ELSE
    1560              :                         WRITE (UNIT=iw, FMT="(T2,A)") &
    1561              :                            "FORCEFIELD| Found multiple ("//TRIM(ldum)// &
    1562              :                            ") torsion terms for the atomic kinds "// &
    1563              :                            TRIM(name_atm_a)//", "//TRIM(name_atm_b)// &
    1564              :                            ", "//TRIM(name_atm_c)// &
    1565          129 :                            " and "//TRIM(name_atm_d)
    1566              :                      END IF
    1567              :                   END IF
    1568              :                ELSE
    1569              :                   CALL store_FF_missing_par(atm1=TRIM(name_atm_a), &
    1570              :                                             atm2=TRIM(name_atm_b), &
    1571              :                                             atm3=TRIM(name_atm_c), &
    1572              :                                             atm4=TRIM(name_atm_d), &
    1573              :                                             type_name="Torsion", &
    1574        36082 :                                             array=Ainfo)
    1575        36082 :                   torsion_list(j)%torsion_kind%id_type = do_ff_undef
    1576        36082 :                   torsion_list(j)%id_type = do_ff_undef
    1577              :                END IF
    1578              : 
    1579              :                ! QM/MM modifications
    1580       116171 :                IF (only_qm) THEN
    1581         1968 :                   IF (iw > 0) THEN
    1582              :                      WRITE (UNIT=iw, FMT="(T2,A,I0,4(A,I0))") &
    1583            0 :                         "FORCEFIELD| Torsion ", j, " for molecule kind "//TRIM(molecule_name)// &
    1584              :                         TRIM(name_atm_a)// &
    1585              :                         "-"//TRIM(name_atm_b)//"-"//TRIM(name_atm_c)//"-"// &
    1586            0 :                         TRIM(name_atm_d)//" (", torsion_list(j)%a, ", ", &
    1587            0 :                         torsion_list(j)%b, ", ", torsion_list(j)%c, ", ", &
    1588            0 :                         torsion_list(j)%d
    1589              :                   END IF
    1590         1968 :                   torsion_list(j)%torsion_kind%id_type = do_ff_undef
    1591         1968 :                   torsion_list(j)%id_type = do_ff_undef
    1592              :                END IF
    1593              : 
    1594              :             END IF
    1595              : 
    1596              :          END DO ! torsion
    1597              : 
    1598              :          CALL set_molecule_kind(molecule_kind=molecule_kind, &
    1599       148293 :                                 torsion_list=torsion_list)
    1600              : 
    1601              :       END DO ! molecule kind
    1602              : 
    1603         2645 :       CALL timestop(handle2)
    1604              : 
    1605         2645 :    END SUBROUTINE force_field_pack_tors
    1606              : 
    1607              : ! **************************************************************************************************
    1608              : !> \brief Pack in impropers information needed for the force_field
    1609              : !> \param particle_set ...
    1610              : !> \param molecule_kind_set ...
    1611              : !> \param molecule_set ...
    1612              : !> \param Ainfo ...
    1613              : !> \param chm_info ...
    1614              : !> \param inp_info ...
    1615              : !> \param gro_info ...
    1616              : !> \param iw ...
    1617              : ! **************************************************************************************************
    1618         2645 :    SUBROUTINE force_field_pack_impr(particle_set, molecule_kind_set, molecule_set, &
    1619              :                                     Ainfo, chm_info, inp_info, gro_info, iw)
    1620              : 
    1621              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1622              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
    1623              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
    1624              :       CHARACTER(LEN=default_string_length), &
    1625              :          DIMENSION(:), POINTER                           :: Ainfo
    1626              :       TYPE(charmm_info_type), POINTER                    :: chm_info
    1627              :       TYPE(input_info_type), POINTER                     :: inp_info
    1628              :       TYPE(gromos_info_type), POINTER                    :: gro_info
    1629              :       INTEGER, INTENT(IN)                                :: iw
    1630              : 
    1631              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_impr'
    1632              : 
    1633              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_b, name_atm_c, &
    1634              :                                                             name_atm_d
    1635              :       INTEGER                                            :: atm_a, atm_b, atm_c, atm_d, first, &
    1636              :                                                             handle2, i, itype, j, k, last, natom, &
    1637              :                                                             nimpr
    1638         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
    1639              :       LOGICAL                                            :: found, only_qm
    1640              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    1641         2645 :       TYPE(impr_type), DIMENSION(:), POINTER             :: impr_list
    1642              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
    1643              :       TYPE(molecule_type), POINTER                       :: molecule
    1644              : 
    1645         2645 :       CALL timeset(routineN, handle2)
    1646              : 
    1647         2645 :       IF (iw > 0) THEN
    1648              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
    1649          239 :             "FORCEFIELD| Checking for improper terms"
    1650              :       END IF
    1651              : 
    1652        75469 :       DO i = 1, SIZE(molecule_kind_set)
    1653              : 
    1654        72824 :          molecule_kind => molecule_kind_set(i)
    1655              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
    1656              :                                 molecule_list=molecule_list, &
    1657              :                                 natom=natom, &
    1658              :                                 nimpr=nimpr, &
    1659        72824 :                                 impr_list=impr_list)
    1660              : 
    1661        72824 :          molecule => molecule_set(molecule_list(1))
    1662        72824 :          CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
    1663              : 
    1664        78136 :          DO j = 1, nimpr
    1665         5312 :             atm_a = impr_list(j)%a
    1666         5312 :             atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
    1667              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1668         5312 :                                  name=name_atm_a)
    1669         5312 :             atm_b = impr_list(j)%b
    1670         5312 :             atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
    1671              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1672         5312 :                                  name=name_atm_b)
    1673         5312 :             atm_c = impr_list(j)%c
    1674         5312 :             atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
    1675              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1676         5312 :                                  name=name_atm_c)
    1677         5312 :             atm_d = impr_list(j)%d
    1678         5312 :             atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
    1679              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1680         5312 :                                  name=name_atm_d)
    1681         5312 :             found = .FALSE.
    1682         5312 :             only_qm = qmmm_ff_precond_only_qm(id1=name_atm_a, id2=name_atm_b, id3=name_atm_c, id4=name_atm_d)
    1683         5312 :             CALL uppercase(name_atm_a)
    1684         5312 :             CALL uppercase(name_atm_b)
    1685         5312 :             CALL uppercase(name_atm_c)
    1686         5312 :             CALL uppercase(name_atm_d)
    1687              : 
    1688              :             ! Loop over params from GROMOS
    1689         5312 :             IF (ASSOCIATED(gro_info%impr_k)) THEN
    1690            0 :                k = SIZE(gro_info%impr_k)
    1691            0 :                itype = impr_list(j)%itype
    1692            0 :                IF (itype > 0) THEN
    1693            0 :                   impr_list(j)%impr_kind%k = gro_info%impr_k(itype)
    1694            0 :                   impr_list(j)%impr_kind%phi0 = gro_info%impr_phi0(itype)
    1695              :                ELSE
    1696            0 :                   impr_list(j)%impr_kind%k = gro_info%impr_k(itype)
    1697            0 :                   impr_list(j)%impr_kind%phi0 = gro_info%impr_phi0(itype)
    1698              :                END IF
    1699            0 :                found = .TRUE.
    1700            0 :                impr_list(j)%impr_kind%id_type = gro_info%ff_gromos_type
    1701            0 :                impr_list(j)%id_type = gro_info%ff_gromos_type
    1702              :             END IF
    1703              : 
    1704              :             ! Loop over params from CHARMM
    1705         5312 :             IF (ASSOCIATED(chm_info%impr_a)) THEN
    1706       171282 :                DO k = 1, SIZE(chm_info%impr_a)
    1707              :                   IF ((((chm_info%impr_a(k)) == (name_atm_a)) .AND. &
    1708              :                        ((chm_info%impr_b(k)) == (name_atm_b)) .AND. &
    1709              :                        ((chm_info%impr_c(k)) == (name_atm_c)) .AND. &
    1710       168054 :                        ((chm_info%impr_d(k)) == (name_atm_d))) .OR. &
    1711              :                       (((chm_info%impr_a(k)) == (name_atm_d)) .AND. &
    1712              :                        ((chm_info%impr_b(k)) == (name_atm_c)) .AND. &
    1713              :                        ((chm_info%impr_c(k)) == (name_atm_b)) .AND. &
    1714         3228 :                        ((chm_info%impr_d(k)) == (name_atm_a)))) THEN
    1715         1130 :                      impr_list(j)%impr_kind%id_type = do_ff_charmm
    1716         1130 :                      impr_list(j)%impr_kind%k = chm_info%impr_k(k)
    1717         1130 :                      impr_list(j)%impr_kind%phi0 = chm_info%impr_phi0(k)
    1718              :                      CALL issue_duplications(found, "Impropers", name_atm_a, name_atm_b, &
    1719         1130 :                                              name_atm_c, name_atm_d)
    1720         1130 :                      found = .TRUE.
    1721         1130 :                      EXIT
    1722              :                   END IF
    1723              :                END DO
    1724         4358 :                IF (.NOT. found) THEN
    1725       116678 :                   DO k = 1, SIZE(chm_info%impr_a)
    1726              :                      IF ((((chm_info%impr_a(k)) == (name_atm_a)) .AND. &
    1727              :                           ((chm_info%impr_b(k)) == ("X")) .AND. &
    1728              :                           ((chm_info%impr_c(k)) == ("X")) .AND. &
    1729       115728 :                           ((chm_info%impr_d(k)) == (name_atm_d))) .OR. &
    1730              :                          (((chm_info%impr_a(k)) == (name_atm_d)) .AND. &
    1731              :                           ((chm_info%impr_b(k)) == ("X")) .AND. &
    1732              :                           ((chm_info%impr_c(k)) == ("X")) .AND. &
    1733          950 :                           ((chm_info%impr_d(k)) == (name_atm_a)))) THEN
    1734         2278 :                         impr_list(j)%impr_kind%id_type = do_ff_charmm
    1735         2278 :                         impr_list(j)%impr_kind%k = chm_info%impr_k(k)
    1736         2278 :                         impr_list(j)%impr_kind%phi0 = chm_info%impr_phi0(k)
    1737              :                         CALL issue_duplications(found, "Impropers", name_atm_a, name_atm_b, &
    1738         2278 :                                                 name_atm_c, name_atm_d)
    1739         2278 :                         found = .TRUE.
    1740         2278 :                         EXIT
    1741              :                      END IF
    1742              :                   END DO
    1743              :                END IF
    1744              :             END IF
    1745              : 
    1746              :             ! Loop over params from AMBER not needed since impropers in AMBER
    1747              :             ! are treated like standard torsions
    1748              : 
    1749              :             ! always have the input param last to overwrite all the other ones
    1750         5312 :             IF (ASSOCIATED(inp_info%impr_a)) THEN
    1751           20 :                DO k = 1, SIZE(inp_info%impr_a)
    1752              :                   IF (((inp_info%impr_a(k)) == (name_atm_a)) .AND. &
    1753           14 :                       ((inp_info%impr_b(k)) == (name_atm_b)) .AND. &
    1754              :                       ((((inp_info%impr_c(k)) == (name_atm_c)) .AND. &
    1755              :                         ((inp_info%impr_d(k)) == (name_atm_d))) .OR. &
    1756              :                        (((inp_info%impr_c(k)) == (name_atm_d)) .AND. &
    1757            6 :                         ((inp_info%impr_d(k)) == (name_atm_c))))) THEN
    1758            8 :                      impr_list(j)%impr_kind%id_type = inp_info%impr_kind(k)
    1759            8 :                      impr_list(j)%impr_kind%k = inp_info%impr_k(k)
    1760            8 :                      IF (((inp_info%impr_c(k)) == (name_atm_c)) .AND. &
    1761              :                          ((inp_info%impr_d(k)) == (name_atm_d))) THEN
    1762            8 :                         impr_list(j)%impr_kind%phi0 = inp_info%impr_phi0(k)
    1763              :                      ELSE
    1764            0 :                         impr_list(j)%impr_kind%phi0 = -inp_info%impr_phi0(k)
    1765              :                         ! alternative solutions:
    1766              :                         !  - swap impr_list(j)%c with impr_list(j)%d and
    1767              :                         !    name_atom_c with name_atom_d and
    1768              :                         !    atm_c with atm_d
    1769              :                         !  - introduce impr_list(j)%impr_kind%sign. if one, the
    1770              :                         !    sign of phi is not changed in mol_force.f90. if minus
    1771              :                         !    one, the sign of phi is changed in mol_force.f90
    1772              :                         ! similar problems with parameters from charmm pot file
    1773              :                         ! above
    1774              :                      END IF
    1775              :                      CALL issue_duplications(found, "Impropers", name_atm_a, name_atm_b, &
    1776            8 :                                              name_atm_c, name_atm_d)
    1777            8 :                      found = .TRUE.
    1778            8 :                      EXIT
    1779              :                   END IF
    1780              :                END DO
    1781              :             END IF
    1782              : 
    1783         5312 :             IF (.NOT. found) THEN
    1784              :                CALL store_FF_missing_par(atm1=TRIM(name_atm_a), &
    1785              :                                          atm2=TRIM(name_atm_b), &
    1786              :                                          atm3=TRIM(name_atm_c), &
    1787              :                                          atm4=TRIM(name_atm_d), &
    1788              :                                          type_name="Improper", &
    1789         1896 :                                          array=Ainfo)
    1790         1896 :                impr_list(j)%impr_kind%k = 0.0_dp
    1791         1896 :                impr_list(j)%impr_kind%phi0 = 0.0_dp
    1792         1896 :                impr_list(j)%impr_kind%id_type = do_ff_undef
    1793         1896 :                impr_list(j)%id_type = do_ff_undef
    1794              :             END IF
    1795              : 
    1796              :             ! QM/MM modifications
    1797        78136 :             IF (only_qm) THEN
    1798           58 :                IF (found) THEN
    1799           10 :                   IF (iw > 0) THEN
    1800              :                      WRITE (UNIT=iw, FMT="(T2,A)") &
    1801              :                         "FORCEFIELD| Found improper term for "//TRIM(name_atm_a)// &
    1802              :                         "-"//TRIM(name_atm_b)//"-"//TRIM(name_atm_c)//"-"// &
    1803            0 :                         TRIM(name_atm_d)
    1804              :                   END IF
    1805              :                END IF
    1806           58 :                impr_list(j)%impr_kind%id_type = do_ff_undef
    1807           58 :                impr_list(j)%id_type = do_ff_undef
    1808              :             END IF
    1809              : 
    1810              :          END DO
    1811              : 
    1812       148293 :          CALL set_molecule_kind(molecule_kind=molecule_kind, impr_list=impr_list)
    1813              : 
    1814              :       END DO
    1815              : 
    1816         2645 :       CALL timestop(handle2)
    1817              : 
    1818         2645 :    END SUBROUTINE force_field_pack_impr
    1819              : 
    1820              : ! **************************************************************************************************
    1821              : !> \brief Pack in opbend information needed for the force_field.
    1822              : !>        No loop over params for charmm, amber and gromos since these force
    1823              : !>        fields have no opbends
    1824              : !> \param particle_set ...
    1825              : !> \param molecule_kind_set ...
    1826              : !> \param molecule_set ...
    1827              : !> \param Ainfo ...
    1828              : !> \param inp_info ...
    1829              : !> \param iw ...
    1830              : !> \author Louis Vanduyfhuys
    1831              : ! **************************************************************************************************
    1832         2645 :    SUBROUTINE force_field_pack_opbend(particle_set, molecule_kind_set, molecule_set, Ainfo, &
    1833              :                                       inp_info, iw)
    1834              : 
    1835              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1836              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
    1837              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
    1838              :       CHARACTER(LEN=default_string_length), &
    1839              :          DIMENSION(:), POINTER                           :: Ainfo
    1840              :       TYPE(input_info_type), POINTER                     :: inp_info
    1841              :       INTEGER, INTENT(IN)                                :: iw
    1842              : 
    1843              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_opbend'
    1844              : 
    1845              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_b, name_atm_c, &
    1846              :                                                             name_atm_d
    1847              :       INTEGER                                            :: atm_a, atm_b, atm_c, atm_d, first, &
    1848              :                                                             handle2, i, j, k, last, natom, nopbend
    1849         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list
    1850              :       LOGICAL                                            :: found, only_qm
    1851              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    1852              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
    1853              :       TYPE(molecule_type), POINTER                       :: molecule
    1854         2645 :       TYPE(opbend_type), DIMENSION(:), POINTER           :: opbend_list
    1855              : 
    1856         2645 :       CALL timeset(routineN, handle2)
    1857              : 
    1858         2645 :       IF (iw > 0) THEN
    1859              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
    1860          239 :             "FORCEFIELD| Checking for out-of-plane bend terms"
    1861              :       END IF
    1862              : 
    1863        75469 :       DO i = 1, SIZE(molecule_kind_set)
    1864        72824 :          molecule_kind => molecule_kind_set(i)
    1865              :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
    1866              :                                 molecule_list=molecule_list, &
    1867              :                                 natom=natom, &
    1868        72824 :                                 nopbend=nopbend, opbend_list=opbend_list)
    1869        72824 :          molecule => molecule_set(molecule_list(1))
    1870              : 
    1871        72824 :          CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
    1872        78136 :          DO j = 1, nopbend
    1873         5312 :             atm_a = opbend_list(j)%a
    1874         5312 :             atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
    1875              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1876         5312 :                                  name=name_atm_a)
    1877         5312 :             atm_b = opbend_list(j)%b
    1878         5312 :             atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
    1879              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1880         5312 :                                  name=name_atm_b)
    1881         5312 :             atm_c = opbend_list(j)%c
    1882         5312 :             atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
    1883              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1884         5312 :                                  name=name_atm_c)
    1885         5312 :             atm_d = opbend_list(j)%d
    1886         5312 :             atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
    1887              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
    1888         5312 :                                  name=name_atm_d)
    1889         5312 :             found = .FALSE.
    1890         5312 :             only_qm = qmmm_ff_precond_only_qm(id1=name_atm_a, id2=name_atm_b, id3=name_atm_c, id4=name_atm_d)
    1891         5312 :             CALL uppercase(name_atm_a)
    1892         5312 :             CALL uppercase(name_atm_b)
    1893         5312 :             CALL uppercase(name_atm_c)
    1894         5312 :             CALL uppercase(name_atm_d)
    1895              : 
    1896              :             ! always have the input param last to overwrite all the other ones
    1897         5312 :             IF (ASSOCIATED(inp_info%opbend_a)) THEN
    1898            2 :                DO k = 1, SIZE(inp_info%opbend_a)
    1899              :                   IF (((inp_info%opbend_a(k)) == (name_atm_a)) .AND. &
    1900            2 :                       ((inp_info%opbend_d(k)) == (name_atm_d)) .AND. &
    1901              :                       ((((inp_info%opbend_c(k)) == (name_atm_c)) .AND. &
    1902              :                         ((inp_info%opbend_b(k)) == (name_atm_b))) .OR. &
    1903              :                        (((inp_info%opbend_c(k)) == (name_atm_b)) .AND. &
    1904            0 :                         ((inp_info%opbend_b(k)) == (name_atm_c))))) THEN
    1905            2 :                      opbend_list(j)%opbend_kind%id_type = inp_info%opbend_kind(k)
    1906            2 :                      opbend_list(j)%opbend_kind%k = inp_info%opbend_k(k)
    1907            2 :                      IF (((inp_info%opbend_c(k)) == (name_atm_c)) .AND. &
    1908              :                          ((inp_info%opbend_b(k)) == (name_atm_b))) THEN
    1909            2 :                         opbend_list(j)%opbend_kind%phi0 = inp_info%opbend_phi0(k)
    1910              :                      ELSE
    1911            0 :                         opbend_list(j)%opbend_kind%phi0 = -inp_info%opbend_phi0(k)
    1912              :                         ! alternative solutions:
    1913              :                         !  - swap opbend_list(j)%c with opbend_list(j)%b and
    1914              :                         !    name_atom_c with name_atom_b and
    1915              :                         !    atm_c with atm_b
    1916              :                         !  - introduce opbend_list(j)%opbend_kind%sign. if one, the
    1917              :                         !    sign of phi is not changed in mol_force.f90. if minus
    1918              :                         !    one, the sign of phi is changed in mol_force.f90
    1919              : 
    1920              :                      END IF
    1921              :                      CALL issue_duplications(found, "Out of plane bend", name_atm_a, name_atm_b, &
    1922            2 :                                              name_atm_c, name_atm_d)
    1923            2 :                      found = .TRUE.
    1924            2 :                      EXIT
    1925              :                   END IF
    1926              :                END DO
    1927              :             END IF
    1928              : 
    1929         5312 :             IF (.NOT. found) THEN
    1930              :                CALL store_FF_missing_par(atm1=TRIM(name_atm_a), &
    1931              :                                          atm2=TRIM(name_atm_b), &
    1932              :                                          atm3=TRIM(name_atm_c), &
    1933              :                                          atm4=TRIM(name_atm_d), &
    1934              :                                          type_name="Out of plane bend", &
    1935         5310 :                                          array=Ainfo)
    1936         5310 :                opbend_list(j)%opbend_kind%k = 0.0_dp
    1937         5310 :                opbend_list(j)%opbend_kind%phi0 = 0.0_dp
    1938         5310 :                opbend_list(j)%opbend_kind%id_type = do_ff_undef
    1939         5310 :                opbend_list(j)%id_type = do_ff_undef
    1940              :             END IF
    1941              :             !
    1942              :             ! QM/MM modifications
    1943              :             !
    1944        78136 :             IF (only_qm) THEN
    1945           58 :                opbend_list(j)%opbend_kind%id_type = do_ff_undef
    1946           58 :                opbend_list(j)%id_type = do_ff_undef
    1947              :             END IF
    1948              : 
    1949              :          END DO
    1950              : 
    1951       148293 :          CALL set_molecule_kind(molecule_kind=molecule_kind, opbend_list=opbend_list)
    1952              : 
    1953              :       END DO
    1954              : 
    1955         2645 :       CALL timestop(handle2)
    1956              : 
    1957         2645 :    END SUBROUTINE force_field_pack_opbend
    1958              : 
    1959              : ! **************************************************************************************************
    1960              : !> \brief Set up array of full charges
    1961              : !> \param charges ...
    1962              : !> \param charges_section ...
    1963              : !> \param particle_set ...
    1964              : !> \param my_qmmm ...
    1965              : !> \param qmmm_env ...
    1966              : !> \param inp_info ...
    1967              : !> \param iw4 ...
    1968              : !> \date 12.2010
    1969              : !> \author Teodoro Laino (teodoro.laino@gmail.com)
    1970              : ! **************************************************************************************************
    1971            8 :    SUBROUTINE force_field_pack_charges(charges, charges_section, particle_set, &
    1972              :                                        my_qmmm, qmmm_env, inp_info, iw4)
    1973              : 
    1974              :       REAL(KIND=dp), DIMENSION(:), POINTER               :: charges
    1975              :       TYPE(section_vals_type), POINTER                   :: charges_section
    1976              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1977              :       LOGICAL                                            :: my_qmmm
    1978              :       TYPE(qmmm_env_mm_type), POINTER                    :: qmmm_env
    1979              :       TYPE(input_info_type), POINTER                     :: inp_info
    1980              :       INTEGER, INTENT(IN)                                :: iw4
    1981              : 
    1982              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_charges'
    1983              : 
    1984              :       CHARACTER(LEN=default_string_length)               :: atmname
    1985              :       INTEGER                                            :: handle, iatom, ilink, j, nval
    1986              :       LOGICAL                                            :: found_p, is_link_atom, is_ok, &
    1987              :                                                             only_manybody, only_qm
    1988              :       REAL(KIND=dp)                                      :: charge, charge_tot, rval, scale_factor
    1989              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    1990              :       TYPE(cp_sll_val_type), POINTER                     :: list
    1991              :       TYPE(fist_potential_type), POINTER                 :: fist_potential
    1992              :       TYPE(val_type), POINTER                            :: val
    1993              : 
    1994            8 :       CALL timeset(routineN, handle)
    1995              : 
    1996            8 :       charge_tot = 0.0_dp
    1997            8 :       NULLIFY (list)
    1998              : 
    1999              :       ! Not implemented for core-shell
    2000            8 :       IF (ASSOCIATED(inp_info%shell_list)) THEN
    2001            0 :          CPABORT("Array of charges is not implemented for the core-shell model")
    2002              :       END IF
    2003              : 
    2004              :       ! Allocate array to particle_set size
    2005            8 :       CPASSERT(.NOT. (ASSOCIATED(charges)))
    2006           24 :       ALLOCATE (charges(SIZE(particle_set)))
    2007              : 
    2008              :       ! Fill with input values
    2009            8 :       CALL section_vals_val_get(charges_section, "_DEFAULT_KEYWORD_", n_rep_val=nval)
    2010            8 :       CPASSERT(nval == SIZE(charges))
    2011            8 :       CALL section_vals_list_get(charges_section, "_DEFAULT_KEYWORD_", list=list)
    2012           44 :       DO iatom = 1, nval
    2013              :          ! we use only the first default_string_length characters of each line
    2014           36 :          is_ok = cp_sll_val_next(list, val)
    2015           36 :          CALL val_get(val, r_val=rval)
    2016              :          ! assign values
    2017           36 :          charges(iatom) = rval
    2018              : 
    2019              :          ! Perform a post-processing
    2020           36 :          atomic_kind => particle_set(iatom)%atomic_kind
    2021              :          CALL get_atomic_kind(atomic_kind=atomic_kind, &
    2022              :                               fist_potential=fist_potential, &
    2023           36 :                               name=atmname)
    2024           36 :          CALL get_potential(potential=fist_potential, qeff=charge)
    2025              : 
    2026           36 :          only_qm = qmmm_ff_precond_only_qm(id1=atmname, is_link=is_link_atom)
    2027           36 :          CALL uppercase(atmname)
    2028           36 :          IF (charge /= -HUGE(0.0_dp)) &
    2029              :             CALL cp_warn(__LOCATION__, &
    2030              :                          "The charge for atom index ("//cp_to_string(iatom)//") and atom name ("// &
    2031              :                          TRIM(atmname)//") was already defined. The charge associated to this kind"// &
    2032            0 :                          " will be set to an uninitialized value and only the atom specific charge will be used! ")
    2033           36 :          charge = -HUGE(0.0_dp)
    2034              : 
    2035              :          ! Check if the potential really requires the charge definition..
    2036           36 :          IF (ASSOCIATED(inp_info%nonbonded)) THEN
    2037           18 :             IF (ASSOCIATED(inp_info%nonbonded%pot)) THEN
    2038              :                ! Let's find the nonbonded potential where this atom is involved
    2039           18 :                only_manybody = .TRUE.
    2040           18 :                found_p = .FALSE.
    2041           30 :                DO j = 1, SIZE(inp_info%nonbonded%pot)
    2042           30 :                   IF (atmname == inp_info%nonbonded%pot(j)%pot%at1 .OR. &
    2043            0 :                       atmname == inp_info%nonbonded%pot(j)%pot%at2) THEN
    2044           18 :                      SELECT CASE (inp_info%nonbonded%pot(j)%pot%type(1))
    2045              :                      CASE (ea_type, tersoff_type, siepmann_type)
    2046              :                         ! Charge is zero for EAM, TERSOFF and SIEPMANN  type potential
    2047              :                         ! Do nothing..
    2048              :                      CASE DEFAULT
    2049              :                         only_manybody = .FALSE.
    2050           18 :                         EXIT
    2051              :                      END SELECT
    2052              :                      found_p = .TRUE.
    2053              :                   END IF
    2054              :                END DO
    2055           18 :                IF (only_manybody .AND. found_p) THEN
    2056            0 :                   charges(iatom) = 0.0_dp
    2057              :                END IF
    2058              :             END IF
    2059              :          END IF
    2060              : 
    2061              :          ! QM/MM modifications
    2062           80 :          IF (only_qm .AND. my_qmmm) THEN
    2063            6 :             IF (qmmm_env%qmmm_coupl_type /= do_qmmm_none) THEN
    2064            6 :                scale_factor = 0.0_dp
    2065            6 :                IF (is_link_atom) THEN
    2066              :                   ! Find the scaling factor...
    2067            0 :                   DO ilink = 1, SIZE(qmmm_env%mm_link_atoms)
    2068            0 :                      IF (iatom == qmmm_env%mm_link_atoms(ilink)) EXIT
    2069              :                   END DO
    2070            0 :                   CPASSERT(ilink <= SIZE(qmmm_env%mm_link_atoms))
    2071            0 :                   scale_factor = qmmm_env%fist_scale_charge_link(ilink)
    2072              :                END IF
    2073            6 :                charges(iatom) = charges(iatom)*scale_factor
    2074              :             END IF
    2075              :          END IF
    2076              :       END DO
    2077              : 
    2078              :       ! Sum up total charges for IO
    2079           44 :       charge_tot = SUM(charges)
    2080              : 
    2081              :       ! Print total charge of the system
    2082            8 :       IF (iw4 > 0) THEN
    2083              :          WRITE (UNIT=iw4, FMT="(/,T2,A,T61,F20.10)") &
    2084            4 :             "FORCEFIELD| Total charge of the classical system: ", charge_tot
    2085              :       END IF
    2086              : 
    2087            8 :       CALL timestop(handle)
    2088              : 
    2089           16 :    END SUBROUTINE force_field_pack_charges
    2090              : 
    2091              : ! **************************************************************************************************
    2092              : !> \brief Set up atomic_kind_set()%fist_potential%[qeff]
    2093              : !>      and shell potential parameters
    2094              : !> \param atomic_kind_set ...
    2095              : !> \param qmmm_env ...
    2096              : !> \param fatal ...
    2097              : !> \param iw ...
    2098              : !> \param iw4 ...
    2099              : !> \param Ainfo ...
    2100              : !> \param my_qmmm ...
    2101              : !> \param inp_info ...
    2102              : ! **************************************************************************************************
    2103         2637 :    SUBROUTINE force_field_pack_charge(atomic_kind_set, qmmm_env, fatal, iw, iw4, &
    2104              :                                       Ainfo, my_qmmm, inp_info)
    2105              : 
    2106              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2107              :       TYPE(qmmm_env_mm_type), POINTER                    :: qmmm_env
    2108              :       LOGICAL, INTENT(INOUT)                             :: fatal
    2109              :       INTEGER, INTENT(IN)                                :: iw, iw4
    2110              :       CHARACTER(LEN=default_string_length), &
    2111              :          DIMENSION(:), POINTER                           :: Ainfo
    2112              :       LOGICAL, INTENT(IN)                                :: my_qmmm
    2113              :       TYPE(input_info_type), POINTER                     :: inp_info
    2114              : 
    2115              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_charge'
    2116              : 
    2117              :       CHARACTER(LEN=default_string_length)               :: atmname
    2118              :       INTEGER                                            :: handle, i, ilink, j
    2119         2637 :       INTEGER, DIMENSION(:), POINTER                     :: my_atom_list
    2120              :       LOGICAL                                            :: found, found_p, is_link_atom, is_shell, &
    2121              :                                                             only_manybody, only_qm
    2122              :       REAL(KIND=dp)                                      :: charge, charge_tot, cs_charge, &
    2123              :                                                             scale_factor
    2124              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    2125              :       TYPE(fist_potential_type), POINTER                 :: fist_potential
    2126              : 
    2127         2637 :       CALL timeset(routineN, handle)
    2128              : 
    2129         2637 :       charge_tot = 0.0_dp
    2130              : 
    2131        13900 :       DO i = 1, SIZE(atomic_kind_set)
    2132        11263 :          atomic_kind => atomic_kind_set(i)
    2133              :          CALL get_atomic_kind(atomic_kind=atomic_kind, &
    2134              :                               fist_potential=fist_potential, &
    2135              :                               atom_list=my_atom_list, &
    2136        11263 :                               name=atmname)
    2137        11263 :          CALL get_potential(potential=fist_potential, qeff=charge)
    2138              : 
    2139        11263 :          is_shell = .FALSE.
    2140        11263 :          found = .FALSE.
    2141        11263 :          only_qm = qmmm_ff_precond_only_qm(id1=atmname, is_link=is_link_atom)
    2142        11263 :          CALL uppercase(atmname)
    2143        11263 :          IF (charge /= -HUGE(0.0_dp)) found = .TRUE.
    2144              : 
    2145              :          ! Always have the input param last to overwrite all the other ones
    2146        11263 :          IF (ASSOCIATED(inp_info%charge_atm)) THEN
    2147         5585 :             IF (iw > 0) WRITE (UNIT=iw, FMT="(A)") ""
    2148        27344 :             DO j = 1, SIZE(inp_info%charge_atm)
    2149              :                IF (debug_this_module) THEN
    2150              :                   IF (iw > 0) THEN
    2151              :                      WRITE (UNIT=iw, FMT="(T2,A)") &
    2152              :                         "Checking charges for the atomic kinds "// &
    2153              :                         TRIM(inp_info%charge_atm(j))//" and "//TRIM(atmname)
    2154              :                   END IF
    2155              :                END IF
    2156        27344 :                IF ((inp_info%charge_atm(j)) == atmname) THEN
    2157         5487 :                   charge = inp_info%charge(j)
    2158         5487 :                   CALL issue_duplications(found, "Charge", atmname)
    2159         5487 :                   found = .TRUE.
    2160              :                END IF
    2161              :             END DO
    2162              :          END IF
    2163              :          ! Check if the ATOM type has a core-shell associated.. In this case
    2164              :          ! print a warning: the CHARGE will not be used if defined.. or we can
    2165              :          ! even skip its definition..
    2166        11263 :          IF (ASSOCIATED(inp_info%shell_list)) THEN
    2167         1414 :             DO j = 1, SIZE(inp_info%shell_list)
    2168         1414 :                IF ((inp_info%shell_list(j)%atm_name) == atmname) THEN
    2169          448 :                   is_shell = .TRUE.
    2170              :                   cs_charge = inp_info%shell_list(j)%shell%charge_core + &
    2171          448 :                               inp_info%shell_list(j)%shell%charge_shell
    2172          448 :                   charge = 0.0_dp
    2173          448 :                   IF (found) THEN
    2174              :                      IF (found) &
    2175              :                         CALL cp_warn(__LOCATION__, &
    2176              :                                      "CORE-SHELL model defined for KIND ("//TRIM(atmname)//")"// &
    2177          204 :                                      " ignoring charge definition! ")
    2178              :                   ELSE
    2179          244 :                      found = .TRUE.
    2180              :                   END IF
    2181              :                END IF
    2182              :             END DO
    2183              :          END IF
    2184              :          ! Check if the potential really requires the charge definition..
    2185        11263 :          IF (ASSOCIATED(inp_info%nonbonded)) THEN
    2186         4351 :             IF (ASSOCIATED(inp_info%nonbonded%pot)) THEN
    2187              :                ! Let's find the nonbonded potential where this atom is involved
    2188         4351 :                only_manybody = .TRUE.
    2189         4351 :                found_p = .FALSE.
    2190         7887 :                DO j = 1, SIZE(inp_info%nonbonded%pot)
    2191         7684 :                   IF (atmname == inp_info%nonbonded%pot(j)%pot%at1 .OR. &
    2192          203 :                       atmname == inp_info%nonbonded%pot(j)%pot%at2) THEN
    2193         4344 :                      SELECT CASE (inp_info%nonbonded%pot(j)%pot%type(1))
    2194              :                      CASE (ea_type, tersoff_type, siepmann_type, nequip_type, &
    2195              :                            allegro_type, deepmd_type, ace_type)
    2196              :                         ! Charge is zero for EAM, TERSOFF and SIEPMANN type potential
    2197              :                         ! Do nothing..
    2198              :                      CASE DEFAULT
    2199              :                         only_manybody = .FALSE.
    2200         4344 :                         EXIT
    2201              :                      END SELECT
    2202              :                      found_p = .TRUE.
    2203              :                   END IF
    2204              :                END DO
    2205         4351 :                IF (only_manybody .AND. found_p) THEN
    2206          156 :                   charge = 0.0_dp
    2207          156 :                   found = .TRUE.
    2208              :                END IF
    2209              :             END IF
    2210              :          END IF
    2211        11263 :          IF (.NOT. found) THEN
    2212              :             ! Set the charge to zero anyway in case the user decides to ignore
    2213              :             ! missing critical parameters.
    2214           12 :             charge = 0.0_dp
    2215              :             CALL store_FF_missing_par(atm1=TRIM(atmname), &
    2216              :                                       fatal=fatal, &
    2217              :                                       type_name="Charge", &
    2218           12 :                                       array=Ainfo)
    2219              :          END IF
    2220              :          !
    2221              :          ! QM/MM modifications
    2222              :          !
    2223        11263 :          IF (only_qm .AND. my_qmmm) THEN
    2224         1286 :             IF (qmmm_env%qmmm_coupl_type /= do_qmmm_none) THEN
    2225         1076 :                scale_factor = 0.0_dp
    2226         1076 :                IF (is_link_atom) THEN
    2227              :                   !
    2228              :                   ! Find the scaling factor...
    2229              :                   !
    2230          386 :                   DO ilink = 1, SIZE(qmmm_env%mm_link_atoms)
    2231          658 :                      IF (ANY(my_atom_list == qmmm_env%mm_link_atoms(ilink))) EXIT
    2232              :                   END DO
    2233          114 :                   CPASSERT(ilink <= SIZE(qmmm_env%mm_link_atoms))
    2234          114 :                   scale_factor = qmmm_env%fist_scale_charge_link(ilink)
    2235              :                END IF
    2236         1076 :                charge = charge*scale_factor
    2237              :             END IF
    2238              :          END IF
    2239              : 
    2240        11263 :          CALL set_potential(potential=fist_potential, qeff=charge)
    2241              :          ! Sum up total charges for IO
    2242        13900 :          IF (found) THEN
    2243        11251 :             IF (is_shell) THEN
    2244          448 :                charge_tot = charge_tot + atomic_kind%natom*cs_charge
    2245              :             ELSE
    2246        10803 :                charge_tot = charge_tot + atomic_kind%natom*charge
    2247              :             END IF
    2248              :          END IF
    2249              :       END DO
    2250              : 
    2251              :       ! Print total charge of the system
    2252         2637 :       IF (iw4 > 0) THEN
    2253              :          WRITE (UNIT=iw4, FMT="(/,T2,A,T61,F20.10)") &
    2254         1302 :             "FORCEFIELD| Total charge of the classical system: ", charge_tot
    2255              :       END IF
    2256              : 
    2257         2637 :       CALL timestop(handle)
    2258              : 
    2259         2637 :    END SUBROUTINE force_field_pack_charge
    2260              : 
    2261              : ! **************************************************************************************************
    2262              : !> \brief Set up the radius of the electrostatic multipole in Fist
    2263              : !> \param atomic_kind_set ...
    2264              : !> \param iw ...
    2265              : !> \param subsys_section ...
    2266              : !> \author Toon.Verstraelen@gmail.com
    2267              : ! **************************************************************************************************
    2268         5290 :    SUBROUTINE force_field_pack_radius(atomic_kind_set, iw, subsys_section)
    2269              : 
    2270              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2271              :       INTEGER, INTENT(IN)                                :: iw
    2272              :       TYPE(section_vals_type), POINTER                   :: subsys_section
    2273              : 
    2274              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_radius'
    2275              : 
    2276              :       CHARACTER(LEN=default_string_length)               :: inp_kind_name, kind_name
    2277              :       INTEGER                                            :: handle, i, i_rep, n_rep
    2278              :       LOGICAL                                            :: found
    2279              :       REAL(KIND=dp)                                      :: mm_radius
    2280              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    2281              :       TYPE(fist_potential_type), POINTER                 :: fist_potential
    2282              :       TYPE(section_vals_type), POINTER                   :: kind_section
    2283              : 
    2284         2645 :       CALL timeset(routineN, handle)
    2285              : 
    2286         2645 :       kind_section => section_vals_get_subs_vals(subsys_section, "KIND")
    2287         2645 :       CALL section_vals_get(kind_section, n_repetition=n_rep)
    2288              : 
    2289        13928 :       DO i = 1, SIZE(atomic_kind_set)
    2290        11283 :          atomic_kind => atomic_kind_set(i)
    2291              :          CALL get_atomic_kind(atomic_kind=atomic_kind, &
    2292        11283 :                               fist_potential=fist_potential, name=kind_name)
    2293        11283 :          CALL uppercase(kind_name)
    2294        11283 :          found = .FALSE.
    2295              : 
    2296              :          ! Try to find a matching KIND section in the SUBSYS section and read the
    2297              :          ! MM_RADIUS field if it is present. In case the kind section is never
    2298              :          ! encountered, the mm_radius remains zero.
    2299        11283 :          IF (iw > 0) WRITE (UNIT=iw, FMT="(A)") ""
    2300        11283 :          mm_radius = 0.0_dp
    2301        39572 :          DO i_rep = 1, n_rep
    2302              :             CALL section_vals_val_get(kind_section, "_SECTION_PARAMETERS_", &
    2303        28289 :                                       c_val=inp_kind_name, i_rep_section=i_rep)
    2304        28289 :             CALL uppercase(inp_kind_name)
    2305        28289 :             IF (iw > 0) THEN
    2306              :                WRITE (UNIT=iw, FMT="(T2,A)") &
    2307              :                   "FORCEFIELD| Matching atomic kinds "//TRIM(kind_name)// &
    2308          905 :                   " and "//TRIM(inp_kind_name)//" for MM_RADIUS"
    2309              :             END IF
    2310        39572 :             IF (TRIM(kind_name) == TRIM(inp_kind_name)) THEN
    2311              :                CALL section_vals_val_get(kind_section, i_rep_section=i_rep, &
    2312         1839 :                                          keyword_name="MM_RADIUS", r_val=mm_radius)
    2313         1839 :                CALL issue_duplications(found, "MM_RADIUS", kind_name)
    2314         1839 :                found = .TRUE.
    2315              :             END IF
    2316              :          END DO
    2317        13928 :          CALL set_potential(potential=fist_potential, mm_radius=mm_radius)
    2318              :       END DO
    2319              : 
    2320         2645 :       CALL timestop(handle)
    2321              : 
    2322         2645 :    END SUBROUTINE force_field_pack_radius
    2323              : 
    2324              : ! **************************************************************************************************
    2325              : !> \brief Set up the polarizable FF parameters
    2326              : !> \param atomic_kind_set ...
    2327              : !> \param iw ...
    2328              : !> \param inp_info ...
    2329              : !> \author Toon.Verstraelen@gmail.com
    2330              : ! **************************************************************************************************
    2331         2645 :    SUBROUTINE force_field_pack_pol(atomic_kind_set, iw, inp_info)
    2332              : 
    2333              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2334              :       INTEGER, INTENT(IN)                                :: iw
    2335              :       TYPE(input_info_type), POINTER                     :: inp_info
    2336              : 
    2337              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_pol'
    2338              : 
    2339              :       CHARACTER(LEN=default_string_length)               :: kind_name
    2340              :       INTEGER                                            :: handle, i, j
    2341              :       LOGICAL                                            :: found
    2342              :       REAL(KIND=dp)                                      :: apol, cpol
    2343              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    2344              :       TYPE(fist_potential_type), POINTER                 :: fist_potential
    2345              : 
    2346         2645 :       CALL timeset(routineN, handle)
    2347              : 
    2348         2645 :       IF (iw > 0) THEN
    2349              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
    2350          239 :             "FORCEFIELD| Checking for polarisable forcefield terms"
    2351              :       END IF
    2352              : 
    2353        13928 :       DO i = 1, SIZE(atomic_kind_set)
    2354        11283 :          atomic_kind => atomic_kind_set(i)
    2355              :          CALL get_atomic_kind(atomic_kind=atomic_kind, &
    2356              :                               fist_potential=fist_potential, &
    2357        11283 :                               name=kind_name)
    2358        11283 :          CALL get_potential(potential=fist_potential, apol=apol, cpol=cpol)
    2359        11283 :          CALL uppercase(kind_name)
    2360        11283 :          found = .FALSE.
    2361              : 
    2362        11283 :          IF (iw > 0) WRITE (UNIT=iw, FMT="(A)") ""
    2363              :          ! Always have the input param last to overwrite all the other ones
    2364        11283 :          IF (ASSOCIATED(inp_info%apol_atm)) THEN
    2365          292 :             DO j = 1, SIZE(inp_info%apol_atm)
    2366          200 :                IF (iw > 0) THEN
    2367              :                   WRITE (UNIT=iw, FMT="(T2,A)") &
    2368              :                      "FORCEFIELD| Matching atomic kinds "//TRIM(kind_name)// &
    2369            0 :                      " and "//TRIM(inp_info%apol_atm(j))//" for APOL"
    2370              :                END IF
    2371          292 :                IF ((inp_info%apol_atm(j)) == kind_name) THEN
    2372           64 :                   apol = inp_info%apol(j)
    2373           64 :                   CALL issue_duplications(found, "APOL", kind_name)
    2374           64 :                   found = .TRUE.
    2375              :                END IF
    2376              :             END DO
    2377              :          END IF
    2378              : 
    2379        11283 :          IF (ASSOCIATED(inp_info%cpol_atm)) THEN
    2380            0 :             DO j = 1, SIZE(inp_info%cpol_atm)
    2381            0 :                IF (iw > 0) THEN
    2382              :                   WRITE (UNIT=iw, FMT="(T2,A)") &
    2383              :                      "FORCEFIELD| Matching atomic kinds "//TRIM(kind_name)// &
    2384            0 :                      " and "//TRIM(inp_info%cpol_atm(j))//" for CPOL"
    2385              :                END IF
    2386            0 :                IF ((inp_info%cpol_atm(j)) == kind_name) THEN
    2387            0 :                   cpol = inp_info%cpol(j)
    2388            0 :                   CALL issue_duplications(found, "CPOL", kind_name)
    2389            0 :                   found = .TRUE.
    2390              :                END IF
    2391              :             END DO
    2392              :          END IF
    2393              : 
    2394        13928 :          CALL set_potential(potential=fist_potential, apol=apol, cpol=cpol)
    2395              : 
    2396              :       END DO
    2397              : 
    2398         2645 :       CALL timestop(handle)
    2399              : 
    2400         2645 :    END SUBROUTINE force_field_pack_pol
    2401              : 
    2402              : ! **************************************************************************************************
    2403              : !> \brief Set up damping parameters
    2404              : !> \param atomic_kind_set ...
    2405              : !> \param iw ...
    2406              : !> \param inp_info ...
    2407              : ! **************************************************************************************************
    2408         2645 :    SUBROUTINE force_field_pack_damp(atomic_kind_set, iw, inp_info)
    2409              : 
    2410              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2411              :       INTEGER                                            :: iw
    2412              :       TYPE(input_info_type), POINTER                     :: inp_info
    2413              : 
    2414              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_damp'
    2415              : 
    2416              :       CHARACTER(len=default_string_length)               :: atm_name1, atm_name2, my_atm_name1, &
    2417              :                                                             my_atm_name2
    2418              :       INTEGER                                            :: handle2, i, j, k, nkinds
    2419              :       LOGICAL                                            :: found
    2420              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind, atomic_kind2
    2421              :       TYPE(damping_p_type), POINTER                      :: damping
    2422              : 
    2423         2645 :       CALL timeset(routineN, handle2)
    2424              : 
    2425         2645 :       IF (iw > 0) THEN
    2426              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
    2427          239 :             "FORCEFIELD| Checking for damping terms"
    2428              :       END IF
    2429              : 
    2430         2645 :       NULLIFY (damping)
    2431         2645 :       nkinds = SIZE(atomic_kind_set)
    2432              : 
    2433        13928 :       DO j = 1, SIZE(atomic_kind_set)
    2434              : 
    2435        11283 :          atomic_kind => atomic_kind_set(j)
    2436              : 
    2437              :          CALL get_atomic_kind(atomic_kind=atomic_kind, &
    2438        11283 :                               name=atm_name1)
    2439        11283 :          CALL uppercase(atm_name1)
    2440              : 
    2441        11283 :          IF (ASSOCIATED(inp_info%damping_list)) THEN
    2442           50 :             DO i = 1, SIZE(inp_info%damping_list)
    2443           28 :                my_atm_name1 = inp_info%damping_list(i)%atm_name1
    2444           28 :                my_atm_name2 = inp_info%damping_list(i)%atm_name2
    2445              :                IF (debug_this_module) THEN
    2446              :                   IF (iw > 0) THEN
    2447              :                      WRITE (UNIT=iw, FMT="(T2,A)") &
    2448              :                         "FORCEFIELD| Check damping for the atomic kinds "// &
    2449              :                         TRIM(my_atm_name1)//" and "//TRIM(atm_name1)
    2450              :                   END IF
    2451              :                END IF
    2452           50 :                IF (my_atm_name1 == atm_name1) THEN
    2453           12 :                   IF (.NOT. ASSOCIATED(damping)) THEN
    2454           10 :                      CALL damping_p_create(damping, nkinds)
    2455              :                   END IF
    2456           12 :                   found = .FALSE.
    2457           40 :                   DO k = 1, SIZE(atomic_kind_set)
    2458           28 :                      atomic_kind2 => atomic_kind_set(k)
    2459              :                      CALL get_atomic_kind(atomic_kind=atomic_kind2, &
    2460           28 :                                           name=atm_name2)
    2461           28 :                      CALL uppercase(atm_name2)
    2462           40 :                      IF (my_atm_name2 == atm_name2) THEN
    2463           12 :                         IF (damping%damp(k)%bij /= HUGE(0.0_dp)) found = .TRUE.
    2464           12 :                         CALL issue_duplications(found, "Damping", atm_name1)
    2465           12 :                         found = .TRUE.
    2466           24 :                         SELECT CASE (TRIM(inp_info%damping_list(i)%dtype))
    2467              :                         CASE ('TANG-TOENNIES')
    2468           12 :                            damping%damp(k)%itype = tang_toennies
    2469              :                         CASE DEFAULT
    2470           24 :                            CPABORT("Unknown damping type.")
    2471              :                         END SELECT
    2472           12 :                         damping%damp(k)%order = inp_info%damping_list(i)%order
    2473           12 :                         damping%damp(k)%bij = inp_info%damping_list(i)%bij
    2474           12 :                         damping%damp(k)%cij = inp_info%damping_list(i)%cij
    2475              :                      END IF
    2476              :                   END DO
    2477           12 :                   IF (.NOT. found) THEN
    2478              :                      CALL cp_warn(__LOCATION__, &
    2479              :                                   "Atom "//TRIM(my_atm_name2)// &
    2480              :                                   " in damping parameters for atom "//TRIM(my_atm_name1)// &
    2481            0 :                                   " not found.")
    2482              :                   END IF
    2483              :                END IF
    2484              :             END DO
    2485              :          END IF
    2486              : 
    2487        11283 :          CALL set_atomic_kind(atomic_kind=atomic_kind, damping=damping)
    2488              : 
    2489        13928 :          NULLIFY (damping)
    2490              : 
    2491              :       END DO
    2492              : 
    2493         2645 :       CALL timestop(handle2)
    2494              : 
    2495         2645 :    END SUBROUTINE force_field_pack_damp
    2496              : 
    2497              : ! **************************************************************************************************
    2498              : !> \brief Set up shell potential parameters
    2499              : !> \param particle_set ...
    2500              : !> \param atomic_kind_set ...
    2501              : !> \param molecule_kind_set ...
    2502              : !> \param molecule_set ...
    2503              : !> \param root_section ...
    2504              : !> \param subsys_section ...
    2505              : !> \param shell_particle_set ...
    2506              : !> \param core_particle_set ...
    2507              : !> \param cell ...
    2508              : !> \param iw ...
    2509              : !> \param inp_info ...
    2510              : ! **************************************************************************************************
    2511        13225 :    SUBROUTINE force_field_pack_shell(particle_set, atomic_kind_set, &
    2512              :                                      molecule_kind_set, molecule_set, root_section, subsys_section, &
    2513              :                                      shell_particle_set, core_particle_set, cell, iw, inp_info)
    2514              : 
    2515              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2516              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2517              :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
    2518              :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
    2519              :       TYPE(section_vals_type), POINTER                   :: root_section, subsys_section
    2520              :       TYPE(particle_type), DIMENSION(:), POINTER         :: shell_particle_set, core_particle_set
    2521              :       TYPE(cell_type), POINTER                           :: cell
    2522              :       INTEGER                                            :: iw
    2523              :       TYPE(input_info_type), POINTER                     :: inp_info
    2524              : 
    2525              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_shell'
    2526              : 
    2527              :       CHARACTER(LEN=default_string_length)               :: atmname
    2528              :       INTEGER                                            :: counter, first, first_shell, handle2, i, &
    2529              :                                                             j, last, last_shell, n, natom, nmol, &
    2530              :                                                             nshell_tot
    2531         2645 :       INTEGER, DIMENSION(:), POINTER                     :: molecule_list, shell_list_tmp
    2532              :       LOGICAL :: core_coord_read, found_shell, is_a_shell, is_link_atom, null_massfrac, only_qm, &
    2533              :          save_mem, shell_adiabatic, shell_coord_read
    2534              :       REAL(KIND=dp)                                      :: atmmass
    2535              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    2536              :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
    2537              :       TYPE(molecule_type), POINTER                       :: molecule
    2538              :       TYPE(section_vals_type), POINTER                   :: global_section
    2539              :       TYPE(shell_kind_type), POINTER                     :: shell
    2540         2645 :       TYPE(shell_type), DIMENSION(:), POINTER            :: shell_list
    2541              : 
    2542         2645 :       CALL timeset(routineN, handle2)
    2543              : 
    2544         2645 :       nshell_tot = 0
    2545         2645 :       n = 0
    2546         2645 :       first_shell = 1
    2547         2645 :       null_massfrac = .FALSE.
    2548         2645 :       core_coord_read = .FALSE.
    2549         2645 :       shell_coord_read = .FALSE.
    2550              : 
    2551         2645 :       NULLIFY (global_section)
    2552         2645 :       global_section => section_vals_get_subs_vals(root_section, "GLOBAL")
    2553         2645 :       CALL section_vals_val_get(global_section, "SAVE_MEM", l_val=save_mem)
    2554              : 
    2555         2645 :       IF (iw > 0) THEN
    2556              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
    2557          239 :             "FORCEFIELD| Checking for core-shell terms"
    2558              :       END IF
    2559              : 
    2560        13928 :       DO i = 1, SIZE(atomic_kind_set)
    2561        11283 :          atomic_kind => atomic_kind_set(i)
    2562              :          CALL get_atomic_kind(atomic_kind=atomic_kind, &
    2563        11283 :                               name=atmname)
    2564              : 
    2565        11283 :          found_shell = .FALSE.
    2566        11283 :          only_qm = qmmm_ff_precond_only_qm(id1=atmname, is_link=is_link_atom)
    2567        11283 :          CALL uppercase(atmname)
    2568              : 
    2569              :          ! The shell potential can be defined only from input
    2570        13928 :          IF (ASSOCIATED(inp_info%shell_list)) THEN
    2571         1414 :             DO j = 1, SIZE(inp_info%shell_list)
    2572              :                IF (debug_this_module) THEN
    2573              :                   IF (iw > 0) THEN
    2574              :                      WRITE (UNIT=iw, FMT="(T2,A)") &
    2575              :                         "Checking shells for the atomic kinds "// &
    2576              :                         TRIM(inp_info%shell_list(j)%atm_name)//" and "//TRIM(atmname)
    2577              :                   END IF
    2578              :                END IF
    2579         1414 :                IF ((inp_info%shell_list(j)%atm_name) == atmname) THEN
    2580              :                   CALL get_atomic_kind(atomic_kind=atomic_kind, &
    2581          448 :                                        shell=shell, mass=atmmass, natom=natom)
    2582          448 :                   IF (.NOT. ASSOCIATED(shell)) ALLOCATE (shell)
    2583          448 :                   nshell_tot = nshell_tot + natom
    2584          448 :                   shell%charge_core = inp_info%shell_list(j)%shell%charge_core
    2585          448 :                   shell%charge_shell = inp_info%shell_list(j)%shell%charge_shell
    2586          448 :                   shell%massfrac = inp_info%shell_list(j)%shell%massfrac
    2587          448 :                   IF (shell%massfrac < EPSILON(1.0_dp)) null_massfrac = .TRUE.
    2588          448 :                   shell%k2_spring = inp_info%shell_list(j)%shell%k2_spring
    2589          448 :                   shell%k4_spring = inp_info%shell_list(j)%shell%k4_spring
    2590          448 :                   shell%max_dist = inp_info%shell_list(j)%shell%max_dist
    2591          448 :                   shell%shell_cutoff = inp_info%shell_list(j)%shell%shell_cutoff
    2592          448 :                   shell%mass_shell = shell%massfrac*atmmass
    2593          448 :                   shell%mass_core = atmmass - shell%mass_shell
    2594          448 :                   CALL issue_duplications(found_shell, "Shell", atmname)
    2595          448 :                   found_shell = .TRUE.
    2596              :                   CALL set_atomic_kind(atomic_kind=atomic_kind, &
    2597          448 :                                        shell=shell, shell_active=.TRUE.)
    2598              :                END IF
    2599              :             END DO ! shell kind
    2600              :          END IF ! associated shell_list
    2601              :       END DO ! atomic kind
    2602              : 
    2603         2645 :       IF (iw > 0) THEN
    2604              :          WRITE (UNIT=iw, FMT="(/,T2,A,T61,I20)") &
    2605          239 :             "FORCEFIELD| Total number of particles with a shell:", nshell_tot
    2606              :       END IF
    2607              :       ! If shell-model is present: Create particle_set of shells (coord. vel. force)
    2608         2645 :       NULLIFY (shell_particle_set)
    2609         2645 :       NULLIFY (core_particle_set)
    2610         2645 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, shell_adiabatic=shell_adiabatic)
    2611         2645 :       IF (nshell_tot > 0) THEN
    2612          256 :          IF (shell_adiabatic .AND. null_massfrac) THEN
    2613            0 :             CPABORT("Shell-model adiabatic: at least one shell_kind has mass zero")
    2614              :          END IF
    2615          256 :          CALL allocate_particle_set(shell_particle_set, nshell_tot)
    2616          256 :          CALL allocate_particle_set(core_particle_set, nshell_tot)
    2617          256 :          counter = 0
    2618              :          ! Initialise the shell (and core) coordinates with the particle (atomic) coordinates,
    2619              :          ! count the shell and set pointers
    2620        28934 :          DO i = 1, SIZE(particle_set)
    2621        28678 :             NULLIFY (atomic_kind)
    2622        28678 :             NULLIFY (shell)
    2623        28678 :             atomic_kind => particle_set(i)%atomic_kind
    2624        28678 :             CALL get_atomic_kind(atomic_kind=atomic_kind, shell_active=is_a_shell)
    2625        28934 :             IF (is_a_shell) THEN
    2626        28070 :                counter = counter + 1
    2627        28070 :                particle_set(i)%shell_index = counter
    2628        28070 :                shell_particle_set(counter)%shell_index = counter
    2629        28070 :                shell_particle_set(counter)%atomic_kind => particle_set(i)%atomic_kind
    2630       196490 :                shell_particle_set(counter)%r(1:3) = particle_set(i)%r(1:3)
    2631        28070 :                shell_particle_set(counter)%atom_index = i
    2632        28070 :                core_particle_set(counter)%shell_index = counter
    2633        28070 :                core_particle_set(counter)%atomic_kind => particle_set(i)%atomic_kind
    2634       196490 :                core_particle_set(counter)%r(1:3) = particle_set(i)%r(1:3)
    2635        28070 :                core_particle_set(counter)%atom_index = i
    2636              :             ELSE
    2637          608 :                particle_set(i)%shell_index = 0
    2638              :             END IF
    2639              :          END DO
    2640          256 :          CPASSERT(counter == nshell_tot)
    2641              :       END IF
    2642              : 
    2643              :       ! Read the shell (and core) coordinates from the restart file, if available
    2644              :       CALL read_binary_cs_coordinates("SHELL", shell_particle_set, root_section, &
    2645         2645 :                                       subsys_section, shell_coord_read)
    2646              :       CALL read_binary_cs_coordinates("CORE", core_particle_set, root_section, &
    2647         2645 :                                       subsys_section, core_coord_read)
    2648              : 
    2649         2645 :       IF (nshell_tot > 0) THEN
    2650              :          ! Read the shell (and core) coordinates from the input, if no coordinates were found
    2651              :          ! in the restart file
    2652          256 :          IF (shell_adiabatic) THEN
    2653          256 :             IF (.NOT. (core_coord_read .AND. shell_coord_read)) THEN
    2654              :                CALL read_shell_coord_input(particle_set, shell_particle_set, cell, &
    2655              :                                            subsys_section, core_particle_set, &
    2656          240 :                                            save_mem=save_mem)
    2657              :             END IF
    2658              :          ELSE
    2659            0 :             IF (.NOT. shell_coord_read) THEN
    2660              :                CALL read_shell_coord_input(particle_set, shell_particle_set, cell, &
    2661            0 :                                            subsys_section, save_mem=save_mem)
    2662              :             END IF
    2663              :          END IF
    2664              :          ! Determine the number of shells per molecule kind
    2665          256 :          n = 0
    2666        11548 :          DO i = 1, SIZE(molecule_kind_set)
    2667        11292 :             molecule_kind => molecule_kind_set(i)
    2668              :             CALL get_molecule_kind(molecule_kind=molecule_kind, molecule_list=molecule_list, &
    2669        11292 :                                    natom=natom, nmolecule=nmol)
    2670        11292 :             molecule => molecule_set(molecule_list(1))
    2671        11292 :             CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
    2672        33876 :             ALLOCATE (shell_list_tmp(natom))
    2673        11292 :             counter = 0
    2674        23562 :             DO j = first, last
    2675        12270 :                atomic_kind => particle_set(j)%atomic_kind
    2676        12270 :                CALL get_atomic_kind(atomic_kind=atomic_kind, shell_active=is_a_shell)
    2677        23562 :                IF (is_a_shell) THEN
    2678        11804 :                   counter = counter + 1
    2679        11804 :                   shell_list_tmp(counter) = j - first + 1
    2680        11804 :                   first_shell = MIN(first_shell, MAX(1, particle_set(j)%shell_index))
    2681              :                END IF
    2682              :             END DO ! j atom in molecule_kind i, molecule 1 of the molecule_list
    2683        11292 :             IF (counter /= 0) THEN
    2684              :                ! Setup of fist_shell and last_shell for all molecules..
    2685        29288 :                DO j = 1, SIZE(molecule_list)
    2686        18414 :                   last_shell = first_shell + counter - 1
    2687        18414 :                   molecule => molecule_set(molecule_list(j))
    2688        18414 :                   molecule%first_shell = first_shell
    2689        18414 :                   molecule%last_shell = last_shell
    2690        29288 :                   first_shell = last_shell + 1
    2691              :                END DO
    2692              :                ! Setup of shell_list
    2693        10874 :                CALL get_molecule_kind(molecule_kind=molecule_kind, shell_list=shell_list)
    2694        10874 :                IF (ASSOCIATED(shell_list)) THEN
    2695            0 :                   DEALLOCATE (shell_list)
    2696              :                END IF
    2697        44426 :                ALLOCATE (shell_list(counter))
    2698        22678 :                DO j = 1, counter
    2699        11804 :                   shell_list(j)%a = shell_list_tmp(j)
    2700        11804 :                   atomic_kind => particle_set(shell_list_tmp(j) + first - 1)%atomic_kind
    2701        11804 :                   CALL get_atomic_kind(atomic_kind=atomic_kind, name=atmname, shell=shell)
    2702        11804 :                   CALL uppercase(atmname)
    2703        11804 :                   shell_list(j)%name = atmname
    2704        22678 :                   shell_list(j)%shell_kind => shell
    2705              :                END DO
    2706        10874 :                CALL set_molecule_kind(molecule_kind=molecule_kind, nshell=counter, shell_list=shell_list)
    2707              :             END IF
    2708        11292 :             DEALLOCATE (shell_list_tmp)
    2709        22840 :             n = n + nmol*counter
    2710              :          END DO ! i molecule kind
    2711              :       END IF
    2712              : 
    2713         2645 :       CPASSERT(first_shell - 1 == nshell_tot)
    2714         2645 :       CPASSERT(n == nshell_tot)
    2715              : 
    2716         2645 :       CALL timestop(handle2)
    2717              : 
    2718         2645 :    END SUBROUTINE force_field_pack_shell
    2719              : 
    2720              : ! **************************************************************************************************
    2721              : !> \brief Assign input and potential info to potparm_nonbond14
    2722              : !> \param atomic_kind_set ...
    2723              : !> \param ff_type ...
    2724              : !> \param qmmm_env ...
    2725              : !> \param iw ...
    2726              : !> \param Ainfo ...
    2727              : !> \param chm_info ...
    2728              : !> \param inp_info ...
    2729              : !> \param gro_info ...
    2730              : !> \param amb_info ...
    2731              : !> \param potparm_nonbond14 ...
    2732              : !> \param ewald_env ...
    2733              : ! **************************************************************************************************
    2734         2629 :    SUBROUTINE force_field_pack_nonbond14(atomic_kind_set, ff_type, qmmm_env, iw, &
    2735              :                                          Ainfo, chm_info, inp_info, gro_info, amb_info, potparm_nonbond14, ewald_env)
    2736              : 
    2737              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2738              :       TYPE(force_field_type), INTENT(INOUT)              :: ff_type
    2739              :       TYPE(qmmm_env_mm_type), POINTER                    :: qmmm_env
    2740              :       INTEGER                                            :: iw
    2741              :       CHARACTER(LEN=default_string_length), &
    2742              :          DIMENSION(:), POINTER                           :: Ainfo
    2743              :       TYPE(charmm_info_type), POINTER                    :: chm_info
    2744              :       TYPE(input_info_type), POINTER                     :: inp_info
    2745              :       TYPE(gromos_info_type), POINTER                    :: gro_info
    2746              :       TYPE(amber_info_type), POINTER                     :: amb_info
    2747              :       TYPE(pair_potential_pp_type), POINTER              :: potparm_nonbond14
    2748              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    2749              : 
    2750              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_nonbond14'
    2751              : 
    2752              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_a_local, &
    2753              :                                                             name_atm_b, name_atm_b_local
    2754              :       INTEGER                                            :: handle2, i, ii, j, jj, k, match_names
    2755              :       LOGICAL                                            :: found, found_a, found_b, only_qm, &
    2756              :                                                             use_qmmm_ff
    2757              :       REAL(KIND=dp)                                      :: epsilon0, epsilon_a, epsilon_b, &
    2758              :                                                             ewald_rcut, rmin, rmin2_a, rmin2_b
    2759              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    2760              :       TYPE(pair_potential_single_type), POINTER          :: pot
    2761              : 
    2762         2629 :       CALL timeset(routineN, handle2)
    2763              : 
    2764         2629 :       use_qmmm_ff = qmmm_env%use_qmmm_ff
    2765         2629 :       NULLIFY (pot)
    2766              : 
    2767         2629 :       IF (iw > 0) THEN
    2768              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
    2769          238 :             "FORCEFIELD| Checking for nonbonded14 terms"
    2770              :       END IF
    2771              : 
    2772         2629 :       CALL ewald_env_get(ewald_env, rcut=ewald_rcut)
    2773         2629 :       CALL pair_potential_pp_create(potparm_nonbond14, SIZE(atomic_kind_set))
    2774              : 
    2775        13838 :       DO i = 1, SIZE(atomic_kind_set)
    2776        11209 :          atomic_kind => atomic_kind_set(i)
    2777        11209 :          CALL get_atomic_kind(atomic_kind=atomic_kind, name=name_atm_a_local)
    2778       271558 :          DO j = i, SIZE(atomic_kind_set)
    2779       257720 :             atomic_kind => atomic_kind_set(j)
    2780       257720 :             CALL get_atomic_kind(atomic_kind=atomic_kind, name=name_atm_b_local)
    2781       257720 :             found = .FALSE.
    2782       257720 :             found_a = .FALSE.
    2783       257720 :             found_b = .FALSE.
    2784       257720 :             name_atm_a = name_atm_a_local
    2785       257720 :             name_atm_b = name_atm_b_local
    2786       257720 :             only_qm = qmmm_ff_precond_only_qm(id1=name_atm_a, id2=name_atm_b)
    2787       257720 :             CALL uppercase(name_atm_a)
    2788       257720 :             CALL uppercase(name_atm_b)
    2789       257720 :             pot => potparm_nonbond14%pot(i, j)%pot
    2790              : 
    2791              :             ! loop over params from GROMOS
    2792       257720 :             IF (ASSOCIATED(gro_info%nonbond_a_14)) THEN
    2793          540 :                ii = 0
    2794          540 :                jj = 0
    2795         1800 :                DO k = 1, SIZE(gro_info%nonbond_a_14)
    2796         1800 :                   IF (TRIM(name_atm_a) == TRIM(gro_info%nonbond_a_14(k))) THEN
    2797              :                      ii = k
    2798              :                      found_a = .TRUE.
    2799              :                      EXIT
    2800              :                   END IF
    2801              :                END DO
    2802         2364 :                DO k = 1, SIZE(gro_info%nonbond_a_14)
    2803         2364 :                   IF (TRIM(name_atm_b) == TRIM(gro_info%nonbond_a_14(k))) THEN
    2804              :                      jj = k
    2805              :                      found_b = .TRUE.
    2806              :                      EXIT
    2807              :                   END IF
    2808              :                END DO
    2809          540 :                IF (ii /= 0 .AND. jj /= 0) THEN
    2810          540 :                   CALL pair_potential_lj_create(pot%set(1)%lj)
    2811         1080 :                   pot%type = lj_type
    2812          540 :                   pot%at1 = name_atm_a
    2813          540 :                   pot%at2 = name_atm_b
    2814          540 :                   pot%set(1)%lj%epsilon = 1.0_dp
    2815          540 :                   pot%set(1)%lj%sigma6 = gro_info%nonbond_c6_14(ii, jj)
    2816          540 :                   pot%set(1)%lj%sigma12 = gro_info%nonbond_c12_14(ii, jj)
    2817          540 :                   pot%rcutsq = (10.0_dp*bohr)**2
    2818          540 :                   CALL issue_duplications(found, "Lennard-Jones", name_atm_a, name_atm_b)
    2819          540 :                   found = .TRUE.
    2820              :                END IF
    2821              :             END IF
    2822              : 
    2823              :             ! Loop over params from CHARMM
    2824       257720 :             ii = 0
    2825       257720 :             jj = 0
    2826       257720 :             IF (ASSOCIATED(chm_info%nonbond_a_14)) THEN
    2827       460416 :                DO k = 1, SIZE(chm_info%nonbond_a_14)
    2828       460416 :                   IF ((name_atm_a) == (chm_info%nonbond_a_14(k))) THEN
    2829        11206 :                      ii = k
    2830        11206 :                      rmin2_a = chm_info%nonbond_rmin2_14(k)
    2831        11206 :                      epsilon_a = chm_info%nonbond_eps_14(k)
    2832        11206 :                      found_a = .TRUE.
    2833              :                   END IF
    2834              :                END DO
    2835       460416 :                DO k = 1, SIZE(chm_info%nonbond_a_14)
    2836       460416 :                   IF ((name_atm_b) == (chm_info%nonbond_a_14(k))) THEN
    2837         8888 :                      jj = k
    2838         8888 :                      rmin2_b = chm_info%nonbond_rmin2_14(k)
    2839         8888 :                      epsilon_b = chm_info%nonbond_eps_14(k)
    2840         8888 :                      found_b = .TRUE.
    2841              :                   END IF
    2842              :                END DO
    2843              :             END IF
    2844       257720 :             IF (ASSOCIATED(chm_info%nonbond_a)) THEN
    2845        48317 :                IF (.NOT. found_a) THEN
    2846      1442209 :                   DO k = 1, SIZE(chm_info%nonbond_a)
    2847      1442209 :                      IF ((name_atm_a) == (chm_info%nonbond_a(k))) THEN
    2848        37045 :                         ii = k
    2849        37045 :                         rmin2_a = chm_info%nonbond_rmin2(k)
    2850        37045 :                         epsilon_a = chm_info%nonbond_eps(k)
    2851              :                      END IF
    2852              :                   END DO
    2853              :                END IF
    2854        48317 :                IF (.NOT. found_b) THEN
    2855      1655119 :                   DO k = 1, SIZE(chm_info%nonbond_a)
    2856      1655119 :                      IF ((name_atm_b) == (chm_info%nonbond_a(k))) THEN
    2857        39411 :                         jj = k
    2858        39411 :                         rmin2_b = chm_info%nonbond_rmin2(k)
    2859        39411 :                         epsilon_b = chm_info%nonbond_eps(k)
    2860              :                      END IF
    2861              :                   END DO
    2862              :                END IF
    2863              :             END IF
    2864       257720 :             IF (ii /= 0 .AND. jj /= 0) THEN
    2865        48251 :                rmin = rmin2_a + rmin2_b
    2866              :                ! ABS to allow for mixing the two different sign conventions for epsilon
    2867        48251 :                epsilon0 = SQRT(ABS(epsilon_a*epsilon_b))
    2868        48251 :                CALL pair_potential_lj_create(pot%set(1)%lj)
    2869        96502 :                pot%type = lj_charmm_type
    2870        48251 :                pot%at1 = name_atm_a
    2871        48251 :                pot%at2 = name_atm_b
    2872        48251 :                pot%set(1)%lj%epsilon = epsilon0
    2873        48251 :                pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
    2874        48251 :                pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
    2875        48251 :                pot%rcutsq = (10.0_dp*bohr)**2
    2876        48251 :                CALL issue_duplications(found, "Lennard-Jones", name_atm_a, name_atm_b)
    2877        48251 :                found = .TRUE.
    2878              :             END IF
    2879              : 
    2880              :             ! Loop over params from AMBER
    2881       257720 :             IF (ASSOCIATED(amb_info%nonbond_a)) THEN
    2882       199334 :                ii = 0
    2883       199334 :                jj = 0
    2884       199334 :                IF (.NOT. found_a) THEN
    2885     45258092 :                   DO k = 1, SIZE(amb_info%nonbond_a)
    2886     45258092 :                      IF ((name_atm_a) == (amb_info%nonbond_a(k))) THEN
    2887       199334 :                         ii = k
    2888       199334 :                         rmin2_a = amb_info%nonbond_rmin2(k)
    2889       199334 :                         epsilon_a = amb_info%nonbond_eps(k)
    2890              :                      END IF
    2891              :                   END DO
    2892              :                END IF
    2893       199334 :                IF (.NOT. found_b) THEN
    2894     45258092 :                   DO k = 1, SIZE(amb_info%nonbond_a)
    2895     45258092 :                      IF ((name_atm_b) == (amb_info%nonbond_a(k))) THEN
    2896       199334 :                         jj = k
    2897       199334 :                         rmin2_b = amb_info%nonbond_rmin2(k)
    2898       199334 :                         epsilon_b = amb_info%nonbond_eps(k)
    2899              :                      END IF
    2900              :                   END DO
    2901              :                END IF
    2902       199334 :                IF (ii /= 0 .AND. jj /= 0) THEN
    2903       199334 :                   rmin = rmin2_a + rmin2_b
    2904              :                   ! ABS to allow for mixing the two different sign conventions for epsilon
    2905       199334 :                   epsilon0 = SQRT(ABS(epsilon_a*epsilon_b))
    2906       199334 :                   CALL pair_potential_lj_create(pot%set(1)%lj)
    2907       398668 :                   pot%type = lj_charmm_type
    2908       199334 :                   pot%at1 = name_atm_a
    2909       199334 :                   pot%at2 = name_atm_b
    2910       199334 :                   pot%set(1)%lj%epsilon = epsilon0
    2911       199334 :                   pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
    2912       199334 :                   pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
    2913       199334 :                   pot%rcutsq = (10.0_dp*bohr)**2
    2914              :                   CALL issue_duplications(found, "Lennard-Jones", name_atm_a, &
    2915       199334 :                                           name_atm_b)
    2916       199334 :                   found = .TRUE.
    2917              :                END IF
    2918              :             END IF
    2919              : 
    2920              :             ! Always have the input param last to overwrite all the other ones
    2921       257720 :             IF (ASSOCIATED(inp_info%nonbonded14)) THEN
    2922        12120 :                DO k = 1, SIZE(inp_info%nonbonded14%pot)
    2923        15263 :                   IF (iw > 0) WRITE (iw, *) "    TESTING ", TRIM(name_atm_a), TRIM(name_atm_b), &
    2924         4817 :                      " with ", TRIM(inp_info%nonbonded14%pot(k)%pot%at1), &
    2925         9634 :                      TRIM(inp_info%nonbonded14%pot(k)%pot%at2)
    2926              :                   IF ((((name_atm_a) == (inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
    2927        10446 :                        ((name_atm_b) == (inp_info%nonbonded14%pot(k)%pot%at2))) .OR. &
    2928              :                       (((name_atm_b) == (inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
    2929         1674 :                        ((name_atm_a) == (inp_info%nonbonded14%pot(k)%pot%at2)))) THEN
    2930         1666 :                      IF (ff_type%multiple_potential) THEN
    2931            0 :                         CALL pair_potential_single_add(inp_info%nonbonded14%pot(k)%pot, pot)
    2932            0 :                         IF (found) &
    2933              :                            CALL cp_warn(__LOCATION__, &
    2934              :                                         "Multiple ONFO declaration: "//TRIM(name_atm_a)// &
    2935            0 :                                         " and "//TRIM(name_atm_b)//" ADDING! ")
    2936            0 :                         potparm_nonbond14%pot(i, j)%pot => pot
    2937            0 :                         potparm_nonbond14%pot(j, i)%pot => pot
    2938              :                      ELSE
    2939         1666 :                         CALL pair_potential_single_copy(inp_info%nonbonded14%pot(k)%pot, pot)
    2940         1666 :                         IF (found) &
    2941              :                            CALL cp_warn(__LOCATION__, &
    2942              :                                         "Multiple ONFO declarations: "//TRIM(name_atm_a)// &
    2943            0 :                                         " and "//TRIM(name_atm_b)//" OVERWRITING! ")
    2944              :                      END IF
    2945         1666 :                      IF (iw > 0) WRITE (iw, *) "    FOUND ", TRIM(name_atm_a), " ", TRIM(name_atm_b)
    2946         1666 :                      found = .TRUE.
    2947              :                   END IF
    2948              :                END DO
    2949              :             END IF
    2950              : 
    2951              :             ! At the very end we offer the possibility to overwrite the parameters for QM/MM
    2952              :             ! nonbonded interactions
    2953       257720 :             IF (use_qmmm_ff) THEN
    2954          252 :                match_names = 0
    2955          252 :                IF ((name_atm_a) == (name_atm_a_local)) match_names = match_names + 1
    2956          252 :                IF ((name_atm_b) == (name_atm_b_local)) match_names = match_names + 1
    2957          252 :                IF (match_names == 1) THEN
    2958          102 :                   IF (ASSOCIATED(qmmm_env%inp_info%nonbonded14)) THEN
    2959            0 :                      DO k = 1, SIZE(qmmm_env%inp_info%nonbonded14%pot)
    2960              :                         IF (debug_this_module) THEN
    2961              :                            IF (iw > 0) THEN
    2962              :                               WRITE (UNIT=iw, FMT="(T2,A)") &
    2963              :                                  "FORCEFIELD| Testing "//TRIM(name_atm_a)//"-"//TRIM(name_atm_b)// &
    2964              :                                  " with "//TRIM(qmmm_env%inp_info%nonbonded14%pot(k)%pot%at1)//"-"// &
    2965              :                                  TRIM(qmmm_env%inp_info%nonbonded14%pot(k)%pot%at2)
    2966              :                            END IF
    2967              :                         END IF
    2968              :                         IF ((((name_atm_a) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
    2969            0 :                              ((name_atm_b) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at2))) .OR. &
    2970              :                             (((name_atm_b) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
    2971            0 :                              ((name_atm_a) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at2)))) THEN
    2972            0 :                            IF (qmmm_env%multiple_potential) THEN
    2973            0 :                               CALL pair_potential_single_add(qmmm_env%inp_info%nonbonded14%pot(k)%pot, pot)
    2974            0 :                               IF (found) &
    2975              :                                  CALL cp_warn(__LOCATION__, &
    2976              :                                               "Multiple ONFO declaration: "//TRIM(name_atm_a)// &
    2977            0 :                                               " and "//TRIM(name_atm_b)//" Adding QM/MM forcefield specifications")
    2978            0 :                               potparm_nonbond14%pot(i, j)%pot => pot
    2979            0 :                               potparm_nonbond14%pot(j, i)%pot => pot
    2980              :                            ELSE
    2981            0 :                               CALL pair_potential_single_copy(qmmm_env%inp_info%nonbonded14%pot(k)%pot, pot)
    2982            0 :                               IF (found) &
    2983              :                                  CALL cp_warn(__LOCATION__, &
    2984              :                                               "Multiple ONFO declaration: "//TRIM(name_atm_a)// &
    2985            0 :                                               " and "//TRIM(name_atm_b)//" OVERWRITING QM/MM forcefield specifications! ")
    2986              :                            END IF
    2987            0 :                            IF (iw > 0) WRITE (iw, *) "    FOUND ", TRIM(name_atm_a), &
    2988            0 :                               " ", TRIM(name_atm_b)
    2989            0 :                            found = .TRUE.
    2990              :                         END IF
    2991              :                      END DO
    2992              :                   END IF
    2993              :                END IF
    2994              :             END IF
    2995              : 
    2996       257720 :             IF (.NOT. found) THEN
    2997              :                CALL store_FF_missing_par(atm1=TRIM(name_atm_a), &
    2998              :                                          atm2=TRIM(name_atm_b), &
    2999              :                                          type_name="Spline_Bond_Env", &
    3000         7929 :                                          array=Ainfo)
    3001         7929 :                CALL pair_potential_single_clean(pot)
    3002        15858 :                pot%type = nn_type
    3003         7929 :                pot%at1 = name_atm_a
    3004         7929 :                pot%at2 = name_atm_b
    3005              :             END IF
    3006              : 
    3007              :             ! If defined global RCUT let's use it
    3008       257720 :             IF (ff_type%rcut_nb > 0.0_dp) THEN
    3009        26946 :                pot%rcutsq = ff_type%rcut_nb*ff_type%rcut_nb
    3010              :             END IF
    3011              : 
    3012              :             ! Cutoff is defined always as the maximum between the FF and Ewald
    3013       257720 :             pot%rcutsq = MAX(pot%rcutsq, ewald_rcut*ewald_rcut)
    3014       268929 :             IF (only_qm) THEN
    3015        11786 :                CALL pair_potential_single_clean(pot)
    3016              :             END IF
    3017              : 
    3018              :          END DO ! atom kind j
    3019              : 
    3020              :       END DO ! atom kind i
    3021              : 
    3022         2629 :       CALL timestop(handle2)
    3023              : 
    3024         2629 :    END SUBROUTINE force_field_pack_nonbond14
    3025              : 
    3026              : ! **************************************************************************************************
    3027              : !> \brief Assign input and potential info to potparm_nonbond
    3028              : !> \param atomic_kind_set ...
    3029              : !> \param ff_type ...
    3030              : !> \param qmmm_env ...
    3031              : !> \param fatal ...
    3032              : !> \param iw ...
    3033              : !> \param Ainfo ...
    3034              : !> \param chm_info ...
    3035              : !> \param inp_info ...
    3036              : !> \param gro_info ...
    3037              : !> \param amb_info ...
    3038              : !> \param potparm_nonbond ...
    3039              : !> \param ewald_env ...
    3040              : ! **************************************************************************************************
    3041         2629 :    SUBROUTINE force_field_pack_nonbond(atomic_kind_set, ff_type, qmmm_env, fatal, &
    3042              :                                        iw, Ainfo, chm_info, inp_info, gro_info, amb_info, potparm_nonbond, &
    3043              :                                        ewald_env)
    3044              : 
    3045              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3046              :       TYPE(force_field_type), INTENT(INOUT)              :: ff_type
    3047              :       TYPE(qmmm_env_mm_type), POINTER                    :: qmmm_env
    3048              :       LOGICAL                                            :: fatal
    3049              :       INTEGER                                            :: iw
    3050              :       CHARACTER(LEN=default_string_length), &
    3051              :          DIMENSION(:), POINTER                           :: Ainfo
    3052              :       TYPE(charmm_info_type), POINTER                    :: chm_info
    3053              :       TYPE(input_info_type), POINTER                     :: inp_info
    3054              :       TYPE(gromos_info_type), POINTER                    :: gro_info
    3055              :       TYPE(amber_info_type), POINTER                     :: amb_info
    3056              :       TYPE(pair_potential_pp_type), POINTER              :: potparm_nonbond
    3057              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    3058              : 
    3059              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_nonbond'
    3060              : 
    3061              :       CHARACTER(LEN=default_string_length)               :: name_atm_a, name_atm_a_local, &
    3062              :                                                             name_atm_b, name_atm_b_local
    3063              :       INTEGER                                            :: handle2, i, ii, j, jj, k, match_names
    3064              :       LOGICAL                                            :: found, is_a_shell, is_b_shell, only_qm, &
    3065              :                                                             use_qmmm_ff
    3066              :       REAL(KIND=dp)                                      :: epsilon0, ewald_rcut, rmin
    3067              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    3068              :       TYPE(pair_potential_single_type), POINTER          :: pot
    3069              : 
    3070         2629 :       CALL timeset(routineN, handle2)
    3071              : 
    3072         2629 :       use_qmmm_ff = qmmm_env%use_qmmm_ff
    3073         2629 :       NULLIFY (pot)
    3074              : 
    3075         2629 :       IF (iw > 0) THEN
    3076              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
    3077          238 :             "FORCEFIELD| Checking for nonbonded terms"
    3078              :       END IF
    3079              : 
    3080         2629 :       CALL ewald_env_get(ewald_env, rcut=ewald_rcut)
    3081         2629 :       CALL pair_potential_pp_create(potparm_nonbond, SIZE(atomic_kind_set))
    3082              : 
    3083        13838 :       DO i = 1, SIZE(atomic_kind_set)
    3084              : 
    3085        11209 :          atomic_kind => atomic_kind_set(i)
    3086              : 
    3087              :          CALL get_atomic_kind(atomic_kind=atomic_kind, name=name_atm_a_local, &
    3088        11209 :                               shell_active=is_a_shell)
    3089              : 
    3090       271558 :          DO j = i, SIZE(atomic_kind_set)
    3091              : 
    3092       257720 :             atomic_kind => atomic_kind_set(j)
    3093              : 
    3094              :             CALL get_atomic_kind(atomic_kind=atomic_kind, name=name_atm_b_local, &
    3095       257720 :                                  shell_active=is_b_shell)
    3096              : 
    3097       257720 :             found = .FALSE.
    3098              : 
    3099       257720 :             name_atm_a = name_atm_a_local
    3100       257720 :             name_atm_b = name_atm_b_local
    3101       257720 :             only_qm = qmmm_ff_precond_only_qm(id1=name_atm_a, id2=name_atm_b)
    3102       257720 :             CALL uppercase(name_atm_a)
    3103       257720 :             CALL uppercase(name_atm_b)
    3104       257720 :             pot => potparm_nonbond%pot(i, j)%pot
    3105              : 
    3106       257720 :             IF (iw > 0) THEN
    3107              :                WRITE (UNIT=iw, FMT="(/,T2,A)") &
    3108              :                   "FORCEFIELD| Checking for nonbonded terms between the atomic kinds "// &
    3109         6441 :                   TRIM(name_atm_a)//" and "//TRIM(name_atm_b)
    3110              :             END IF
    3111              : 
    3112              :             ! Loop over params from GROMOS
    3113       257720 :             IF (ASSOCIATED(gro_info%nonbond_a)) THEN
    3114          540 :                ii = 0
    3115          540 :                jj = 0
    3116         1800 :                DO k = 1, SIZE(gro_info%nonbond_a)
    3117         1800 :                   IF (TRIM(name_atm_a) == TRIM(gro_info%nonbond_a(k))) THEN
    3118              :                      ii = k
    3119              :                      EXIT
    3120              :                   END IF
    3121              :                END DO
    3122         2364 :                DO k = 1, SIZE(gro_info%nonbond_a)
    3123         2364 :                   IF (TRIM(name_atm_b) == TRIM(gro_info%nonbond_a(k))) THEN
    3124              :                      jj = k
    3125              :                      EXIT
    3126              :                   END IF
    3127              :                END DO
    3128              : 
    3129          540 :                IF (ii /= 0 .AND. jj /= 0) THEN
    3130          540 :                   CALL pair_potential_lj_create(pot%set(1)%lj)
    3131         1080 :                   pot%type = lj_type
    3132          540 :                   pot%at1 = name_atm_a
    3133          540 :                   pot%at2 = name_atm_b
    3134          540 :                   pot%set(1)%lj%epsilon = 1.0_dp
    3135          540 :                   pot%set(1)%lj%sigma6 = gro_info%nonbond_c6(ii, jj)
    3136          540 :                   pot%set(1)%lj%sigma12 = gro_info%nonbond_c12(ii, jj)
    3137          540 :                   pot%rcutsq = (10.0_dp*bohr)**2
    3138          540 :                   CALL issue_duplications(found, "Lennard-Jones", name_atm_a, name_atm_b)
    3139          540 :                   found = .TRUE.
    3140              :                END IF
    3141              :             END IF
    3142              : 
    3143              :             ! Loop over params from CHARMM
    3144       257720 :             IF (ASSOCIATED(chm_info%nonbond_a)) THEN
    3145        48317 :                ii = 0
    3146        48317 :                jj = 0
    3147      2286521 :                DO k = 1, SIZE(chm_info%nonbond_a)
    3148      2286521 :                   IF ((name_atm_a) == (chm_info%nonbond_a(k))) THEN
    3149        48251 :                      ii = k
    3150              :                   END IF
    3151              :                END DO
    3152      2286521 :                DO k = 1, SIZE(chm_info%nonbond_a)
    3153      2286521 :                   IF ((name_atm_b) == (chm_info%nonbond_a(k))) THEN
    3154        48299 :                      jj = k
    3155              :                   END IF
    3156              :                END DO
    3157              : 
    3158        48317 :                IF (ii /= 0 .AND. jj /= 0) THEN
    3159        48251 :                   rmin = chm_info%nonbond_rmin2(ii) + chm_info%nonbond_rmin2(jj)
    3160              :                   epsilon0 = SQRT(chm_info%nonbond_eps(ii)* &
    3161        48251 :                                   chm_info%nonbond_eps(jj))
    3162        48251 :                   CALL pair_potential_lj_create(pot%set(1)%lj)
    3163        96502 :                   pot%type = lj_charmm_type
    3164        48251 :                   pot%at1 = name_atm_a
    3165        48251 :                   pot%at2 = name_atm_b
    3166        48251 :                   pot%set(1)%lj%epsilon = epsilon0
    3167        48251 :                   pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
    3168        48251 :                   pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
    3169        48251 :                   pot%rcutsq = (10.0_dp*bohr)**2
    3170        48251 :                   CALL issue_duplications(found, "Lennard-Jones", name_atm_a, name_atm_b)
    3171        48251 :                   found = .TRUE.
    3172              :                END IF
    3173              :             END IF
    3174              : 
    3175              :             ! Loop over params from AMBER
    3176       257720 :             IF (ASSOCIATED(amb_info%nonbond_a)) THEN
    3177       199334 :                ii = 0
    3178       199334 :                jj = 0
    3179     45258092 :                DO k = 1, SIZE(amb_info%nonbond_a)
    3180     45258092 :                   IF ((name_atm_a) == (amb_info%nonbond_a(k))) THEN
    3181       199334 :                      ii = k
    3182              :                   END IF
    3183              :                END DO
    3184     45258092 :                DO k = 1, SIZE(amb_info%nonbond_a)
    3185     45258092 :                   IF ((name_atm_b) == (amb_info%nonbond_a(k))) THEN
    3186       199334 :                      jj = k
    3187              :                   END IF
    3188              :                END DO
    3189              : 
    3190       199334 :                IF (ii /= 0 .AND. jj /= 0) THEN
    3191       199334 :                   rmin = amb_info%nonbond_rmin2(ii) + amb_info%nonbond_rmin2(jj)
    3192       199334 :                   epsilon0 = SQRT(amb_info%nonbond_eps(ii)*amb_info%nonbond_eps(jj))
    3193       199334 :                   CALL pair_potential_lj_create(pot%set(1)%lj)
    3194       398668 :                   pot%type = lj_charmm_type
    3195       199334 :                   pot%at1 = name_atm_a
    3196       199334 :                   pot%at2 = name_atm_b
    3197       199334 :                   pot%set(1)%lj%epsilon = epsilon0
    3198       199334 :                   pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
    3199       199334 :                   pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
    3200       199334 :                   pot%rcutsq = (10.0_dp*bohr)**2
    3201       199334 :                   CALL issue_duplications(found, "Lennard-Jones", name_atm_a, name_atm_b)
    3202       199334 :                   found = .TRUE.
    3203              :                END IF
    3204              :             END IF
    3205              : 
    3206              :             ! Always have the input param last to overwrite all the other ones
    3207       257720 :             IF (ASSOCIATED(inp_info%nonbonded)) THEN
    3208        53254 :                DO k = 1, SIZE(inp_info%nonbonded%pot)
    3209        43579 :                   IF ((TRIM(inp_info%nonbonded%pot(k)%pot%at1) == "*") .OR. &
    3210              :                       (TRIM(inp_info%nonbonded%pot(k)%pot%at2) == "*")) CYCLE
    3211              :                   IF (debug_this_module) THEN
    3212              :                      IF (iw > 0) THEN
    3213              :                         WRITE (UNIT=iw, FMT="(T2,A)") &
    3214              :                            "FORCEFIELD| Testing "//TRIM(name_atm_a)//"-"//TRIM(name_atm_b)// &
    3215              :                            " with "//TRIM(inp_info%nonbonded%pot(k)%pot%at1)//"-"// &
    3216              :                            TRIM(inp_info%nonbonded%pot(k)%pot%at2)
    3217              :                      END IF
    3218              :                   END IF
    3219              :                   IF ((((name_atm_a) == (inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
    3220        43577 :                        ((name_atm_b) == (inp_info%nonbonded%pot(k)%pot%at2))) .OR. &
    3221              :                       (((name_atm_b) == (inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
    3222         9675 :                        ((name_atm_a) == (inp_info%nonbonded%pot(k)%pot%at2)))) THEN
    3223         9454 :                      IF (iw > 0) THEN
    3224              :                         WRITE (UNIT=iw, FMT="(T2,A)") &
    3225              :                            "FORCEFIELD| Found nonbonded term "// &
    3226          932 :                            TRIM(name_atm_a)//"-"//TRIM(name_atm_b)
    3227              :                      END IF
    3228         9454 :                      IF (ff_type%multiple_potential) THEN
    3229           38 :                         CALL pair_potential_single_add(inp_info%nonbonded%pot(k)%pot, pot)
    3230           38 :                         IF (found) &
    3231              :                            CALL cp_warn(__LOCATION__, &
    3232              :                                         "Multiple NONBONDED declarations for "//TRIM(name_atm_a)// &
    3233            8 :                                         "-"//TRIM(name_atm_b)//" -> ADDING")
    3234           38 :                         potparm_nonbond%pot(i, j)%pot => pot
    3235           38 :                         potparm_nonbond%pot(j, i)%pot => pot
    3236              :                      ELSE
    3237         9416 :                         CALL pair_potential_single_copy(inp_info%nonbonded%pot(k)%pot, pot)
    3238         9416 :                         IF (found) &
    3239              :                            CALL cp_warn(__LOCATION__, &
    3240              :                                         "Multiple NONBONDED declarations for "//TRIM(name_atm_a)// &
    3241            8 :                                         "-"//TRIM(name_atm_b)//" -> OVERWRITING")
    3242              :                      END IF
    3243         9454 :                      found = .TRUE.
    3244              :                   END IF
    3245              :                END DO
    3246              : 
    3247              :                ! Check for wildcards for one of the two types (if not associated yet)
    3248         9675 :                IF (.NOT. found) THEN
    3249          590 :                   DO k = 1, SIZE(inp_info%nonbonded%pot)
    3250          433 :                      IF ((TRIM(inp_info%nonbonded%pot(k)%pot%at1) == "*") .EQV. &
    3251              :                          (TRIM(inp_info%nonbonded%pot(k)%pot%at2) == "*")) CYCLE
    3252              :                      IF (debug_this_module) THEN
    3253              :                         IF (iw > 0) THEN
    3254              :                            WRITE (UNIT=iw, FMT="(T2,A)") &
    3255              :                               "FORCEFIELD| Testing "//TRIM(name_atm_a)//"-"//TRIM(name_atm_b)// &
    3256              :                               " with "//TRIM(inp_info%nonbonded%pot(k)%pot%at1)//"-"// &
    3257              :                               TRIM(inp_info%nonbonded%pot(k)%pot%at2)
    3258              :                         END IF
    3259              :                      END IF
    3260              :                      IF ((name_atm_a == inp_info%nonbonded%pot(k)%pot%at1) .OR. &
    3261              :                          (name_atm_b == inp_info%nonbonded%pot(k)%pot%at2) .OR. &
    3262            0 :                          (name_atm_b == inp_info%nonbonded%pot(k)%pot%at1) .OR. &
    3263          157 :                          (name_atm_a == inp_info%nonbonded%pot(k)%pot%at2)) THEN
    3264            0 :                         IF (iw > 0) THEN
    3265              :                            WRITE (UNIT=iw, FMT="(T2,A)") &
    3266              :                               "FORCEFIELD| Found one wildcard for "// &
    3267            0 :                               TRIM(name_atm_a)//"-"//TRIM(name_atm_b)
    3268              :                         END IF
    3269            0 :                         IF (ff_type%multiple_potential) THEN
    3270            0 :                            CALL pair_potential_single_add(inp_info%nonbonded%pot(k)%pot, pot)
    3271            0 :                            IF (found) &
    3272              :                               CALL cp_warn(__LOCATION__, &
    3273              :                                            "Multiple NONBONDED declarations "//TRIM(name_atm_a)// &
    3274            0 :                                            "-"//TRIM(name_atm_b)//" -> ADDING")
    3275            0 :                            potparm_nonbond%pot(i, j)%pot => pot
    3276            0 :                            potparm_nonbond%pot(j, i)%pot => pot
    3277              :                         ELSE
    3278            0 :                            CALL pair_potential_single_copy(inp_info%nonbonded%pot(k)%pot, pot)
    3279            0 :                            IF (found) &
    3280              :                               CALL cp_warn(__LOCATION__, &
    3281              :                                            "Multiple NONBONDED declarations "//TRIM(name_atm_a)// &
    3282            0 :                                            "-"//TRIM(name_atm_b)//" -> OVERWRITING")
    3283              :                         END IF
    3284            0 :                         found = .TRUE.
    3285              :                      END IF
    3286              :                   END DO
    3287              :                END IF
    3288              : 
    3289              :                ! Check for wildcards for both types (if not associated yet)
    3290         9675 :                IF (.NOT. found) THEN
    3291          590 :                   DO k = 1, SIZE(inp_info%nonbonded%pot)
    3292          433 :                      IF ((TRIM(inp_info%nonbonded%pot(k)%pot%at1) /= "*") .OR. &
    3293              :                          (TRIM(inp_info%nonbonded%pot(k)%pot%at2) /= "*")) CYCLE
    3294              :                      IF (debug_this_module) THEN
    3295              :                         IF (iw > 0) THEN
    3296              :                            WRITE (UNIT=iw, FMT="(T2,A)") &
    3297              :                               "FORCEFIELD| Testing "//TRIM(name_atm_a)//"-"//TRIM(name_atm_b)// &
    3298              :                               " with "//TRIM(inp_info%nonbonded%pot(k)%pot%at1)//"-"// &
    3299              :                               TRIM(inp_info%nonbonded%pot(k)%pot%at2)
    3300              :                         END IF
    3301              :                      END IF
    3302            2 :                      IF (iw > 0) THEN
    3303              :                         WRITE (UNIT=iw, FMT="(T2,A)") &
    3304              :                            "FORCEFIELD| Found wildcards for both "// &
    3305            0 :                            TRIM(name_atm_a)//" and "//TRIM(name_atm_b)
    3306              :                      END IF
    3307            2 :                      IF (ff_type%multiple_potential) THEN
    3308            0 :                         CALL pair_potential_single_add(inp_info%nonbonded%pot(k)%pot, pot)
    3309            0 :                         IF (found) &
    3310              :                            CALL cp_warn(__LOCATION__, &
    3311              :                                         "Multiple NONBONDED declarations "//TRIM(name_atm_a)// &
    3312            0 :                                         " - "//TRIM(name_atm_b)//" -> ADDING")
    3313            0 :                         potparm_nonbond%pot(i, j)%pot => pot
    3314            0 :                         potparm_nonbond%pot(j, i)%pot => pot
    3315              :                      ELSE
    3316            2 :                         CALL pair_potential_single_copy(inp_info%nonbonded%pot(k)%pot, pot)
    3317            2 :                         IF (found) &
    3318              :                            CALL cp_warn(__LOCATION__, &
    3319              :                                         "Multiple NONBONDED declarations "//TRIM(name_atm_a)// &
    3320            0 :                                         " - "//TRIM(name_atm_b)//" -> OVERWRITING")
    3321              :                      END IF
    3322          590 :                      found = .TRUE.
    3323              :                   END DO
    3324              :                END IF
    3325              :             END IF
    3326              : 
    3327              :             ! At the very end we offer the possibility to overwrite the parameters for QM/MM
    3328              :             ! nonbonded interactions
    3329       257720 :             IF (use_qmmm_ff) THEN
    3330          252 :                match_names = 0
    3331          252 :                IF ((name_atm_a) == (name_atm_a_local)) match_names = match_names + 1
    3332          252 :                IF ((name_atm_b) == (name_atm_b_local)) match_names = match_names + 1
    3333          252 :                IF (match_names == 1) THEN
    3334          102 :                   IF (ASSOCIATED(qmmm_env%inp_info%nonbonded)) THEN
    3335          276 :                      DO k = 1, SIZE(qmmm_env%inp_info%nonbonded%pot)
    3336              :                         IF (debug_this_module) THEN
    3337              :                            IF (iw > 0) THEN
    3338              :                               WRITE (UNIT=iw, FMT="(T2,A)") &
    3339              :                                  "FORCEFIELD| Testing "//TRIM(name_atm_a)//"-"//TRIM(name_atm_b)// &
    3340              :                                  " with "//TRIM(qmmm_env%inp_info%nonbonded%pot(k)%pot%at1), &
    3341              :                                  TRIM(qmmm_env%inp_info%nonbonded%pot(k)%pot%at2)
    3342              :                            END IF
    3343              :                         END IF
    3344              :                         IF ((((name_atm_a) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
    3345          174 :                              ((name_atm_b) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at2))) .OR. &
    3346              :                             (((name_atm_b) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
    3347          102 :                              ((name_atm_a) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at2)))) THEN
    3348           20 :                            IF (iw > 0) THEN
    3349              :                               WRITE (UNIT=iw, FMT="(T2,A)") &
    3350           11 :                                  "FORCEFIELD| Found "//TRIM(name_atm_a)//"-"//TRIM(name_atm_b)//" (QM/MM)"
    3351              :                            END IF
    3352           20 :                            IF (qmmm_env%multiple_potential) THEN
    3353            0 :                               CALL pair_potential_single_add(qmmm_env%inp_info%nonbonded%pot(k)%pot, pot)
    3354            0 :                               IF (found) &
    3355              :                                  CALL cp_warn(__LOCATION__, &
    3356              :                                               "Multiple NONBONDED declarations for "//TRIM(name_atm_a)// &
    3357            0 :                                               " and "//TRIM(name_atm_b)//" -> ADDING QM/MM forcefield specifications")
    3358            0 :                               potparm_nonbond%pot(i, j)%pot => pot
    3359            0 :                               potparm_nonbond%pot(j, i)%pot => pot
    3360              :                            ELSE
    3361           20 :                               CALL pair_potential_single_copy(qmmm_env%inp_info%nonbonded%pot(k)%pot, pot)
    3362           20 :                               IF (found) &
    3363              :                                  CALL cp_warn(__LOCATION__, &
    3364              :                                               "Multiple NONBONDED declarations for "//TRIM(name_atm_a)// &
    3365            2 :                                               " and "//TRIM(name_atm_b)//" -> OVERWRITING QM/MM forcefield specifications")
    3366              :                            END IF
    3367           20 :                            found = .TRUE.
    3368              :                         END IF
    3369              :                      END DO
    3370              :                   END IF
    3371              :                END IF
    3372              :             END IF
    3373              : 
    3374       257720 :             IF (.NOT. found) THEN
    3375              :                CALL store_FF_missing_par(atm1=TRIM(name_atm_a), &
    3376              :                                          atm2=TRIM(name_atm_b), &
    3377              :                                          type_name="Spline_Non_Bond_Env", &
    3378              :                                          fatal=fatal, &
    3379          137 :                                          array=Ainfo)
    3380              :             END IF
    3381              : 
    3382              :             ! If defined global RCUT let's use it
    3383       257720 :             IF (ff_type%rcut_nb > 0.0_dp) THEN
    3384        26946 :                pot%rcutsq = ff_type%rcut_nb*ff_type%rcut_nb
    3385              :             END IF
    3386              : 
    3387              :             ! Cutoff is defined always as the maximum between the FF and Ewald
    3388       257720 :             pot%rcutsq = MAX(pot%rcutsq, ewald_rcut*ewald_rcut)
    3389              :             ! Set the shell type
    3390       257720 :             IF ((is_a_shell .AND. .NOT. is_b_shell) .OR. (is_b_shell .AND. .NOT. is_a_shell)) THEN
    3391           66 :                pot%shell_type = nosh_sh
    3392       257654 :             ELSE IF (is_a_shell .AND. is_b_shell) THEN
    3393          616 :                pot%shell_type = sh_sh
    3394              :             ELSE
    3395       257038 :                pot%shell_type = nosh_nosh
    3396              :             END IF
    3397              : 
    3398       526649 :             IF (only_qm) THEN
    3399        11786 :                CALL pair_potential_single_clean(pot)
    3400              :             END IF
    3401              : 
    3402              :          END DO ! jkind
    3403              : 
    3404              :       END DO ! ikind
    3405              : 
    3406         2629 :       CALL timestop(handle2)
    3407              : 
    3408         2629 :    END SUBROUTINE force_field_pack_nonbond
    3409              : 
    3410              : ! **************************************************************************************************
    3411              : !> \brief create the pair potential spline environment
    3412              : !> \param atomic_kind_set ...
    3413              : !> \param ff_type ...
    3414              : !> \param iw2 ...
    3415              : !> \param iw3 ...
    3416              : !> \param iw4 ...
    3417              : !> \param potparm ...
    3418              : !> \param do_zbl ...
    3419              : !> \param nonbonded_type ...
    3420              : ! **************************************************************************************************
    3421         5258 :    SUBROUTINE force_field_pack_splines(atomic_kind_set, ff_type, iw2, iw3, iw4, &
    3422              :                                        potparm, do_zbl, nonbonded_type)
    3423              : 
    3424              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3425              :       TYPE(force_field_type), INTENT(INOUT)              :: ff_type
    3426              :       INTEGER                                            :: iw2, iw3, iw4
    3427              :       TYPE(pair_potential_pp_type), POINTER              :: potparm
    3428              :       LOGICAL, INTENT(IN)                                :: do_zbl
    3429              :       CHARACTER(LEN=*), INTENT(IN)                       :: nonbonded_type
    3430              : 
    3431              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_splines'
    3432              : 
    3433              :       INTEGER                                            :: handle2, ikind, jkind, n
    3434         5258 :       TYPE(spline_data_p_type), DIMENSION(:), POINTER    :: spl_p
    3435              :       TYPE(spline_environment_type), POINTER             :: spline_env
    3436              : 
    3437         5258 :       CALL timeset(routineN, handle2)
    3438              : 
    3439         5258 :       IF (iw2 > 0) THEN
    3440              :          WRITE (UNIT=iw2, FMT="(/,T2,A)") &
    3441          476 :             "FORCEFIELD| Splining nonbonded terms"
    3442              :       END IF
    3443              : 
    3444              :       ! Figure out which nonbonded interactions happen to be identical, and
    3445              :       ! prepare storage for these, avoiding duplicates.
    3446         5258 :       NULLIFY (spline_env)
    3447              :       CALL get_nonbond_storage(spline_env, potparm, atomic_kind_set, &
    3448         5258 :                                do_zbl, shift_cutoff=ff_type%shift_cutoff)
    3449              :       ! Effectively compute the spline data
    3450              :       CALL spline_nonbond_control(spline_env, potparm, &
    3451              :                                   atomic_kind_set, eps_spline=ff_type%eps_spline, &
    3452              :                                   max_energy=ff_type%max_energy, rlow_nb=ff_type%rlow_nb, &
    3453              :                                   emax_spline=ff_type%emax_spline, npoints=ff_type%npoints, &
    3454              :                                   iw=iw2, iw2=iw3, iw3=iw4, &
    3455              :                                   do_zbl=do_zbl, shift_cutoff=ff_type%shift_cutoff, &
    3456         5258 :                                   nonbonded_type=nonbonded_type)
    3457              :       ! Let the pointers on potparm point to the splines generated in
    3458              :       ! spline_nonbond_control
    3459        27676 :       DO ikind = 1, SIZE(potparm%pot, 1)
    3460       543116 :          DO jkind = ikind, SIZE(potparm%pot, 2)
    3461       515440 :             n = spline_env%spltab(ikind, jkind)
    3462       515440 :             spl_p => spline_env%spl_pp(n)%spl_p
    3463       515440 :             CALL spline_data_p_retain(spl_p)
    3464       515440 :             CALL spline_data_p_release(potparm%pot(ikind, jkind)%pot%pair_spline_data)
    3465       537858 :             potparm%pot(ikind, jkind)%pot%pair_spline_data => spl_p
    3466              :          END DO
    3467              :       END DO
    3468         5258 :       CALL spline_env_release(spline_env)
    3469         5258 :       DEALLOCATE (spline_env)
    3470              :       NULLIFY (spline_env)
    3471              : 
    3472         5258 :       IF (iw2 > 0) THEN
    3473              :          WRITE (UNIT=iw2, FMT="(/,T2,A)") &
    3474          476 :             "FORCEFIELD| Splining done"
    3475              :       END IF
    3476              : 
    3477         5258 :       CALL timestop(handle2)
    3478              : 
    3479         5258 :    END SUBROUTINE force_field_pack_splines
    3480              : 
    3481              : ! **************************************************************************************************
    3482              : !> \brief Compute the electrostatic interaction cutoffs
    3483              : !> \param atomic_kind_set ...
    3484              : !> \param ff_type ...
    3485              : !> \param potparm_nonbond ...
    3486              : !> \param ewald_env ...
    3487              : !> \param iw ...
    3488              : !> \author Toon.Verstraelen@gmail.com
    3489              : ! **************************************************************************************************
    3490         2645 :    SUBROUTINE force_field_pack_eicut(atomic_kind_set, ff_type, potparm_nonbond, ewald_env, iw)
    3491              : 
    3492              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3493              :       TYPE(force_field_type), INTENT(IN)                 :: ff_type
    3494              :       TYPE(pair_potential_pp_type), POINTER              :: potparm_nonbond
    3495              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    3496              :       INTEGER, INTENT(IN)                                :: iw
    3497              : 
    3498              :       CHARACTER(len=*), PARAMETER :: routineN = 'force_field_pack_eicut'
    3499              : 
    3500              :       INTEGER                                            :: ewald_type, handle, i1, i2, nkinds
    3501              :       REAL(KIND=dp)                                      :: alpha, beta, mm_radius1, mm_radius2, &
    3502              :                                                             rcut2, rcut2_ewald, tmp
    3503         2645 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: interaction_cutoffs
    3504              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
    3505              : 
    3506         2645 :       CALL timeset(routineN, handle)
    3507              : 
    3508         2645 :       IF (iw > 0) THEN
    3509              :          WRITE (UNIT=iw, FMT="(/,T2,A)") &
    3510          239 :             "FORCEFIELD| Computing the electrostatic interactions cutoffs"
    3511              :       END IF
    3512              : 
    3513         2645 :       tmp = 0.0_dp
    3514         2645 :       nkinds = SIZE(atomic_kind_set)
    3515              : 
    3516              :       ! Allocate the array with interaction cutoffs for the electrostatics, used
    3517              :       ! to make the electrostatic interaction continuous at ewald_env%rcut
    3518        10580 :       ALLOCATE (interaction_cutoffs(3, nkinds, nkinds))
    3519      2032972 :       interaction_cutoffs = 0.0_dp
    3520              : 
    3521              :       ! Compute the interaction cutoff if SHIFT_CUTOFF is active
    3522         2645 :       IF (ff_type%shift_cutoff) THEN
    3523              :          CALL ewald_env_get(ewald_env, alpha=alpha, ewald_type=ewald_type, &
    3524         2493 :                             rcut=rcut2_ewald)
    3525         2493 :          rcut2_ewald = rcut2_ewald*rcut2_ewald
    3526        11736 :          DO i1 = 1, nkinds
    3527         9243 :             atomic_kind => atomic_kind_set(i1)
    3528         9243 :             CALL get_atomic_kind(atomic_kind=atomic_kind, mm_radius=mm_radius1)
    3529       118117 :             DO i2 = 1, nkinds
    3530       106381 :                rcut2 = rcut2_ewald
    3531       106381 :                IF (ASSOCIATED(potparm_nonbond)) THEN
    3532       105851 :                   rcut2 = MAX(potparm_nonbond%pot(i1, i2)%pot%rcutsq, rcut2_ewald)
    3533              :                END IF
    3534       115624 :                IF (rcut2 > 0) THEN
    3535       103069 :                   atomic_kind => atomic_kind_set(i2)
    3536       103069 :                   CALL get_atomic_kind(atomic_kind=atomic_kind, mm_radius=mm_radius2)
    3537              :                   ! cutoff for core-core
    3538              :                   interaction_cutoffs(1, i1, i2) = potential_coulomb(rcut2, tmp, &
    3539       103069 :                                                                      1.0_dp, ewald_type, alpha, 0.0_dp, 0.0_dp)
    3540              :                   ! cutoff for core-shell, core-ion, shell-core or ion-core
    3541       103069 :                   IF (mm_radius1 > 0.0_dp) THEN
    3542          676 :                      beta = sqrthalf/mm_radius1
    3543              :                   ELSE
    3544       102393 :                      beta = 0.0_dp
    3545              :                   END IF
    3546              :                   interaction_cutoffs(2, i1, i2) = potential_coulomb(rcut2, tmp, &
    3547       103069 :                                                                      1.0_dp, ewald_type, alpha, beta, 0.0_dp)
    3548              :                   ! cutoff for shell-shell or ion-ion
    3549       103069 :                   IF (mm_radius1 + mm_radius2 > 0.0_dp) THEN
    3550          698 :                      beta = sqrthalf/SQRT(mm_radius1*mm_radius1 + mm_radius2*mm_radius2)
    3551              :                   ELSE
    3552       102371 :                      beta = 0.0_dp
    3553              :                   END IF
    3554              :                   interaction_cutoffs(3, i1, i2) = potential_coulomb(rcut2, tmp, &
    3555       103069 :                                                                      1.0_dp, ewald_type, alpha, beta, 0.0_dp)
    3556              :                END IF
    3557              :             END DO
    3558              :          END DO
    3559              :       END IF
    3560              : 
    3561         2645 :       CALL ewald_env_set(ewald_env, interaction_cutoffs=interaction_cutoffs)
    3562              : 
    3563         2645 :       CALL timestop(handle)
    3564              : 
    3565         2645 :    END SUBROUTINE force_field_pack_eicut
    3566              : 
    3567              : ! **************************************************************************************************
    3568              : !> \brief Issues on screen a warning when repetitions are present in the
    3569              : !>        definition of the forcefield
    3570              : !> \param found ...
    3571              : !> \param tag_label ...
    3572              : !> \param name_atm_a ...
    3573              : !> \param name_atm_b ...
    3574              : !> \param name_atm_c ...
    3575              : !> \param name_atm_d ...
    3576              : !> \author Teodoro Laino [tlaino] - University of Zurich 10.2008
    3577              : ! **************************************************************************************************
    3578       783515 :    SUBROUTINE issue_duplications(found, tag_label, name_atm_a, name_atm_b, &
    3579              :                                  name_atm_c, name_atm_d)
    3580              : 
    3581              :       LOGICAL, INTENT(IN)                                :: found
    3582              :       CHARACTER(LEN=*), INTENT(IN)                       :: tag_label, name_atm_a
    3583              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: name_atm_b, name_atm_c, name_atm_d
    3584              : 
    3585              :       CHARACTER(LEN=default_string_length)               :: item
    3586              : 
    3587       783515 :       item = "("//TRIM(name_atm_a)
    3588       783515 :       IF (PRESENT(name_atm_b)) THEN
    3589       775665 :          item = TRIM(item)//", "//TRIM(name_atm_b)
    3590              :       END IF
    3591       783515 :       IF (PRESENT(name_atm_c)) THEN
    3592       164592 :          item = TRIM(item)//", "//TRIM(name_atm_c)
    3593              :       END IF
    3594       783515 :       IF (PRESENT(name_atm_d)) THEN
    3595         3418 :          item = TRIM(item)//", "//TRIM(name_atm_d)
    3596              :       END IF
    3597       783515 :       item = TRIM(item)//")"
    3598       783515 :       IF (found) THEN
    3599         1678 :          CPWARN("Found multiple "//TRIM(tag_label)//" terms for "//TRIM(item)//" -> OVERWRITING")
    3600              :       END IF
    3601              : 
    3602       783515 :    END SUBROUTINE issue_duplications
    3603              : 
    3604              : ! **************************************************************************************************
    3605              : !> \brief Store informations on possible missing ForceFields parameters
    3606              : !> \param atm1 ...
    3607              : !> \param atm2 ...
    3608              : !> \param atm3 ...
    3609              : !> \param atm4 ...
    3610              : !> \param type_name ...
    3611              : !> \param fatal ...
    3612              : !> \param array ...
    3613              : ! **************************************************************************************************
    3614       171162 :    SUBROUTINE store_FF_missing_par(atm1, atm2, atm3, atm4, type_name, fatal, array)
    3615              :       CHARACTER(LEN=*), INTENT(IN)                       :: atm1
    3616              :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: atm2, atm3, atm4
    3617              :       CHARACTER(LEN=*), INTENT(IN)                       :: type_name
    3618              :       LOGICAL, INTENT(INOUT), OPTIONAL                   :: fatal
    3619              :       CHARACTER(LEN=default_string_length), &
    3620              :          DIMENSION(:), POINTER                           :: array
    3621              : 
    3622              :       CHARACTER(LEN=10)                                  :: sfmt
    3623              :       CHARACTER(LEN=9)                                   :: my_atm1, my_atm2, my_atm3, my_atm4
    3624              :       CHARACTER(LEN=default_path_length)                 :: my_format
    3625              :       INTEGER                                            :: fmt, i, nsize
    3626              :       LOGICAL                                            :: found
    3627              : 
    3628       171162 :       nsize = 0
    3629       171162 :       fmt = 1
    3630              :       my_format = '(T2,"FORCEFIELD| Missing ","'//TRIM(type_name)// &
    3631       171162 :                   '",T40,"(",A9,")")'
    3632       171162 :       IF (PRESENT(atm2)) fmt = fmt + 1
    3633       171162 :       IF (PRESENT(atm3)) fmt = fmt + 1
    3634       171162 :       IF (PRESENT(atm4)) fmt = fmt + 1
    3635       171162 :       CALL integer_to_string(fmt - 1, sfmt)
    3636       171162 :       IF (fmt > 1) &
    3637              :          my_format = '(T2,"FORCEFIELD| Missing ","'//TRIM(type_name)// &
    3638       171150 :                      '",T40,"(",A9,'//TRIM(sfmt)//'(",",A9),")")'
    3639       171162 :       IF (PRESENT(fatal)) fatal = .TRUE.
    3640              :       ! Check for previous already stored equal force fields
    3641       171162 :       IF (ASSOCIATED(array)) nsize = SIZE(array)
    3642       171162 :       found = .FALSE.
    3643       171162 :       IF (nsize >= 1) THEN
    3644     19488388 :          DO i = 1, nsize
    3645            8 :             SELECT CASE (type_name)
    3646              :             CASE ("Bond")
    3647            8 :                IF (INDEX(array(i) (21:39), "Bond") == 0) CYCLE
    3648            8 :                my_atm1 = array(i) (41:49)
    3649            8 :                my_atm2 = array(i) (51:59)
    3650            8 :                CALL compress(my_atm1, .TRUE.)
    3651            8 :                CALL compress(my_atm2, .TRUE.)
    3652            8 :                IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2)) .OR. &
    3653            8 :                    ((atm1 == my_atm2) .AND. (atm2 == my_atm1))) found = .TRUE.
    3654              :             CASE ("Angle")
    3655            8 :                IF (INDEX(array(i) (21:39), "Angle") == 0) CYCLE
    3656            0 :                my_atm1 = array(i) (41:49)
    3657            0 :                my_atm2 = array(i) (51:59)
    3658            0 :                my_atm3 = array(i) (61:69)
    3659            0 :                CALL compress(my_atm1, .TRUE.)
    3660            0 :                CALL compress(my_atm2, .TRUE.)
    3661            0 :                CALL compress(my_atm3, .TRUE.)
    3662            0 :                IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3)) .OR. &
    3663              :                    ((atm1 == my_atm3) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm1))) &
    3664     18206414 :                   found = .TRUE.
    3665              :             CASE ("Urey-Bradley")
    3666     18206414 :                IF (INDEX(array(i) (21:39), "Urey-Bradley") == 0) CYCLE
    3667     18206414 :                my_atm1 = array(i) (41:49)
    3668     18206414 :                my_atm2 = array(i) (51:59)
    3669     18206414 :                my_atm3 = array(i) (61:69)
    3670     18206414 :                CALL compress(my_atm1, .TRUE.)
    3671     18206414 :                CALL compress(my_atm2, .TRUE.)
    3672     18206414 :                CALL compress(my_atm3, .TRUE.)
    3673     18206414 :                IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3)) .OR. &
    3674              :                    ((atm1 == my_atm3) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm1))) &
    3675       607150 :                   found = .TRUE.
    3676              :             CASE ("Torsion")
    3677       607150 :                IF (INDEX(array(i) (21:39), "Torsion") == 0) CYCLE
    3678       198764 :                my_atm1 = array(i) (41:49)
    3679       198764 :                my_atm2 = array(i) (51:59)
    3680       198764 :                my_atm3 = array(i) (61:69)
    3681       198764 :                my_atm4 = array(i) (71:79)
    3682       198764 :                CALL compress(my_atm1, .TRUE.)
    3683       198764 :                CALL compress(my_atm2, .TRUE.)
    3684       198764 :                CALL compress(my_atm3, .TRUE.)
    3685       198764 :                CALL compress(my_atm4, .TRUE.)
    3686       198764 :                IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm4)) .OR. &
    3687              :                    ((atm1 == my_atm4) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm1))) &
    3688       154212 :                   found = .TRUE.
    3689              :             CASE ("Improper")
    3690       154212 :                IF (INDEX(array(i) (21:39), "Improper") == 0) CYCLE
    3691         9684 :                my_atm1 = array(i) (41:49)
    3692         9684 :                my_atm2 = array(i) (51:59)
    3693         9684 :                my_atm3 = array(i) (61:69)
    3694         9684 :                my_atm4 = array(i) (71:79)
    3695         9684 :                CALL compress(my_atm1, .TRUE.)
    3696         9684 :                CALL compress(my_atm2, .TRUE.)
    3697         9684 :                CALL compress(my_atm3, .TRUE.)
    3698         9684 :                CALL compress(my_atm4, .TRUE.)
    3699              :                IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm4)) .OR. &
    3700              :                    ((atm1 == my_atm1) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm4)) .OR. &
    3701              :                    ((atm1 == my_atm1) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm4) .AND. (atm4 == my_atm3)) .OR. &
    3702              :                    ((atm1 == my_atm1) .AND. (atm2 == my_atm4) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm2)) .OR. &
    3703         9684 :                    ((atm1 == my_atm1) .AND. (atm2 == my_atm4) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm3)) .OR. &
    3704              :                    ((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm4) .AND. (atm4 == my_atm3))) &
    3705       483920 :                   found = .TRUE.
    3706              : 
    3707              :             CASE ("Out of plane bend")
    3708       483920 :                IF (INDEX(array(i) (21:39), "Out of plane bend") == 0) CYCLE
    3709        27416 :                my_atm1 = array(i) (41:49)
    3710        27416 :                my_atm2 = array(i) (51:59)
    3711        27416 :                my_atm3 = array(i) (61:69)
    3712        27416 :                my_atm4 = array(i) (71:79)
    3713        27416 :                CALL compress(my_atm1, .TRUE.)
    3714        27416 :                CALL compress(my_atm2, .TRUE.)
    3715        27416 :                CALL compress(my_atm3, .TRUE.)
    3716        27416 :                CALL compress(my_atm4, .TRUE.)
    3717        27416 :                IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm4)) .OR. &
    3718              :                    ((atm1 == my_atm1) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm4))) &
    3719            8 :                   found = .TRUE.
    3720              : 
    3721              :             CASE ("Charge")
    3722            8 :                IF (INDEX(array(i) (21:39), "Charge") == 0) CYCLE
    3723            8 :                my_atm1 = array(i) (41:49)
    3724            8 :                CALL compress(my_atm1, .TRUE.)
    3725            8 :                IF (atm1 == my_atm1) found = .TRUE.
    3726              :             CASE ("Spline_Bond_Env", "Spline_Non_Bond_Env")
    3727        18826 :                IF (INDEX(array(i) (21:39), "Spline_") == 0) CYCLE
    3728         6571 :                fmt = 0
    3729         6571 :                my_atm1 = array(i) (41:49)
    3730         6571 :                my_atm2 = array(i) (51:59)
    3731         6571 :                CALL compress(my_atm1, .TRUE.)
    3732         6571 :                CALL compress(my_atm2, .TRUE.)
    3733         6571 :                IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2)) .OR. &
    3734            0 :                    ((atm1 == my_atm2) .AND. (atm2 == my_atm1))) found = .TRUE.
    3735              :             CASE DEFAULT
    3736              :                ! Should never reach this point
    3737     19470546 :                CPABORT("")
    3738              :             END SELECT
    3739     18316619 :             IF (found) EXIT
    3740              :          END DO
    3741              :       END IF
    3742       171162 :       IF (.NOT. found) THEN
    3743        21074 :          nsize = nsize + 1
    3744        21074 :          CALL reallocate(array, 1, nsize)
    3745           12 :          SELECT CASE (fmt)
    3746              :          CASE (1)
    3747           12 :             WRITE (array(nsize), FMT=TRIM(my_format)) atm1
    3748              :          CASE (2)
    3749         1503 :             WRITE (array(nsize), FMT=TRIM(my_format)) atm1, atm2
    3750              :          CASE (3)
    3751        11672 :             WRITE (array(nsize), FMT=TRIM(my_format)) atm1, atm2, atm3
    3752              :          CASE (4)
    3753        21074 :             WRITE (array(nsize), FMT=TRIM(my_format)) atm1, atm2, atm3, atm4
    3754              :          END SELECT
    3755              :       END IF
    3756              : 
    3757       171162 :    END SUBROUTINE store_FF_missing_par
    3758              : 
    3759              : ! **************************************************************************************************
    3760              : !> \brief Search sorted 2d array of integers for a first occurence of value `val` in row `row`
    3761              : !> \param array 2d array of integers
    3762              : !> \param val value to search
    3763              : !> \param row row to search, default = 1
    3764              : !> \return column index if `val` is found in the row `row` of `array`; zero otherwise
    3765              : ! **************************************************************************************************
    3766        45098 :    FUNCTION bsearch_leftmost_2d(array, val, row) RESULT(res)
    3767              :       INTEGER, INTENT(IN)                                :: array(:, :), val
    3768              :       INTEGER, INTENT(IN), OPTIONAL                      :: row
    3769              :       INTEGER                                            :: res
    3770              : 
    3771              :       INTEGER                                            :: left, locRow, mid, right
    3772              : 
    3773        45098 :       locRow = 1
    3774        45098 :       IF (PRESENT(row)) locRow = row
    3775              : 
    3776        45098 :       left = 1
    3777        90196 :       right = UBOUND(array, dim=2)
    3778              : 
    3779       571050 :       DO WHILE (left < right)
    3780       525952 :          mid = (left + right)/2
    3781       571050 :          IF (array(locRow, mid) < val) THEN
    3782       349610 :             left = mid + 1
    3783              :          ELSE
    3784              :             right = mid
    3785              :          END IF
    3786              :       END DO
    3787              : 
    3788        45098 :       res = left
    3789              : 
    3790              :       ! Not found:
    3791        45098 :       IF (array(locRow, res) /= val) res = 0
    3792              : 
    3793        45098 :    END FUNCTION bsearch_leftmost_2d
    3794              : 
    3795              : END MODULE force_fields_all
        

Generated by: LCOV version 2.0-1