LCOV - code coverage report
Current view: top level - src - force_fields_all.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 93.3 % 1673 1561
Test Date: 2025-12-04 06:27:48 Functions: 100.0 % 25 25

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

Generated by: LCOV version 2.0-1