LCOV - code coverage report
Current view: top level - src - topology_connectivity_util.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:ccc2433) Lines: 884 953 92.8 %
Date: 2024-04-25 07:09:54 Functions: 3 3 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Collection of subroutine needed for topology related things
      10             : !> \par History
      11             : !>     jgh (23-05-2004) Last atom of molecule information added
      12             : ! **************************************************************************************************
      13             : 
      14             : MODULE topology_connectivity_util
      15             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      16             :                                               cp_logger_get_default_io_unit,&
      17             :                                               cp_logger_type
      18             :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      19             :                                               cp_print_key_unit_nr
      20             :    USE force_field_kind_types,          ONLY: do_ff_charmm,&
      21             :                                               do_ff_harmonic
      22             :    USE input_constants,                 ONLY: do_conn_g87,&
      23             :                                               do_conn_g96,&
      24             :                                               do_conn_user
      25             :    USE input_section_types,             ONLY: section_vals_type,&
      26             :                                               section_vals_val_get
      27             :    USE kinds,                           ONLY: default_string_length
      28             :    USE memory_utilities,                ONLY: reallocate
      29             :    USE molecule_kind_types,             ONLY: &
      30             :         allocate_molecule_kind_set, atom_type, bend_type, bond_type, get_molecule_kind, impr_type, &
      31             :         molecule_kind_type, opbend_type, set_molecule_kind, torsion_type, ub_type
      32             :    USE molecule_types,                  ONLY: allocate_molecule_set,&
      33             :                                               get_molecule,&
      34             :                                               local_states_type,&
      35             :                                               molecule_type,&
      36             :                                               set_molecule,&
      37             :                                               set_molecule_set
      38             :    USE string_table,                    ONLY: id2str
      39             :    USE topology_types,                  ONLY: atom_info_type,&
      40             :                                               connectivity_info_type,&
      41             :                                               topology_parameters_type
      42             :    USE util,                            ONLY: sort
      43             : #include "./base/base_uses.f90"
      44             : 
      45             :    IMPLICIT NONE
      46             : 
      47             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'topology_connectivity_util'
      48             : 
      49             :    PRIVATE
      50             :    PUBLIC :: topology_connectivity_pack, topology_conn_multiple
      51             : 
      52             : CONTAINS
      53             : 
      54             : ! **************************************************************************************************
      55             : !> \brief topology connectivity pack
      56             : !> \param molecule_kind_set ...
      57             : !> \param molecule_set ...
      58             : !> \param topology ...
      59             : !> \param subsys_section ...
      60             : !> \par History 11/2009 (Louis Vanduyhuys): added Out of Plane bends based on
      61             : !>                                      impropers in topology
      62             : ! **************************************************************************************************
      63        9374 :    SUBROUTINE topology_connectivity_pack(molecule_kind_set, molecule_set, &
      64             :                                          topology, subsys_section)
      65             :       TYPE(molecule_kind_type), DIMENSION(:), POINTER    :: molecule_kind_set
      66             :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
      67             :       TYPE(topology_parameters_type), INTENT(INOUT)      :: topology
      68             :       TYPE(section_vals_type), POINTER                   :: subsys_section
      69             : 
      70             :       CHARACTER(len=*), PARAMETER :: routineN = 'topology_connectivity_pack'
      71             : 
      72             :       CHARACTER(LEN=default_string_length)               :: name
      73             :       INTEGER :: counter, first, handle, handle2, i, ibend, ibond, idim, iimpr, ikind, imol, &
      74             :          inter_bends, inter_bonds, inter_imprs, inter_torsions, inter_ubs, intra_bends, &
      75             :          intra_bonds, intra_imprs, intra_torsions, intra_ubs, inum, ires, istart_mol, istart_typ, &
      76             :          itorsion, ityp, iub, iw, j, j1, j2, j3, j4, jind, last, min_index, natom, nelectron, &
      77             :          nsgf, nval_tot1, nval_tot2, nvar1, nvar2, output_unit, stat
      78        9374 :       INTEGER, DIMENSION(:), POINTER :: c_var_a, c_var_b, c_var_c, c_var_d, c_var_type, &
      79        9374 :          first_list, last_list, map_atom_mol, map_atom_type, map_cvar_mol, map_cvars, map_var_mol, &
      80        9374 :          map_vars, molecule_list
      81        9374 :       INTEGER, DIMENSION(:, :), POINTER                  :: bnd_ctype, bnd_type
      82             :       LOGICAL                                            :: found, found_last
      83             :       TYPE(atom_info_type), POINTER                      :: atom_info
      84        9374 :       TYPE(atom_type), DIMENSION(:), POINTER             :: atom_list
      85        9374 :       TYPE(bend_type), DIMENSION(:), POINTER             :: bend_list
      86        9374 :       TYPE(bond_type), DIMENSION(:), POINTER             :: bond_list
      87             :       TYPE(connectivity_info_type), POINTER              :: conn_info
      88             :       TYPE(cp_logger_type), POINTER                      :: logger
      89        9374 :       TYPE(impr_type), DIMENSION(:), POINTER             :: impr_list
      90        9374 :       TYPE(local_states_type), DIMENSION(:), POINTER     :: lmi
      91             :       TYPE(molecule_kind_type), POINTER                  :: molecule_kind
      92             :       TYPE(molecule_type), POINTER                       :: molecule
      93        9374 :       TYPE(opbend_type), DIMENSION(:), POINTER           :: opbend_list
      94        9374 :       TYPE(torsion_type), DIMENSION(:), POINTER          :: torsion_list
      95        9374 :       TYPE(ub_type), DIMENSION(:), POINTER               :: ub_list
      96             : 
      97        9374 :       NULLIFY (logger)
      98       18748 :       logger => cp_get_default_logger()
      99        9374 :       output_unit = cp_logger_get_default_io_unit(logger)
     100             :       iw = cp_print_key_unit_nr(logger, subsys_section, "PRINT%TOPOLOGY_INFO/UTIL_INFO", &
     101        9374 :                                 extension=".subsysLog")
     102        9374 :       CALL timeset(routineN, handle)
     103             : 
     104        9374 :       atom_info => topology%atom_info
     105        9374 :       conn_info => topology%conn_info
     106       28122 :       ALLOCATE (map_atom_mol(topology%natoms))
     107       28122 :       ALLOCATE (map_atom_type(topology%natoms))
     108             :       !-----------------------------------------------------------------------------
     109             :       !-----------------------------------------------------------------------------
     110             :       ! 1. Set the topology%[nmol_type,nmol,nmol_conn]
     111             :       !-----------------------------------------------------------------------------
     112        9374 :       CALL timeset(routineN//"_1", handle2)
     113        9374 :       natom = topology%natoms
     114        9374 :       topology%nmol = 1
     115        9374 :       topology%nmol_type = 1
     116        9374 :       topology%nmol_conn = 0
     117      759871 :       map_atom_mol = -1
     118      759871 :       map_atom_type = -1
     119        9374 :       map_atom_mol(1) = 1
     120        9374 :       map_atom_type(1) = 1
     121      750497 :       DO i = 1, natom - 1
     122      741123 :          IF ((atom_info%map_mol_typ(i + 1) /= atom_info%map_mol_typ(i)) .OR. &
     123             :              ((atom_info%map_mol_res(i + 1) /= atom_info%map_mol_res(i)) .AND. &
     124             :               (.NOT. (topology%conn_type == do_conn_user)))) THEN
     125      123005 :             topology%nmol_type = topology%nmol_type + 1
     126             :          END IF
     127      741123 :          map_atom_type(i + 1) = topology%nmol_type
     128             :          IF ((atom_info%map_mol_typ(i + 1) /= atom_info%map_mol_typ(i)) .OR. &
     129      741123 :              (atom_info%map_mol_num(i + 1) /= atom_info%map_mol_num(i)) .OR. &
     130             :              (atom_info%map_mol_res(i + 1) /= atom_info%map_mol_res(i))) THEN
     131      290958 :             topology%nmol = topology%nmol + 1
     132             :          END IF
     133      741123 :          map_atom_mol(i + 1) = topology%nmol
     134             :          IF ((atom_info%map_mol_typ(i + 1) == atom_info%map_mol_typ(i)) .AND. &
     135      741123 :              (atom_info%map_mol_num(i + 1) == atom_info%map_mol_num(i)) .AND. &
     136        9374 :              (atom_info%map_mol_res(i + 1) /= atom_info%map_mol_res(i))) THEN
     137        2832 :             topology%nmol_conn = topology%nmol_conn + 1
     138             :          END IF
     139             :       END DO
     140        9374 :       IF (iw > 0) WRITE (iw, *) "topology%nmol ::", topology%nmol
     141        9374 :       IF (iw > 0) WRITE (iw, *) "topology%nmol_type ::", topology%nmol_type
     142        9374 :       IF (iw > 0) WRITE (iw, *) "topology%nmol_conn ::", topology%nmol_conn
     143        9374 :       CALL timestop(handle2)
     144             :       !-----------------------------------------------------------------------------
     145             :       !-----------------------------------------------------------------------------
     146             :       ! 1.1 Clean the temporary arrays to avoid quadratic loops around
     147             :       !     after this fix all topology_pack will be linear scaling
     148             :       !-----------------------------------------------------------------------------
     149        9374 :       CALL timeset(routineN//"_1.1", handle2)
     150        9374 :       istart_mol = map_atom_mol(1)
     151        9374 :       istart_typ = map_atom_type(1)
     152      750497 :       DO i = 2, natom
     153      750497 :          IF ((map_atom_mol(i) /= istart_mol) .AND. (map_atom_type(i) == istart_typ)) THEN
     154      493297 :             map_atom_mol(i) = -map_atom_mol(i)
     155      247826 :          ELSE IF (map_atom_type(i) /= istart_typ) THEN
     156      123005 :             istart_mol = map_atom_mol(i)
     157      123005 :             istart_typ = map_atom_type(i)
     158             :          END IF
     159             :       END DO
     160        9374 :       CALL timestop(handle2)
     161             :       !-----------------------------------------------------------------------------
     162             :       !-----------------------------------------------------------------------------
     163             :       ! 2. Allocate the molecule_kind_set
     164             :       !-----------------------------------------------------------------------------
     165        9374 :       CALL timeset(routineN//"_2", handle2)
     166        9374 :       IF (topology%nmol_type <= 0) THEN
     167           0 :          CPABORT("No molecule kind defined")
     168             :       ELSE
     169        9374 :          NULLIFY (molecule_kind_set)
     170        9374 :          i = topology%nmol_type
     171        9374 :          CALL allocate_molecule_kind_set(molecule_kind_set, i)
     172        9400 :          IF (iw > 0) WRITE (iw, *) "    Allocated molecule_kind_set, Dimenstion of ", &
     173          52 :             SIZE(molecule_kind_set)
     174             :       END IF
     175        9374 :       CALL timestop(handle2)
     176             :       !-----------------------------------------------------------------------------
     177             :       !-----------------------------------------------------------------------------
     178             :       ! 3. Allocate the molecule_set
     179             :       !-----------------------------------------------------------------------------
     180        9374 :       CALL timeset(routineN//"_3", handle2)
     181        9374 :       IF (topology%nmol <= 0) THEN
     182           0 :          CPABORT("No molecule defined")
     183             :       ELSE
     184        9374 :          NULLIFY (molecule_set)
     185        9374 :          i = topology%nmol
     186        9374 :          CALL allocate_molecule_set(molecule_set, i)
     187        9400 :          IF (iw > 0) WRITE (iw, *) "    Allocated molecule_set, dimension of ", &
     188          52 :             topology%nmol
     189             :       END IF
     190        9374 :       CALL timestop(handle2)
     191             :       !-----------------------------------------------------------------------------
     192             :       !-----------------------------------------------------------------------------
     193             :       ! 4. Set the molecule_kind_set%[kind_number,name,nsgf,nelectron]
     194             :       !-----------------------------------------------------------------------------
     195        9374 :       CALL timeset(routineN//"_4", handle2)
     196        9374 :       natom = topology%natoms
     197        9374 :       ikind = -1
     198      759871 :       DO i = 1, natom
     199      759871 :          IF (ikind /= map_atom_type(i)) THEN
     200      132379 :             ikind = map_atom_type(i)
     201      132379 :             molecule_kind => molecule_kind_set(ikind)
     202      132379 :             nsgf = 0
     203      132379 :             nelectron = 0
     204      132379 :             name = TRIM(id2str(atom_info%id_molname(i)))
     205             :             CALL set_molecule_kind(molecule_kind=molecule_kind, &
     206             :                                    kind_number=ikind, &
     207             :                                    molname_generated=topology%molname_generated, &
     208             :                                    name=TRIM(name), &
     209             :                                    nsgf=nsgf, &
     210      132379 :                                    nelectron=nelectron)
     211             :          END IF
     212             :       END DO
     213        9374 :       CALL timestop(handle2)
     214             :       !-----------------------------------------------------------------------------
     215             :       !-----------------------------------------------------------------------------
     216             :       ! 5. Set the molecule_list for molecule_kind in molecule_kind_set
     217             :       !-----------------------------------------------------------------------------
     218        9374 :       CALL timeset(routineN//"_5", handle2)
     219        9374 :       natom = topology%natoms
     220        9374 :       ikind = map_atom_type(1)
     221        9374 :       imol = ABS(map_atom_mol(1))
     222        9374 :       counter = 0
     223      285944 :       DO i = 1, natom - 1
     224      279289 :          IF (ikind /= map_atom_type(i + 1)) THEN
     225      123005 :             found = .TRUE.
     226      123005 :             found_last = .FALSE.
     227      123005 :             imol = ABS(map_atom_mol(i))
     228      156284 :          ELSEIF (ikind == topology%nmol_type) THEN
     229        2719 :             found = .TRUE.
     230        2719 :             found_last = .TRUE.
     231        2719 :             imol = ABS(map_atom_mol(natom))
     232             :          ELSE
     233             :             found = .FALSE.
     234             :             found_last = .FALSE.
     235             :          END IF
     236             : 
     237        9374 :          IF (found) THEN
     238      377172 :             ALLOCATE (molecule_list(imol - counter))
     239      419401 :             DO j = 1, SIZE(molecule_list)
     240      419401 :                molecule_list(j) = j + counter
     241             :             END DO
     242      125724 :             molecule_kind => molecule_kind_set(ikind)
     243             :             CALL set_molecule_kind(molecule_kind=molecule_kind, &
     244      125724 :                                    molecule_list=molecule_list)
     245      125724 :             IF (iw > 0) WRITE (iw, *) "      molecule_list", ikind, molecule_list(:)
     246      125724 :             IF (found_last) EXIT
     247      123005 :             counter = imol
     248      123005 :             ikind = map_atom_type(i + 1)
     249             :          END IF
     250             :       END DO
     251             :       ! Treat separately the case in which the last atom is also a molecule
     252        9374 :       IF (i == natom) THEN
     253        6655 :          imol = ABS(map_atom_mol(natom))
     254             :          ! Last atom is also a molecule by itself
     255       19965 :          ALLOCATE (molecule_list(imol - counter))
     256       13310 :          DO j = 1, SIZE(molecule_list)
     257       13310 :             molecule_list(j) = j + counter
     258             :          END DO
     259        6655 :          molecule_kind => molecule_kind_set(ikind)
     260             :          CALL set_molecule_kind(molecule_kind=molecule_kind, &
     261        6655 :                                 molecule_list=molecule_list)
     262        6655 :          IF (iw > 0) WRITE (iw, *) "      molecule_list", ikind, molecule_list(:)
     263             :       END IF
     264        9374 :       CALL timestop(handle2)
     265             :       !-----------------------------------------------------------------------------
     266             :       !-----------------------------------------------------------------------------
     267             :       ! 6. Set the molecule_set(imol)%molecule_kind via set_molecule
     268             :       !-----------------------------------------------------------------------------
     269        9374 :       CALL timeset(routineN//"_6", handle2)
     270      141753 :       DO ikind = 1, SIZE(molecule_kind_set)
     271      132379 :          molecule_kind => molecule_kind_set(ikind)
     272             :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
     273      132379 :                                 molecule_list=molecule_list)
     274      442085 :          DO i = 1, SIZE(molecule_list)
     275      300332 :             molecule => molecule_set(molecule_list(i))
     276      432711 :             CALL set_molecule(molecule, molecule_kind=molecule_kind)
     277             :          END DO
     278             :       END DO
     279        9374 :       CALL timestop(handle2)
     280             :       !-----------------------------------------------------------------------------
     281             :       !-----------------------------------------------------------------------------
     282             :       ! 7. Set the molecule_set(imol)%[first_atom,last_atom] via set_molecule_set
     283             :       !-----------------------------------------------------------------------------
     284       28122 :       ALLOCATE (first_list(SIZE(molecule_set)))
     285       28122 :       ALLOCATE (last_list(SIZE(molecule_set)))
     286        9374 :       CALL timeset(routineN//"_7", handle2)
     287      309706 :       first_list(:) = 0
     288      309706 :       last_list(:) = 0
     289        9374 :       ityp = atom_info%map_mol_typ(1)
     290        9374 :       inum = atom_info%map_mol_num(1)
     291        9374 :       ires = atom_info%map_mol_res(1)
     292        9374 :       imol = 1
     293        9374 :       first_list(1) = 1
     294      750497 :       DO j = 2, natom
     295             :          IF ((atom_info%map_mol_typ(j) /= ityp) .OR. &
     296      741123 :              (atom_info%map_mol_num(j) /= inum) .OR. &
     297        9374 :              (atom_info%map_mol_res(j) /= ires)) THEN
     298      290958 :             ityp = atom_info%map_mol_typ(j)
     299      290958 :             inum = atom_info%map_mol_num(j)
     300      290958 :             ires = atom_info%map_mol_res(j)
     301      290958 :             imol = imol + 1
     302      290958 :             first_list(imol) = j
     303             :          END IF
     304             :       END DO
     305        9374 :       CPASSERT(imol == topology%nmol)
     306      300332 :       DO ikind = 1, topology%nmol - 1
     307      300332 :          last_list(ikind) = first_list(ikind + 1) - 1
     308             :       END DO
     309        9374 :       last_list(topology%nmol) = topology%natoms
     310        9374 :       CALL set_molecule_set(molecule_set, first_list, last_list)
     311        9374 :       CALL timestop(handle2)
     312             :       !-----------------------------------------------------------------------------
     313             :       !-----------------------------------------------------------------------------
     314             :       ! 8. Set and NULLIFY the molecule_set(imol)%lmi via set_molecule_set
     315             :       !-----------------------------------------------------------------------------
     316        9374 :       CALL timeset(routineN//"_8", handle2)
     317      309706 :       DO imol = 1, SIZE(molecule_set)
     318      300332 :          molecule => molecule_set(imol)
     319      300332 :          NULLIFY (lmi)
     320      309706 :          CALL set_molecule(molecule, lmi=lmi)
     321             :       END DO
     322        9374 :       CALL timestop(handle2)
     323             :       !-----------------------------------------------------------------------------
     324             :       !-----------------------------------------------------------------------------
     325             :       ! 9. Set the atom_list for molecule_kind in molecule_kind_set (PART 1)
     326             :       !-----------------------------------------------------------------------------
     327        9374 :       CALL timeset(routineN//"_9", handle2)
     328        9374 :       counter = 0
     329      309706 :       DO imol = 1, SIZE(molecule_set)
     330      300332 :          molecule => molecule_set(imol)
     331      300332 :          molecule_kind => molecule_set(imol)%molecule_kind
     332             :          CALL get_molecule_kind(molecule_kind=molecule_kind, &
     333      300332 :                                 kind_number=i)
     334      309706 :          IF (counter /= i) THEN
     335      132379 :             counter = i
     336             :             CALL get_molecule(molecule=molecule, &
     337      132379 :                               first_atom=first, last_atom=last)
     338      132379 :             natom = 0
     339      132379 :             IF (first /= 0 .AND. last /= 0) natom = last - first + 1
     340      654337 :             ALLOCATE (atom_list(natom))
     341      389579 :             DO i = 1, natom
     342             :                !Atomic kind information will be filled in (PART 2)
     343      257200 :                NULLIFY (atom_list(i)%atomic_kind)
     344      257200 :                atom_list(i)%id_name = atom_info%id_atmname(i + first - 1)
     345      257990 :                IF (iw > 0) WRITE (iw, '(5X,A,3I5,1X,A5)') "atom_list ", &
     346      133959 :                   imol, counter, i, TRIM(id2str(atom_list(i)%id_name))
     347             :             END DO
     348      132379 :             CALL set_molecule_kind(molecule_kind=molecule_kind, atom_list=atom_list)
     349             :          END IF
     350             :       END DO
     351        9374 :       CALL timestop(handle2)
     352             :       !-----------------------------------------------------------------------------
     353             :       !-----------------------------------------------------------------------------
     354             :       ! 10. Set the molecule_kind%[nbond,bond_list] via set_molecule_kind
     355             :       !-----------------------------------------------------------------------------
     356        9374 :       CALL timeset(routineN//"_10", handle2)
     357             :       ! First map bonds on molecules
     358        9374 :       nvar1 = 0
     359        9374 :       nvar2 = 0
     360        9374 :       NULLIFY (map_vars, map_cvars, bnd_type, bnd_ctype)
     361        9374 :       IF (ASSOCIATED(conn_info%bond_a)) nvar1 = SIZE(conn_info%bond_a)
     362        9374 :       IF (ASSOCIATED(conn_info%c_bond_a)) nvar2 = SIZE(conn_info%c_bond_a)
     363        9374 :       nval_tot1 = nvar1
     364        9374 :       nval_tot2 = 0
     365       21261 :       ALLOCATE (map_var_mol(nvar1))
     366       18902 :       ALLOCATE (map_cvar_mol(nvar2))
     367      517551 :       map_var_mol = -1
     368       12240 :       map_cvar_mol = -1
     369      517551 :       DO i = 1, nvar1
     370      508177 :          j1 = map_atom_mol(conn_info%bond_a(i))
     371      508177 :          j2 = map_atom_mol(conn_info%bond_b(i))
     372      517551 :          IF (j1 == j2) THEN
     373      505311 :             IF (j1 > 0) map_var_mol(i) = map_atom_type(conn_info%bond_a(i))
     374             :          END IF
     375             :       END DO
     376       12240 :       DO i = 1, nvar2
     377        2866 :          min_index = MIN(conn_info%c_bond_a(i), conn_info%c_bond_b(i))
     378        2866 :          j1 = map_atom_mol(min_index)
     379       12240 :          IF (j1 > 0) map_cvar_mol(i) = map_atom_type(min_index)
     380             :       END DO
     381        9374 :       CALL find_bnd_typ(topology%nmol_type, map_vars, map_var_mol, bnd_type, nvar1)
     382        9374 :       CALL find_bnd_typ(topology%nmol_type, map_cvars, map_cvar_mol, bnd_ctype, nvar2)
     383      141753 :       DO i = 1, topology%nmol_type
     384      132379 :          intra_bonds = 0
     385      132379 :          inter_bonds = 0
     386      192881 :          IF (ALL(bnd_type(:, i) > 0)) THEN
     387       30251 :             intra_bonds = bnd_type(2, i) - bnd_type(1, i) + 1
     388             :          END IF
     389      138047 :          IF (ALL(bnd_ctype(:, i) > 0)) THEN
     390        2834 :             inter_bonds = bnd_ctype(2, i) - bnd_ctype(1, i) + 1
     391             :          END IF
     392      132379 :          ibond = intra_bonds + inter_bonds
     393      132379 :          IF (iw > 0) THEN
     394         434 :             WRITE (iw, *) "    Total number bonds for molecule type ", i, " :", ibond
     395         434 :             WRITE (iw, *) "    intra (bonds inside  molecules) :: ", intra_bonds
     396         434 :             WRITE (iw, *) "    inter (bonds between molecules) :: ", inter_bonds
     397             :          END IF
     398      132379 :          molecule_kind => molecule_kind_set(i)
     399      132379 :          nval_tot2 = nval_tot2 + ibond*SIZE(molecule_kind%molecule_list)
     400             : 
     401      411152 :          ALLOCATE (bond_list(ibond))
     402      132379 :          ibond = 0
     403      347782 :          DO j = bnd_type(1, i), bnd_type(2, i)
     404      215403 :             IF (j == 0) CYCLE
     405      113275 :             ibond = ibond + 1
     406      113275 :             jind = map_vars(j)
     407      113275 :             first = first_list(map_atom_mol(conn_info%bond_a(jind)))
     408      113275 :             bond_list(ibond)%a = conn_info%bond_a(jind) - first + 1
     409      113275 :             bond_list(ibond)%b = conn_info%bond_b(jind) - first + 1
     410             :             ! Set by default id_type to charmm and modify when handling the forcefield
     411      113275 :             bond_list(ibond)%id_type = do_ff_charmm
     412      113275 :             IF ((topology%conn_type == do_conn_g96) .OR. (topology%conn_type == do_conn_g87)) THEN
     413         132 :                bond_list(ibond)%itype = conn_info%bond_type(jind)
     414             :             END IF
     415             :             !point this to the right bond_kind_type if using force field
     416      113275 :             NULLIFY (bond_list(ibond)%bond_kind)
     417      245654 :             IF (iw > 0) THEN
     418         135 :                WRITE (iw, '(7X,A,I3,1X,A,I5,I5,1X,A,I5,I5)') "molecule_kind", &
     419         135 :                   i, "  intra bond", &
     420         135 :                   conn_info%bond_a(jind), &
     421         135 :                   conn_info%bond_b(jind), &
     422         135 :                   "offset number at", &
     423         135 :                   conn_info%bond_a(jind) - first + 1, &
     424         270 :                   conn_info%bond_b(jind) - first + 1
     425             :             END IF
     426             :          END DO
     427      264790 :          DO j = bnd_ctype(1, i), bnd_ctype(2, i)
     428      132411 :             IF (j == 0) CYCLE
     429        2866 :             ibond = ibond + 1
     430        2866 :             jind = map_cvars(j)
     431        2866 :             min_index = MIN(conn_info%c_bond_a(jind), conn_info%c_bond_b(jind))
     432        2866 :             first = first_list(map_atom_mol(min_index))
     433        2866 :             bond_list(ibond)%a = conn_info%c_bond_a(jind) - first + 1
     434        2866 :             bond_list(ibond)%b = conn_info%c_bond_b(jind) - first + 1
     435             :             ! Set by default id_type to charmm and modify when handling the forcefield
     436        2866 :             bond_list(ibond)%id_type = do_ff_charmm
     437        2866 :             IF ((topology%conn_type == do_conn_g96) .OR. (topology%conn_type == do_conn_g87)) THEN
     438           0 :                bond_list(ibond)%itype = conn_info%c_bond_type(jind)
     439             :             END IF
     440             :             !point this to the right bond_kind_type if using force field
     441        2866 :             NULLIFY (bond_list(ibond)%bond_kind)
     442      135245 :             IF (iw > 0) THEN
     443           2 :                WRITE (iw, '(7X,A,I3,1X,A,I5,I5,1X,A,I5,I5)') "molecule_kind", &
     444           2 :                   i, " inter bond", &
     445           2 :                   conn_info%c_bond_a(jind), &
     446           2 :                   conn_info%c_bond_b(jind), &
     447           2 :                   "offset number at", &
     448           2 :                   conn_info%c_bond_a(jind) - first + 1, &
     449           4 :                   conn_info%c_bond_b(jind) - first + 1
     450             :             END IF
     451             :          END DO
     452             :          CALL set_molecule_kind(molecule_kind=molecule_kind, &
     453      141753 :                                 nbond=SIZE(bond_list), bond_list=bond_list)
     454             :       END DO
     455        9374 :       IF ((nval_tot1 /= nval_tot2) .AND. (output_unit > 0)) THEN
     456           0 :          WRITE (output_unit, '(/)')
     457           0 :          WRITE (output_unit, '(T5,A)') "ERROR| Mismatching found between the total number  of atoms"
     458           0 :          WRITE (output_unit, '(T5,A)') "ERROR| and the number of atoms computed multiplying the Nr."
     459           0 :          WRITE (output_unit, '(T5,A)') "ERROR| of molecules by the  number of atoms  building  that"
     460           0 :          WRITE (output_unit, '(T5,A)') "ERROR| kind of molecule."
     461           0 :          WRITE (output_unit, '(T5,A)') "ERROR| This happens when the connectivity is wrongly  built"
     462           0 :          WRITE (output_unit, '(T5,A)') "ERROR| One example could be two same kind of molecules have"
     463           0 :          WRITE (output_unit, '(T5,A)') "ERROR| a different number of atoms. Check the connectivity!"
     464             :       END IF
     465        9374 :       CPASSERT(nval_tot1 == nval_tot2)
     466        9374 :       DEALLOCATE (map_var_mol)
     467        9374 :       DEALLOCATE (map_cvar_mol)
     468        9374 :       DEALLOCATE (map_vars)
     469        9374 :       DEALLOCATE (map_cvars)
     470        9374 :       DEALLOCATE (bnd_type)
     471        9374 :       DEALLOCATE (bnd_ctype)
     472        9374 :       CALL timestop(handle2)
     473             :       !-----------------------------------------------------------------------------
     474             :       !-----------------------------------------------------------------------------
     475             :       ! 11. Set the molecule_kind%[nbend,bend_list] via set_molecule_kind
     476             :       !-----------------------------------------------------------------------------
     477             :       ! Allocate c_var_a, c_var_b, c_var_c, c_var_type
     478        9374 :       CALL timeset(routineN//"_11_pre", handle2)
     479        9374 :       idim = 0
     480        9374 :       ALLOCATE (c_var_a(idim))
     481        9374 :       ALLOCATE (c_var_b(idim))
     482        9374 :       ALLOCATE (c_var_c(idim))
     483        9374 :       found = ASSOCIATED(conn_info%theta_type)
     484        9374 :       IF (found) THEN
     485          14 :          ALLOCATE (c_var_type(idim))
     486             :       END IF
     487        9374 :       IF (ASSOCIATED(conn_info%c_bond_a) .AND. ASSOCIATED(conn_info%theta_a)) THEN
     488      229336 :          DO j = 1, SIZE(conn_info%theta_a)
     489      222267 :             j1 = map_atom_mol(conn_info%theta_a(j))
     490      222267 :             j2 = map_atom_mol(conn_info%theta_b(j))
     491      222267 :             j3 = map_atom_mol(conn_info%theta_c(j))
     492      229336 :             IF (j1 /= j2 .OR. j2 /= j3) THEN
     493       11392 :                idim = idim + 1
     494             :             END IF
     495             :          END DO
     496        7069 :          CALL reallocate(c_var_a, 1, idim)
     497        7069 :          CALL reallocate(c_var_b, 1, idim)
     498        7069 :          CALL reallocate(c_var_c, 1, idim)
     499        7069 :          IF (found) THEN
     500           0 :             CALL reallocate(c_var_type, 1, idim)
     501             :          END IF
     502        7069 :          idim = 0
     503      229336 :          DO j = 1, SIZE(conn_info%theta_a)
     504      222267 :             j1 = map_atom_mol(conn_info%theta_a(j))
     505      222267 :             j2 = map_atom_mol(conn_info%theta_b(j))
     506      222267 :             j3 = map_atom_mol(conn_info%theta_c(j))
     507      229336 :             IF (j1 /= j2 .OR. j2 /= j3) THEN
     508       11392 :                idim = idim + 1
     509       11392 :                c_var_a(idim) = conn_info%theta_a(j)
     510       11392 :                c_var_b(idim) = conn_info%theta_b(j)
     511       11392 :                c_var_c(idim) = conn_info%theta_c(j)
     512       11392 :                IF (found) THEN
     513           0 :                   c_var_type(idim) = conn_info%theta_type(j)
     514             :                END IF
     515             :             END IF
     516             :          END DO
     517             :       END IF
     518        9374 :       CALL timestop(handle2)
     519        9374 :       CALL timeset(routineN//"_11", handle2)
     520             :       ! map bends on molecules
     521        9374 :       nvar1 = 0
     522        9374 :       nvar2 = 0
     523             :       NULLIFY (map_vars, map_cvars, bnd_type, bnd_ctype)
     524        9374 :       IF (ASSOCIATED(conn_info%theta_a)) nvar1 = SIZE(conn_info%theta_a)
     525        9374 :       IF (ASSOCIATED(c_var_a)) nvar2 = SIZE(c_var_a)
     526        9374 :       nval_tot1 = nvar1
     527        9374 :       nval_tot2 = 0
     528       21095 :       ALLOCATE (map_var_mol(nvar1))
     529       18902 :       ALLOCATE (map_cvar_mol(nvar2))
     530      280867 :       map_var_mol = -1
     531       20766 :       map_cvar_mol = -1
     532      280867 :       DO i = 1, nvar1
     533      271493 :          j1 = map_atom_mol(conn_info%theta_a(i))
     534      271493 :          j2 = map_atom_mol(conn_info%theta_b(i))
     535      271493 :          j3 = map_atom_mol(conn_info%theta_c(i))
     536      280867 :          IF (j1 == j2 .AND. j2 == j3) THEN
     537      260101 :             IF (j1 > 0) map_var_mol(i) = map_atom_type(conn_info%theta_a(i))
     538             :          END IF
     539             :       END DO
     540       20766 :       DO i = 1, nvar2
     541       11392 :          min_index = MIN(c_var_a(i), c_var_b(i), c_var_c(i))
     542       11392 :          j1 = map_atom_mol(min_index)
     543       20766 :          IF (j1 > 0) map_cvar_mol(i) = map_atom_type(min_index)
     544             :       END DO
     545        9374 :       CALL find_bnd_typ(topology%nmol_type, map_vars, map_var_mol, bnd_type, nvar1)
     546        9374 :       CALL find_bnd_typ(topology%nmol_type, map_cvars, map_cvar_mol, bnd_ctype, nvar2)
     547      141753 :       DO i = 1, topology%nmol_type
     548      132379 :          intra_bends = 0
     549      132379 :          inter_bends = 0
     550      191877 :          IF (ALL(bnd_type(:, i) > 0)) THEN
     551       29749 :             intra_bends = bnd_type(2, i) - bnd_type(1, i) + 1
     552             :          END IF
     553      138047 :          IF (ALL(bnd_ctype(:, i) > 0)) THEN
     554        2834 :             inter_bends = bnd_ctype(2, i) - bnd_ctype(1, i) + 1
     555             :          END IF
     556      132379 :          ibend = intra_bends + inter_bends
     557      132379 :          IF (iw > 0) THEN
     558         434 :             WRITE (iw, *) "    Total number of angles for molecule type ", i, " :", ibend
     559         434 :             WRITE (iw, *) "    intra (angles inside  molecules) :: ", intra_bends
     560         434 :             WRITE (iw, *) "    inter (angles between molecules) :: ", inter_bends
     561             :          END IF
     562      132379 :          molecule_kind => molecule_kind_set(i)
     563      132379 :          nval_tot2 = nval_tot2 + ibend*SIZE(molecule_kind%molecule_list)
     564      435207 :          ALLOCATE (bend_list(ibend))
     565      132379 :          ibend = 0
     566      364315 :          DO j = bnd_type(1, i), bnd_type(2, i)
     567      231936 :             IF (j == 0) CYCLE
     568      129306 :             ibend = ibend + 1
     569      129306 :             jind = map_vars(j)
     570      129306 :             first = first_list(map_atom_mol(conn_info%theta_a(jind)))
     571      129306 :             bend_list(ibend)%a = conn_info%theta_a(jind) - first + 1
     572      129306 :             bend_list(ibend)%b = conn_info%theta_b(jind) - first + 1
     573      129306 :             bend_list(ibend)%c = conn_info%theta_c(jind) - first + 1
     574             :             ! Set by default id_type to charmm and modify when handling the forcefield
     575      129306 :             bend_list(ibend)%id_type = do_ff_charmm
     576      129306 :             IF ((topology%conn_type == do_conn_g96) .OR. (topology%conn_type == do_conn_g87)) THEN
     577         158 :                bend_list(ibend)%itype = conn_info%theta_type(jind)
     578             :             END IF
     579             :             !point this to the right bend_kind_type if using force field
     580      129306 :             NULLIFY (bend_list(ibend)%bend_kind)
     581      261685 :             IF (iw > 0) THEN
     582             :                WRITE (iw, '(7X,A,I3,1X,A,I5,I5,I5,1X,A,I5,I5,I5)') &
     583         229 :                   "molecule_kind", ikind, "intra bend", &
     584         229 :                   conn_info%theta_a(jind), &
     585         229 :                   conn_info%theta_b(jind), &
     586         229 :                   conn_info%theta_c(jind), &
     587         229 :                   "offset number at", &
     588         229 :                   conn_info%theta_a(jind) - first + 1, &
     589         229 :                   conn_info%theta_b(jind) - first + 1, &
     590         458 :                   conn_info%theta_c(jind) - first + 1
     591             :             END IF
     592             :          END DO
     593      273316 :          DO j = bnd_ctype(1, i), bnd_ctype(2, i)
     594      140937 :             IF (j == 0) CYCLE
     595       11392 :             ibend = ibend + 1
     596       11392 :             jind = map_cvars(j)
     597       11392 :             min_index = MIN(c_var_a(jind), c_var_b(jind), c_var_c(jind))
     598       11392 :             first = first_list(map_atom_mol(min_index))
     599       11392 :             bend_list(ibend)%a = c_var_a(jind) - first + 1
     600       11392 :             bend_list(ibend)%b = c_var_b(jind) - first + 1
     601       11392 :             bend_list(ibend)%c = c_var_c(jind) - first + 1
     602             :             ! Set by default id_type to charmm and modify when handling the forcefield
     603       11392 :             bend_list(ibend)%id_type = do_ff_charmm
     604       11392 :             IF ((topology%conn_type == do_conn_g96) .OR. (topology%conn_type == do_conn_g87)) THEN
     605           0 :                bend_list(ibend)%itype = c_var_type(jind)
     606             :             END IF
     607             :             !point this to the right bend_kind_type if using force field
     608       11392 :             NULLIFY (bend_list(ibend)%bend_kind)
     609      143771 :             IF (iw > 0) THEN
     610             :                WRITE (iw, '(7X,A,I3,1X,A,I5,I5,I5,1X,A,I5,I5,I5)') &
     611           8 :                   "molecule_kind", ikind, "inter bend", &
     612           8 :                   c_var_a(jind), &
     613           8 :                   c_var_b(jind), &
     614           8 :                   c_var_c(jind), &
     615           8 :                   "offset number at", &
     616           8 :                   c_var_a(jind) - first + 1, &
     617           8 :                   c_var_b(jind) - first + 1, &
     618          16 :                   c_var_c(jind) - first + 1
     619             :             END IF
     620             :          END DO
     621             :          CALL set_molecule_kind(molecule_kind=molecule_kind, &
     622      141753 :                                 nbend=SIZE(bend_list), bend_list=bend_list)
     623             :       END DO
     624        9374 :       CPASSERT(nval_tot1 == nval_tot2)
     625        9374 :       DEALLOCATE (map_var_mol)
     626        9374 :       DEALLOCATE (map_cvar_mol)
     627        9374 :       DEALLOCATE (map_vars)
     628        9374 :       DEALLOCATE (map_cvars)
     629        9374 :       DEALLOCATE (bnd_type)
     630        9374 :       DEALLOCATE (bnd_ctype)
     631        9374 :       DEALLOCATE (c_var_a)
     632        9374 :       DEALLOCATE (c_var_b)
     633        9374 :       DEALLOCATE (c_var_c)
     634        9374 :       IF (found) THEN
     635          14 :          DEALLOCATE (c_var_type)
     636             :       END IF
     637        9374 :       CALL timestop(handle2)
     638             :       !-----------------------------------------------------------------------------
     639             :       !-----------------------------------------------------------------------------
     640             :       ! 12. Set the molecule_kind%[nub,ub_list] via set_molecule_kind
     641             :       !-----------------------------------------------------------------------------
     642        9374 :       CALL timeset(routineN//"_12_pre", handle2)
     643        9374 :       idim = 0
     644        9374 :       ALLOCATE (c_var_a(idim))
     645        9374 :       ALLOCATE (c_var_b(idim))
     646        9374 :       ALLOCATE (c_var_c(idim))
     647        9374 :       IF (ASSOCIATED(conn_info%c_bond_a) .AND. ASSOCIATED(conn_info%ub_a)) THEN
     648      229336 :          DO j = 1, SIZE(conn_info%ub_a)
     649      222267 :             j1 = map_atom_mol(conn_info%ub_a(j))
     650      222267 :             j2 = map_atom_mol(conn_info%ub_b(j))
     651      222267 :             j3 = map_atom_mol(conn_info%ub_c(j))
     652      229336 :             IF (j1 /= j2 .OR. j2 /= j3) THEN
     653       11392 :                idim = idim + 1
     654             :             END IF
     655             :          END DO
     656        7069 :          CALL reallocate(c_var_a, 1, idim)
     657        7069 :          CALL reallocate(c_var_b, 1, idim)
     658        7069 :          CALL reallocate(c_var_c, 1, idim)
     659        7069 :          idim = 0
     660      229336 :          DO j = 1, SIZE(conn_info%ub_a)
     661      222267 :             j1 = map_atom_mol(conn_info%ub_a(j))
     662      222267 :             j2 = map_atom_mol(conn_info%ub_b(j))
     663      222267 :             j3 = map_atom_mol(conn_info%ub_c(j))
     664      229336 :             IF (j1 /= j2 .OR. j2 /= j3) THEN
     665       11392 :                idim = idim + 1
     666       11392 :                c_var_a(idim) = conn_info%ub_a(j)
     667       11392 :                c_var_b(idim) = conn_info%ub_b(j)
     668       11392 :                c_var_c(idim) = conn_info%ub_c(j)
     669             :             END IF
     670             :          END DO
     671             :       END IF
     672        9374 :       CALL timestop(handle2)
     673        9374 :       CALL timeset(routineN//"_12", handle2)
     674             :       ! map UBs on molecules
     675        9374 :       nvar1 = 0
     676        9374 :       nvar2 = 0
     677             :       NULLIFY (map_vars, map_cvars, bnd_type, bnd_ctype)
     678        9374 :       IF (ASSOCIATED(conn_info%ub_a)) nvar1 = SIZE(conn_info%ub_a)
     679        9374 :       IF (ASSOCIATED(c_var_a)) nvar2 = SIZE(c_var_a)
     680        9374 :       nval_tot1 = nvar1
     681        9374 :       nval_tot2 = 0
     682       21081 :       ALLOCATE (map_var_mol(nvar1))
     683       18902 :       ALLOCATE (map_cvar_mol(nvar2))
     684      280709 :       map_var_mol = -1
     685       20766 :       map_cvar_mol = -1
     686      280709 :       DO i = 1, nvar1
     687      271335 :          j1 = map_atom_mol(conn_info%ub_a(i))
     688      271335 :          j2 = map_atom_mol(conn_info%ub_b(i))
     689      271335 :          j3 = map_atom_mol(conn_info%ub_c(i))
     690      280709 :          IF (j1 == j2 .AND. j2 == j3) THEN
     691      259943 :             IF (j1 > 0) map_var_mol(i) = map_atom_type(conn_info%ub_a(i))
     692             :          END IF
     693             :       END DO
     694       20766 :       DO i = 1, nvar2
     695       11392 :          min_index = MIN(c_var_a(i), c_var_b(i), c_var_c(i))
     696       11392 :          j1 = map_atom_mol(min_index)
     697       20766 :          IF (j1 > 0) map_cvar_mol(i) = map_atom_type(min_index)
     698             :       END DO
     699        9374 :       CALL find_bnd_typ(topology%nmol_type, map_vars, map_var_mol, bnd_type, nvar1)
     700        9374 :       CALL find_bnd_typ(topology%nmol_type, map_cvars, map_cvar_mol, bnd_ctype, nvar2)
     701      141753 :       DO i = 1, topology%nmol_type
     702      132379 :          intra_ubs = 0
     703      132379 :          inter_ubs = 0
     704      191849 :          IF (ALL(bnd_type(:, i) > 0)) THEN
     705       29735 :             intra_ubs = bnd_type(2, i) - bnd_type(1, i) + 1
     706             :          END IF
     707      138047 :          IF (ALL(bnd_ctype(:, i) > 0)) THEN
     708        2834 :             inter_ubs = bnd_ctype(2, i) - bnd_ctype(1, i) + 1
     709             :          END IF
     710      132379 :          iub = intra_ubs + inter_ubs
     711      132379 :          IF (iw > 0) THEN
     712         434 :             WRITE (iw, *) "    Total number of Urey-Bradley for molecule type ", i, " :", iub
     713         434 :             WRITE (iw, *) "    intra (UB inside  molecules) :: ", intra_ubs
     714         434 :             WRITE (iw, *) "    inter (UB between molecules) :: ", inter_ubs
     715             :          END IF
     716      132379 :          molecule_kind => molecule_kind_set(i)
     717      132379 :          nval_tot2 = nval_tot2 + iub*SIZE(molecule_kind%molecule_list)
     718      435035 :          ALLOCATE (ub_list(iub))
     719      132379 :          iub = 0
     720      364171 :          DO j = bnd_type(1, i), bnd_type(2, i)
     721      231792 :             IF (j == 0) CYCLE
     722      129148 :             iub = iub + 1
     723      129148 :             jind = map_vars(j)
     724      129148 :             first = first_list(map_atom_mol(conn_info%ub_a(jind)))
     725      129148 :             ub_list(iub)%a = conn_info%ub_a(jind) - first + 1
     726      129148 :             ub_list(iub)%b = conn_info%ub_b(jind) - first + 1
     727      129148 :             ub_list(iub)%c = conn_info%ub_c(jind) - first + 1
     728      129148 :             ub_list(iub)%id_type = do_ff_charmm
     729             :             !point this to the right ub_kind_type if using force field
     730      129148 :             NULLIFY (ub_list(iub)%ub_kind)
     731      261527 :             IF (iw > 0) THEN
     732             :                WRITE (iw, '(7X,A,I3,1X,A,I5,I5,I5,1X,A,I5,I5,I5)') &
     733         229 :                   "molecule_kind", i, "intra UB", &
     734         229 :                   conn_info%ub_a(jind), &
     735         229 :                   conn_info%ub_b(jind), &
     736         229 :                   conn_info%ub_c(jind), &
     737         229 :                   "offset number at", &
     738         229 :                   conn_info%ub_a(jind) - first + 1, &
     739         229 :                   conn_info%ub_b(jind) - first + 1, &
     740         458 :                   conn_info%ub_c(jind) - first + 1
     741             :             END IF
     742             :          END DO
     743      273316 :          DO j = bnd_ctype(1, i), bnd_ctype(2, i)
     744      140937 :             IF (j == 0) CYCLE
     745       11392 :             iub = iub + 1
     746       11392 :             jind = map_cvars(j)
     747       11392 :             min_index = MIN(c_var_a(jind), c_var_b(jind), c_var_c(jind))
     748       11392 :             first = first_list(map_atom_mol(min_index))
     749       11392 :             ub_list(iub)%a = c_var_a(jind) - first + 1
     750       11392 :             ub_list(iub)%b = c_var_b(jind) - first + 1
     751       11392 :             ub_list(iub)%c = c_var_c(jind) - first + 1
     752       11392 :             ub_list(iub)%id_type = do_ff_charmm
     753             :             !point this to the right ub_kind_type if using force field
     754       11392 :             NULLIFY (ub_list(iub)%ub_kind)
     755      143771 :             IF (iw > 0) THEN
     756             :                WRITE (iw, '(7X,A,I3,1X,A,I5,I5,I5,1X,A,I5,I5,I5)') &
     757           8 :                   "molecule_kind", i, "inter UB", &
     758           8 :                   c_var_a(jind), &
     759           8 :                   c_var_b(jind), &
     760           8 :                   c_var_c(jind), &
     761           8 :                   "offset number at", &
     762           8 :                   c_var_a(jind) - first + 1, &
     763           8 :                   c_var_b(jind) - first + 1, &
     764          16 :                   c_var_c(jind) - first + 1
     765             :             END IF
     766             :          END DO
     767             :          CALL set_molecule_kind(molecule_kind=molecule_kind, &
     768      141753 :                                 nub=SIZE(ub_list), ub_list=ub_list)
     769             :       END DO
     770        9374 :       CPASSERT(nval_tot1 == nval_tot2)
     771        9374 :       DEALLOCATE (map_var_mol)
     772        9374 :       DEALLOCATE (map_cvar_mol)
     773        9374 :       DEALLOCATE (map_vars)
     774        9374 :       DEALLOCATE (map_cvars)
     775        9374 :       DEALLOCATE (bnd_type)
     776        9374 :       DEALLOCATE (bnd_ctype)
     777        9374 :       DEALLOCATE (c_var_a)
     778        9374 :       DEALLOCATE (c_var_b)
     779        9374 :       DEALLOCATE (c_var_c)
     780        9374 :       CALL timestop(handle2)
     781             :       !-----------------------------------------------------------------------------
     782             :       !-----------------------------------------------------------------------------
     783             :       ! 13. Set the molecule_kind%[ntorsion,torsion_list] via set_molecule_kind
     784             :       !-----------------------------------------------------------------------------
     785             :       ! Allocate c_var_a, c_var_b, c_var_c, c_var_d, c_var_type
     786        9374 :       CALL timeset(routineN//"_13_pre", handle2)
     787        9374 :       idim = 0
     788        9374 :       ALLOCATE (c_var_a(idim))
     789        9374 :       ALLOCATE (c_var_b(idim))
     790        9374 :       ALLOCATE (c_var_c(idim))
     791        9374 :       ALLOCATE (c_var_d(idim))
     792        9374 :       found = ASSOCIATED(conn_info%phi_type)
     793        9374 :       IF (found) THEN
     794          14 :          ALLOCATE (c_var_type(idim))
     795             :       END IF
     796        9374 :       IF (ASSOCIATED(conn_info%c_bond_a) .AND. ASSOCIATED(conn_info%phi_a)) THEN
     797      141428 :          DO j = 1, SIZE(conn_info%phi_a)
     798      134359 :             j1 = map_atom_mol(conn_info%phi_a(j))
     799      134359 :             j2 = map_atom_mol(conn_info%phi_b(j))
     800      134359 :             j3 = map_atom_mol(conn_info%phi_c(j))
     801      134359 :             j4 = map_atom_mol(conn_info%phi_d(j))
     802      141428 :             IF (j1 /= j2 .OR. j2 /= j3 .OR. j3 /= j4) THEN
     803       31630 :                idim = idim + 1
     804             :             END IF
     805             :          END DO
     806        7069 :          CALL reallocate(c_var_a, 1, idim)
     807        7069 :          CALL reallocate(c_var_b, 1, idim)
     808        7069 :          CALL reallocate(c_var_c, 1, idim)
     809        7069 :          CALL reallocate(c_var_d, 1, idim)
     810        7069 :          IF (found) THEN
     811           0 :             CALL reallocate(c_var_type, 1, idim)
     812             :          END IF
     813        7069 :          idim = 0
     814      141428 :          DO j = 1, SIZE(conn_info%phi_a)
     815      134359 :             j1 = map_atom_mol(conn_info%phi_a(j))
     816      134359 :             j2 = map_atom_mol(conn_info%phi_b(j))
     817      134359 :             j3 = map_atom_mol(conn_info%phi_c(j))
     818      134359 :             j4 = map_atom_mol(conn_info%phi_d(j))
     819      141428 :             IF (j1 /= j2 .OR. j2 /= j3 .OR. j3 /= j4) THEN
     820       31630 :                idim = idim + 1
     821       31630 :                c_var_a(idim) = conn_info%phi_a(j)
     822       31630 :                c_var_b(idim) = conn_info%phi_b(j)
     823       31630 :                c_var_c(idim) = conn_info%phi_c(j)
     824       31630 :                c_var_d(idim) = conn_info%phi_d(j)
     825       31630 :                IF (found) THEN
     826           0 :                   c_var_type(idim) = conn_info%phi_type(j)
     827             :                END IF
     828             :             END IF
     829             :          END DO
     830             :       END IF
     831        9374 :       CALL timestop(handle2)
     832        9374 :       CALL timeset(routineN//"_13", handle2)
     833             :       ! map torsions on molecules
     834        9374 :       nvar1 = 0
     835        9374 :       nvar2 = 0
     836             :       NULLIFY (map_vars, map_cvars, bnd_type, bnd_ctype)
     837        9374 :       IF (ASSOCIATED(conn_info%phi_a)) nvar1 = SIZE(conn_info%phi_a)
     838        9374 :       IF (ASSOCIATED(c_var_a)) nvar2 = SIZE(c_var_a)
     839        9374 :       nval_tot1 = nvar1
     840        9374 :       nval_tot2 = 0
     841       19394 :       ALLOCATE (map_var_mol(nvar1))
     842       18900 :       ALLOCATE (map_cvar_mol(nvar2))
     843      174811 :       map_var_mol = -1
     844       41004 :       map_cvar_mol = -1
     845      174811 :       DO i = 1, nvar1
     846      165437 :          j1 = map_atom_mol(conn_info%phi_a(i))
     847      165437 :          j2 = map_atom_mol(conn_info%phi_b(i))
     848      165437 :          j3 = map_atom_mol(conn_info%phi_c(i))
     849      165437 :          j4 = map_atom_mol(conn_info%phi_d(i))
     850      174811 :          IF (j1 == j2 .AND. j2 == j3 .AND. j3 == j4) THEN
     851      133807 :             IF (j1 > 0) map_var_mol(i) = map_atom_type(conn_info%phi_a(i))
     852             :          END IF
     853             :       END DO
     854       41004 :       DO i = 1, nvar2
     855       31630 :          min_index = MIN(c_var_a(i), c_var_b(i), c_var_c(i), c_var_d(i))
     856       31630 :          j1 = map_atom_mol(min_index)
     857       41004 :          IF (j1 > 0) map_cvar_mol(i) = map_atom_type(min_index)
     858             :       END DO
     859        9374 :       CALL find_bnd_typ(topology%nmol_type, map_vars, map_var_mol, bnd_type, nvar1)
     860        9374 :       CALL find_bnd_typ(topology%nmol_type, map_cvars, map_cvar_mol, bnd_ctype, nvar2)
     861      141753 :       DO i = 1, topology%nmol_type
     862      132379 :          intra_torsions = 0
     863      132379 :          inter_torsions = 0
     864      143555 :          IF (ALL(bnd_type(:, i) > 0)) THEN
     865        5588 :             intra_torsions = bnd_type(2, i) - bnd_type(1, i) + 1
     866             :          END IF
     867      138043 :          IF (ALL(bnd_ctype(:, i) > 0)) THEN
     868        2832 :             inter_torsions = bnd_ctype(2, i) - bnd_ctype(1, i) + 1
     869             :          END IF
     870      132379 :          itorsion = intra_torsions + inter_torsions
     871      132379 :          IF (iw > 0) THEN
     872         434 :             WRITE (iw, *) "    Total number of torsions for molecule type ", i, " :", itorsion
     873         434 :             WRITE (iw, *) "    intra (torsions inside  molecules) :: ", intra_torsions
     874         434 :             WRITE (iw, *) "    inter (torsions between molecules) :: ", inter_torsions
     875             :          END IF
     876      132379 :          molecule_kind => molecule_kind_set(i)
     877      132379 :          nval_tot2 = nval_tot2 + itorsion*SIZE(molecule_kind%molecule_list)
     878      426935 :          ALLOCATE (torsion_list(itorsion))
     879      132379 :          itorsion = 0
     880      384129 :          DO j = bnd_type(1, i), bnd_type(2, i)
     881      251750 :             IF (j == 0) CYCLE
     882      124959 :             itorsion = itorsion + 1
     883      124959 :             jind = map_vars(j)
     884      124959 :             first = first_list(map_atom_mol(conn_info%phi_a(jind)))
     885      124959 :             torsion_list(itorsion)%a = conn_info%phi_a(jind) - first + 1
     886      124959 :             torsion_list(itorsion)%b = conn_info%phi_b(jind) - first + 1
     887      124959 :             torsion_list(itorsion)%c = conn_info%phi_c(jind) - first + 1
     888      124959 :             torsion_list(itorsion)%d = conn_info%phi_d(jind) - first + 1
     889             :             ! Set by default id_type to charmm and modify when handling the forcefield
     890      124959 :             torsion_list(itorsion)%id_type = do_ff_charmm
     891      124959 :             IF ((topology%conn_type == do_conn_g96) .OR. (topology%conn_type == do_conn_g87)) THEN
     892         312 :                torsion_list(itorsion)%itype = conn_info%phi_type(jind)
     893             :             END IF
     894             :             !point this to the right torsion_kind_type if using force field
     895      124959 :             NULLIFY (torsion_list(itorsion)%torsion_kind)
     896      257338 :             IF (iw > 0) THEN
     897             :                WRITE (iw, '(7X,A,I3,1X,A,I4,I4,I4,I4,1X,A,I4,I4,I4,I4)') &
     898         366 :                   "molecule_kind", i, "intra TOR", &
     899         366 :                   conn_info%phi_a(jind), &
     900         366 :                   conn_info%phi_b(jind), &
     901         366 :                   conn_info%phi_c(jind), &
     902         366 :                   conn_info%phi_d(jind), &
     903         366 :                   "offset number at", &
     904         366 :                   conn_info%phi_a(jind) - first + 1, &
     905         366 :                   conn_info%phi_b(jind) - first + 1, &
     906         366 :                   conn_info%phi_c(jind) - first + 1, &
     907         732 :                   conn_info%phi_d(jind) - first + 1
     908             :             END IF
     909             :          END DO
     910      293556 :          DO j = bnd_ctype(1, i), bnd_ctype(2, i)
     911      161177 :             IF (j == 0) CYCLE
     912       31630 :             itorsion = itorsion + 1
     913       31630 :             jind = map_cvars(j)
     914       31630 :             min_index = MIN(c_var_a(jind), c_var_b(jind), c_var_c(jind), c_var_d(jind))
     915       31630 :             first = first_list(map_atom_mol(min_index))
     916       31630 :             torsion_list(itorsion)%a = c_var_a(jind) - first + 1
     917       31630 :             torsion_list(itorsion)%b = c_var_b(jind) - first + 1
     918       31630 :             torsion_list(itorsion)%c = c_var_c(jind) - first + 1
     919       31630 :             torsion_list(itorsion)%d = c_var_d(jind) - first + 1
     920             :             ! Set by default id_type to charmm and modify when handling the forcefield
     921       31630 :             torsion_list(itorsion)%id_type = do_ff_charmm
     922       31630 :             IF ((topology%conn_type == do_conn_g96) .OR. (topology%conn_type == do_conn_g87)) THEN
     923           0 :                torsion_list(itorsion)%itype = c_var_type(jind)
     924             :             END IF
     925             :             !point this to the right torsion_kind_type if using force field
     926       31630 :             NULLIFY (torsion_list(itorsion)%torsion_kind)
     927      164009 :             IF (iw > 0) THEN
     928             :                WRITE (iw, '(7X,A,I3,1X,A,I4,I4,I4,I4,1X,A,I4,I4,I4,I4)') &
     929          34 :                   "molecule_kind", i, "inter TOR", &
     930          34 :                   c_var_a(jind), &
     931          34 :                   c_var_b(jind), &
     932          34 :                   c_var_c(jind), &
     933          34 :                   c_var_d(jind), &
     934          34 :                   "offset number at", &
     935          34 :                   c_var_a(jind) - first + 1, &
     936          34 :                   c_var_b(jind) - first + 1, &
     937          34 :                   c_var_c(jind) - first + 1, &
     938          68 :                   c_var_d(jind) - first + 1
     939             :             END IF
     940             :          END DO
     941             :          CALL set_molecule_kind(molecule_kind=molecule_kind, &
     942      141753 :                                 ntorsion=SIZE(torsion_list), torsion_list=torsion_list)
     943             :       END DO
     944        9374 :       CPASSERT(nval_tot1 == nval_tot2)
     945        9374 :       DEALLOCATE (map_var_mol)
     946        9374 :       DEALLOCATE (map_cvar_mol)
     947        9374 :       DEALLOCATE (map_vars)
     948        9374 :       DEALLOCATE (map_cvars)
     949        9374 :       DEALLOCATE (bnd_type)
     950        9374 :       DEALLOCATE (bnd_ctype)
     951        9374 :       DEALLOCATE (c_var_a)
     952        9374 :       DEALLOCATE (c_var_b)
     953        9374 :       DEALLOCATE (c_var_c)
     954        9374 :       DEALLOCATE (c_var_d)
     955        9374 :       IF (found) THEN
     956          14 :          DEALLOCATE (c_var_type)
     957             :       END IF
     958        9374 :       CALL timestop(handle2)
     959             :       !-----------------------------------------------------------------------------
     960             :       !-----------------------------------------------------------------------------
     961             :       ! 14. Set the molecule_kind%[nimpr,impr_list] via set_molecule_kind
     962             :       !     Also set the molecule_kind%[nopbend,opbend_list]
     963             :       !-----------------------------------------------------------------------------
     964             :       ! Allocate c_var_a, c_var_b, c_var_c, c_var_d, c_var_type
     965        9374 :       CALL timeset(routineN//"_14_pre", handle2)
     966        9374 :       idim = 0
     967        9374 :       ALLOCATE (c_var_a(idim))
     968        9374 :       ALLOCATE (c_var_b(idim))
     969        9374 :       ALLOCATE (c_var_c(idim))
     970        9374 :       ALLOCATE (c_var_d(idim))
     971        9374 :       found = ASSOCIATED(conn_info%impr_type)
     972        9374 :       IF (found) THEN
     973          14 :          ALLOCATE (c_var_type(idim))
     974             :       END IF
     975        9374 :       IF (ASSOCIATED(conn_info%c_bond_a) .AND. ASSOCIATED(conn_info%impr_a)) THEN
     976       11483 :          DO j = 1, SIZE(conn_info%impr_a)
     977        4414 :             j1 = map_atom_mol(conn_info%impr_a(j))
     978        4414 :             j2 = map_atom_mol(conn_info%impr_b(j))
     979        4414 :             j3 = map_atom_mol(conn_info%impr_c(j))
     980        4414 :             j4 = map_atom_mol(conn_info%impr_d(j))
     981       11483 :             IF (j1 /= j2 .OR. j2 /= j3 .OR. j3 /= j4) THEN
     982        3124 :                idim = idim + 1
     983             :             END IF
     984             :          END DO
     985        7069 :          CALL reallocate(c_var_a, 1, idim)
     986        7069 :          CALL reallocate(c_var_b, 1, idim)
     987        7069 :          CALL reallocate(c_var_c, 1, idim)
     988        7069 :          CALL reallocate(c_var_d, 1, idim)
     989        7069 :          IF (found) THEN
     990           0 :             CALL reallocate(c_var_type, 1, idim)
     991             :          END IF
     992        7069 :          idim = 0
     993       11483 :          DO j = 1, SIZE(conn_info%impr_a)
     994        4414 :             j1 = map_atom_mol(conn_info%impr_a(j))
     995        4414 :             j2 = map_atom_mol(conn_info%impr_b(j))
     996        4414 :             j3 = map_atom_mol(conn_info%impr_c(j))
     997        4414 :             j4 = map_atom_mol(conn_info%impr_d(j))
     998       11483 :             IF (j1 /= j2 .OR. j2 /= j3 .OR. j3 /= j4) THEN
     999        3124 :                idim = idim + 1
    1000        3124 :                c_var_a(idim) = conn_info%impr_a(j)
    1001        3124 :                c_var_b(idim) = conn_info%impr_b(j)
    1002        3124 :                c_var_c(idim) = conn_info%impr_c(j)
    1003        3124 :                c_var_d(idim) = conn_info%impr_d(j)
    1004        3124 :                IF (found) THEN
    1005           0 :                   c_var_type(idim) = conn_info%impr_type(j)
    1006             :                END IF
    1007             :             END IF
    1008             :          END DO
    1009             :       END IF
    1010        9374 :       CALL timestop(handle2)
    1011        9374 :       CALL timeset(routineN//"_14", handle2)
    1012             :       ! map imprs on molecules
    1013        9374 :       nvar1 = 0
    1014        9374 :       nvar2 = 0
    1015             :       NULLIFY (map_vars, map_cvars, bnd_type, bnd_ctype)
    1016        9374 :       IF (ASSOCIATED(conn_info%impr_a)) nvar1 = SIZE(conn_info%impr_a)
    1017        9374 :       IF (ASSOCIATED(c_var_a)) nvar2 = SIZE(c_var_a)
    1018        9374 :       nval_tot1 = nvar1
    1019        9374 :       nval_tot2 = 0
    1020       18894 :       ALLOCATE (map_var_mol(nvar1))
    1021       18788 :       ALLOCATE (map_cvar_mol(nvar2))
    1022       14784 :       map_var_mol = -1
    1023       12498 :       map_cvar_mol = -1
    1024       14784 :       DO i = 1, nvar1
    1025        5410 :          j1 = map_atom_mol(conn_info%impr_a(i))
    1026        5410 :          j2 = map_atom_mol(conn_info%impr_b(i))
    1027        5410 :          j3 = map_atom_mol(conn_info%impr_c(i))
    1028        5410 :          j4 = map_atom_mol(conn_info%impr_d(i))
    1029       14784 :          IF (j1 == j2 .AND. j2 == j3 .AND. j3 == j4) THEN
    1030        2286 :             IF (j1 > 0) map_var_mol(i) = map_atom_type(conn_info%impr_a(i))
    1031             :          END IF
    1032             :       END DO
    1033       12498 :       DO i = 1, nvar2
    1034        3124 :          min_index = MIN(c_var_a(i), c_var_b(i), c_var_c(i), c_var_d(i))
    1035        3124 :          j1 = map_atom_mol(min_index)
    1036       12498 :          IF (j1 > 0) map_cvar_mol(i) = map_atom_type(min_index)
    1037             :       END DO
    1038        9374 :       CALL find_bnd_typ(topology%nmol_type, map_vars, map_var_mol, bnd_type, nvar1)
    1039        9374 :       CALL find_bnd_typ(topology%nmol_type, map_cvars, map_cvar_mol, bnd_ctype, nvar2)
    1040      141753 :       DO i = 1, topology%nmol_type
    1041      132379 :          intra_imprs = 0
    1042      132379 :          inter_imprs = 0
    1043      133467 :          IF (ALL(bnd_type(:, i) > 0)) THEN
    1044         544 :             intra_imprs = bnd_type(2, i) - bnd_type(1, i) + 1
    1045             :          END IF
    1046      135503 :          IF (ALL(bnd_ctype(:, i) > 0)) THEN
    1047        1562 :             inter_imprs = bnd_ctype(2, i) - bnd_ctype(1, i) + 1
    1048             :          END IF
    1049      132379 :          iimpr = intra_imprs + inter_imprs
    1050      132379 :          IF (iw > 0) THEN
    1051         434 :             WRITE (iw, *) "    Total number of imprs for molecule type ", i, " :", iimpr
    1052         434 :             WRITE (iw, *) "    intra (imprs inside  molecules) :: ", intra_imprs
    1053         434 :             WRITE (iw, *) "    inter (imprs between molecules) :: ", inter_imprs
    1054         434 :             WRITE (iw, *) "    Total number of opbends for molecule type ", i, " :", iimpr
    1055         434 :             WRITE (iw, *) "    intra (opbends inside  molecules) :: ", intra_imprs
    1056         434 :             WRITE (iw, *) "    inter (opbends between molecules) :: ", inter_imprs
    1057             :          END IF
    1058      132379 :          molecule_kind => molecule_kind_set(i)
    1059      132379 :          nval_tot2 = nval_tot2 + iimpr*SIZE(molecule_kind%molecule_list)
    1060      271830 :          ALLOCATE (impr_list(iimpr), STAT=stat)
    1061      271830 :          ALLOCATE (opbend_list(iimpr), STAT=stat)
    1062      132379 :          CPASSERT(stat == 0)
    1063      132379 :          iimpr = 0
    1064      266476 :          DO j = bnd_type(1, i), bnd_type(2, i)
    1065      134097 :             IF (j == 0) CYCLE
    1066        2262 :             iimpr = iimpr + 1
    1067        2262 :             jind = map_vars(j)
    1068        2262 :             first = first_list(map_atom_mol(conn_info%impr_a(jind)))
    1069        2262 :             impr_list(iimpr)%a = conn_info%impr_a(jind) - first + 1
    1070        2262 :             impr_list(iimpr)%b = conn_info%impr_b(jind) - first + 1
    1071        2262 :             impr_list(iimpr)%c = conn_info%impr_c(jind) - first + 1
    1072        2262 :             impr_list(iimpr)%d = conn_info%impr_d(jind) - first + 1
    1073             :             ! Atom sequence for improper is A B C D in which A is central atom,
    1074             :             ! B is deviating atom and C & D are secondairy atoms. Atom sequence for
    1075             :             ! opbend is B D C A in which A is central atom, B is deviating. Hence
    1076             :             ! to create an opbend out of an improper, B and D need to be interchanged.
    1077        2262 :             opbend_list(iimpr)%a = conn_info%impr_b(jind) - first + 1
    1078        2262 :             opbend_list(iimpr)%b = conn_info%impr_d(jind) - first + 1
    1079        2262 :             opbend_list(iimpr)%c = conn_info%impr_c(jind) - first + 1
    1080        2262 :             opbend_list(iimpr)%d = conn_info%impr_a(jind) - first + 1
    1081             :             ! Set by default id_type of improper to charmm and modify when handling the forcefield
    1082        2262 :             impr_list(iimpr)%id_type = do_ff_charmm
    1083             :             ! Set by default id_type of opbend to harmonic and modify when handling the forcefield
    1084        2262 :             opbend_list(iimpr)%id_type = do_ff_harmonic
    1085        2262 :             IF ((topology%conn_type == do_conn_g96) .OR. (topology%conn_type == do_conn_g87)) THEN
    1086           0 :                impr_list(iimpr)%itype = conn_info%impr_type(jind)
    1087             :             END IF
    1088             :             !point this to the right impr_kind_type if using force field
    1089        2262 :             NULLIFY (impr_list(iimpr)%impr_kind)
    1090        2262 :             NULLIFY (opbend_list(iimpr)%opbend_kind)
    1091      134641 :             IF (iw > 0) THEN
    1092             :                WRITE (iw, '(7X,A,I3,1X,A,I4,I4,I4,I4,1X,A,I4,I4,I4,I4)') &
    1093           0 :                   "molecule_kind", i, "intra IMPR", &
    1094           0 :                   conn_info%impr_a(jind), &
    1095           0 :                   conn_info%impr_b(jind), &
    1096           0 :                   conn_info%impr_c(jind), &
    1097           0 :                   conn_info%impr_d(jind), &
    1098           0 :                   "offset number at", &
    1099           0 :                   conn_info%impr_a(jind) - first + 1, &
    1100           0 :                   conn_info%impr_b(jind) - first + 1, &
    1101           0 :                   conn_info%impr_c(jind) - first + 1, &
    1102           0 :                   conn_info%impr_d(jind) - first + 1
    1103             :                WRITE (iw, '(7X,A,I3,1X,A,I4,I4,I4,I4,1X,A,I4,I4,I4,I4)') &
    1104           0 :                   "molecule_kind", i, "intra OPBEND", &
    1105           0 :                   conn_info%impr_b(jind), &
    1106           0 :                   conn_info%impr_d(jind), &
    1107           0 :                   conn_info%impr_c(jind), &
    1108           0 :                   conn_info%impr_a(jind), &
    1109           0 :                   "offset number at", &
    1110           0 :                   conn_info%impr_b(jind) - first + 1, &
    1111           0 :                   conn_info%impr_d(jind) - first + 1, &
    1112           0 :                   conn_info%impr_c(jind) - first + 1, &
    1113           0 :                   conn_info%impr_a(jind) - first + 1
    1114             :             END IF
    1115             :          END DO
    1116      266320 :          DO j = bnd_ctype(1, i), bnd_ctype(2, i)
    1117      133941 :             IF (j == 0) CYCLE
    1118        3124 :             iimpr = iimpr + 1
    1119        3124 :             jind = map_cvars(j)
    1120        3124 :             min_index = MIN(c_var_a(jind), c_var_b(jind), c_var_c(jind), c_var_d(jind))
    1121        3124 :             first = first_list(map_atom_mol(min_index))
    1122        3124 :             impr_list(iimpr)%a = c_var_a(jind) - first + 1
    1123        3124 :             impr_list(iimpr)%b = c_var_b(jind) - first + 1
    1124        3124 :             impr_list(iimpr)%c = c_var_c(jind) - first + 1
    1125        3124 :             impr_list(iimpr)%d = c_var_d(jind) - first + 1
    1126        3124 :             opbend_list(iimpr)%a = c_var_b(jind) - first + 1
    1127        3124 :             opbend_list(iimpr)%b = c_var_d(jind) - first + 1
    1128        3124 :             opbend_list(iimpr)%c = c_var_c(jind) - first + 1
    1129        3124 :             opbend_list(iimpr)%d = c_var_a(jind) - first + 1
    1130             :             ! Set by default id_type of improper to charmm and modify when handling the forcefield
    1131        3124 :             impr_list(iimpr)%id_type = do_ff_charmm
    1132             :             ! Set by default id_type of opbend to harmonic and modify when handling the forcefield
    1133        3124 :             opbend_list(iimpr)%id_type = do_ff_harmonic
    1134        3124 :             IF ((topology%conn_type == do_conn_g96) .OR. (topology%conn_type == do_conn_g87)) THEN
    1135           0 :                impr_list(iimpr)%itype = c_var_type(jind)
    1136             :             END IF
    1137             :             !point this to the right impr_kind_type and opbend_kind_type if using force field
    1138        3124 :             NULLIFY (impr_list(iimpr)%impr_kind)
    1139        3124 :             NULLIFY (opbend_list(iimpr)%opbend_kind)
    1140      135503 :             IF (iw > 0) THEN
    1141             :                WRITE (iw, '(7X,A,I3,1X,A,I4,I4,I4,I4,1X,A,I4,I4,I4,I4)') &
    1142           0 :                   "molecule_kind", i, "inter IMPR", &
    1143           0 :                   c_var_a(jind), &
    1144           0 :                   c_var_b(jind), &
    1145           0 :                   c_var_c(jind), &
    1146           0 :                   c_var_d(jind), &
    1147           0 :                   "offset number at", &
    1148           0 :                   c_var_a(jind) - first + 1, &
    1149           0 :                   c_var_b(jind) - first + 1, &
    1150           0 :                   c_var_c(jind) - first + 1, &
    1151           0 :                   c_var_d(jind) - first + 1
    1152             :                WRITE (iw, '(7X,A,I3,1X,A,I4,I4,I4,I4,1X,A,I4,I4,I4,I4)') &
    1153           0 :                   "molecule_kind", i, "inter OPBEND", &
    1154           0 :                   c_var_b(jind), &
    1155           0 :                   c_var_d(jind), &
    1156           0 :                   c_var_c(jind), &
    1157           0 :                   c_var_a(jind), &
    1158           0 :                   "offset number at", &
    1159           0 :                   c_var_b(jind) - first + 1, &
    1160           0 :                   c_var_d(jind) - first + 1, &
    1161           0 :                   c_var_c(jind) - first + 1, &
    1162           0 :                   c_var_a(jind) - first + 1
    1163             :             END IF
    1164             :          END DO
    1165             :          CALL set_molecule_kind(molecule_kind=molecule_kind, &
    1166      132379 :                                 nimpr=SIZE(impr_list), impr_list=impr_list)
    1167             :          CALL set_molecule_kind(molecule_kind=molecule_kind, &
    1168      141753 :                                 nopbend=SIZE(opbend_list), opbend_list=opbend_list)
    1169             :       END DO
    1170        9374 :       CPASSERT(nval_tot1 == nval_tot2)
    1171        9374 :       DEALLOCATE (map_var_mol)
    1172        9374 :       DEALLOCATE (map_cvar_mol)
    1173        9374 :       DEALLOCATE (map_vars)
    1174        9374 :       DEALLOCATE (map_cvars)
    1175        9374 :       DEALLOCATE (bnd_type)
    1176        9374 :       DEALLOCATE (bnd_ctype)
    1177        9374 :       DEALLOCATE (c_var_a)
    1178        9374 :       DEALLOCATE (c_var_b)
    1179        9374 :       DEALLOCATE (c_var_c)
    1180        9374 :       DEALLOCATE (c_var_d)
    1181        9374 :       IF (found) THEN
    1182          14 :          DEALLOCATE (c_var_type)
    1183             :       END IF
    1184        9374 :       CALL timestop(handle2)
    1185             :       !-----------------------------------------------------------------------------
    1186             :       !-----------------------------------------------------------------------------
    1187             :       ! Finally deallocate some stuff.
    1188             :       !-----------------------------------------------------------------------------
    1189        9374 :       DEALLOCATE (first_list)
    1190        9374 :       DEALLOCATE (last_list)
    1191        9374 :       DEALLOCATE (map_atom_mol)
    1192        9374 :       DEALLOCATE (map_atom_type)
    1193        9374 :       CALL timestop(handle)
    1194             :       CALL cp_print_key_finished_output(iw, logger, subsys_section, &
    1195        9374 :                                         "PRINT%TOPOLOGY_INFO/UTIL_INFO")
    1196      196854 :    END SUBROUTINE topology_connectivity_pack
    1197             : 
    1198             : ! **************************************************************************************************
    1199             : !> \brief used to achieve linear scaling in the connectivity_pack
    1200             : !> \param nmol_type ...
    1201             : !> \param map_vars ...
    1202             : !> \param map_var_mol ...
    1203             : !> \param bnd_type ...
    1204             : !> \param nvar1 ...
    1205             : !> \par History
    1206             : !>      Teodoro Laino
    1207             : ! **************************************************************************************************
    1208       93740 :    SUBROUTINE find_bnd_typ(nmol_type, map_vars, map_var_mol, bnd_type, nvar1)
    1209             :       INTEGER, INTENT(IN)                                :: nmol_type
    1210             :       INTEGER, DIMENSION(:), POINTER                     :: map_vars, map_var_mol
    1211             :       INTEGER, DIMENSION(:, :), POINTER                  :: bnd_type
    1212             :       INTEGER, INTENT(IN)                                :: nvar1
    1213             : 
    1214             :       INTEGER                                            :: i, ibond, j
    1215             : 
    1216      196119 :       ALLOCATE (map_vars(nvar1))
    1217       93740 :       CALL sort(map_var_mol, nvar1, map_vars)
    1218      281220 :       ALLOCATE (bnd_type(2, nmol_type))
    1219     4065110 :       bnd_type = 0
    1220       93740 :       IF (nvar1 == 0) RETURN
    1221      731541 :       DO j = 1, nvar1
    1222      731541 :          IF (map_var_mol(j) /= -1) EXIT
    1223             :       END DO
    1224        8639 :       IF (j == nvar1 + 1) RETURN
    1225        8607 :       i = map_var_mol(j)
    1226        8607 :       bnd_type(1, i) = j
    1227      567961 :       DO ibond = j, nvar1
    1228      567961 :          IF (map_var_mol(ibond) /= i) THEN
    1229      100156 :             bnd_type(2, i) = ibond - 1
    1230      100156 :             i = map_var_mol(ibond)
    1231      100156 :             bnd_type(1, i) = ibond
    1232             :          END IF
    1233             :       END DO
    1234        8607 :       bnd_type(2, i) = nvar1
    1235             : 
    1236             :    END SUBROUTINE find_bnd_typ
    1237             : 
    1238             : ! **************************************************************************************************
    1239             : !> \brief   Handles the multiple unit cell option for the connectivity
    1240             : !> \param topology ...
    1241             : !> \param subsys_section ...
    1242             : !> \author  Teodoro Laino [tlaino] - 06.2009
    1243             : ! **************************************************************************************************
    1244        9374 :    SUBROUTINE topology_conn_multiple(topology, subsys_section)
    1245             :       TYPE(topology_parameters_type), INTENT(INOUT)      :: topology
    1246             :       TYPE(section_vals_type), POINTER                   :: subsys_section
    1247             : 
    1248             :       INTEGER                                            :: a, fac, i, ind, j, k, m, natoms_orig, &
    1249             :                                                             nbond, nbond_c, nimpr, nonfo, nphi, &
    1250             :                                                             ntheta, nub
    1251        9374 :       INTEGER, DIMENSION(:), POINTER                     :: multiple_unit_cell
    1252             :       TYPE(connectivity_info_type), POINTER              :: conn_info
    1253             : 
    1254        9374 :       NULLIFY (multiple_unit_cell)
    1255             :       CALL section_vals_val_get(subsys_section, "TOPOLOGY%MULTIPLE_UNIT_CELL", &
    1256        9374 :                                 i_vals=multiple_unit_cell)
    1257       37026 :       IF (ANY(multiple_unit_cell /= 1)) THEN
    1258         640 :          fac = PRODUCT(multiple_unit_cell)
    1259         160 :          conn_info => topology%conn_info
    1260             : 
    1261         160 :          nbond = 0
    1262         160 :          IF (ASSOCIATED(conn_info%bond_a)) THEN
    1263         160 :             nbond = SIZE(conn_info%bond_a)
    1264         160 :             CALL reallocate(conn_info%bond_a, 1, nbond*fac)
    1265         160 :             CALL reallocate(conn_info%bond_b, 1, nbond*fac)
    1266             :          END IF
    1267             : 
    1268         160 :          ntheta = 0
    1269         160 :          IF (ASSOCIATED(conn_info%theta_a)) THEN
    1270         160 :             ntheta = SIZE(conn_info%theta_a)
    1271         160 :             CALL reallocate(conn_info%theta_a, 1, ntheta*fac)
    1272         160 :             CALL reallocate(conn_info%theta_b, 1, ntheta*fac)
    1273         160 :             CALL reallocate(conn_info%theta_c, 1, ntheta*fac)
    1274             :          END IF
    1275             : 
    1276         160 :          nphi = 0
    1277         160 :          IF (ASSOCIATED(conn_info%phi_a)) THEN
    1278         160 :             nphi = SIZE(conn_info%phi_a)
    1279         160 :             CALL reallocate(conn_info%phi_a, 1, nphi*fac)
    1280         160 :             CALL reallocate(conn_info%phi_b, 1, nphi*fac)
    1281         160 :             CALL reallocate(conn_info%phi_c, 1, nphi*fac)
    1282         160 :             CALL reallocate(conn_info%phi_d, 1, nphi*fac)
    1283             :          END IF
    1284             : 
    1285         160 :          nimpr = 0
    1286         160 :          IF (ASSOCIATED(conn_info%impr_a)) THEN
    1287         160 :             nimpr = SIZE(conn_info%impr_a)
    1288         160 :             CALL reallocate(conn_info%impr_a, 1, nimpr*fac)
    1289         160 :             CALL reallocate(conn_info%impr_b, 1, nimpr*fac)
    1290         160 :             CALL reallocate(conn_info%impr_c, 1, nimpr*fac)
    1291         160 :             CALL reallocate(conn_info%impr_d, 1, nimpr*fac)
    1292             :          END IF
    1293             : 
    1294         160 :          nbond_c = 0
    1295         160 :          IF (ASSOCIATED(conn_info%c_bond_a)) THEN
    1296         128 :             nbond_c = SIZE(conn_info%c_bond_a)
    1297         128 :             CALL reallocate(conn_info%c_bond_a, 1, nbond_c*fac)
    1298         128 :             CALL reallocate(conn_info%c_bond_b, 1, nbond_c*fac)
    1299             :          END IF
    1300             : 
    1301         160 :          nub = 0
    1302         160 :          IF (ASSOCIATED(conn_info%ub_a)) THEN
    1303         160 :             nub = SIZE(conn_info%ub_a)
    1304         160 :             CALL reallocate(conn_info%ub_a, 1, nub*fac)
    1305         160 :             CALL reallocate(conn_info%ub_b, 1, nub*fac)
    1306         160 :             CALL reallocate(conn_info%ub_c, 1, nub*fac)
    1307             :          END IF
    1308             : 
    1309         160 :          nonfo = 0
    1310         160 :          IF (ASSOCIATED(conn_info%onfo_a)) THEN
    1311         160 :             nonfo = SIZE(conn_info%onfo_a)
    1312         160 :             CALL reallocate(conn_info%onfo_a, 1, nonfo*fac)
    1313         160 :             CALL reallocate(conn_info%onfo_b, 1, nonfo*fac)
    1314             :          END IF
    1315             : 
    1316         160 :          natoms_orig = topology%natoms/fac
    1317         160 :          ind = 0
    1318         580 :          DO k = 1, multiple_unit_cell(3)
    1319        1906 :             DO j = 1, multiple_unit_cell(2)
    1320        6752 :                DO i = 1, multiple_unit_cell(1)
    1321        5006 :                   ind = ind + 1
    1322        5006 :                   IF (ind == 1) CYCLE
    1323        4846 :                   a = (ind - 1)*natoms_orig
    1324             : 
    1325             :                   ! Bonds
    1326        4846 :                   IF (nbond > 0) THEN
    1327        3208 :                      m = (ind - 1)*nbond
    1328       34024 :                      conn_info%bond_a(m + 1:m + nbond) = conn_info%bond_a(1:nbond) + a
    1329       34024 :                      conn_info%bond_b(m + 1:m + nbond) = conn_info%bond_b(1:nbond) + a
    1330             :                   END IF
    1331             :                   ! Theta
    1332        4846 :                   IF (ntheta > 0) THEN
    1333        2168 :                      m = (ind - 1)*ntheta
    1334       37428 :                      conn_info%theta_a(m + 1:m + ntheta) = conn_info%theta_a(1:ntheta) + a
    1335       37428 :                      conn_info%theta_b(m + 1:m + ntheta) = conn_info%theta_b(1:ntheta) + a
    1336       37428 :                      conn_info%theta_c(m + 1:m + ntheta) = conn_info%theta_c(1:ntheta) + a
    1337             :                   END IF
    1338             :                   ! Phi
    1339        4846 :                   IF (nphi > 0) THEN
    1340          14 :                      m = (ind - 1)*nphi
    1341       35756 :                      conn_info%phi_a(m + 1:m + nphi) = conn_info%phi_a(1:nphi) + a
    1342       35756 :                      conn_info%phi_b(m + 1:m + nphi) = conn_info%phi_b(1:nphi) + a
    1343       35756 :                      conn_info%phi_c(m + 1:m + nphi) = conn_info%phi_c(1:nphi) + a
    1344       35756 :                      conn_info%phi_d(m + 1:m + nphi) = conn_info%phi_d(1:nphi) + a
    1345             :                   END IF
    1346             :                   ! Impropers
    1347        4846 :                   IF (nimpr > 0) THEN
    1348           0 :                      m = (ind - 1)*nimpr
    1349           0 :                      conn_info%impr_a(m + 1:m + nimpr) = conn_info%impr_a(1:nimpr) + a
    1350           0 :                      conn_info%impr_b(m + 1:m + nimpr) = conn_info%impr_b(1:nimpr) + a
    1351           0 :                      conn_info%impr_c(m + 1:m + nimpr) = conn_info%impr_c(1:nimpr) + a
    1352           0 :                      conn_info%impr_d(m + 1:m + nimpr) = conn_info%impr_d(1:nimpr) + a
    1353             :                   END IF
    1354             :                   ! Para_res
    1355        4846 :                   IF (nbond_c > 0) THEN
    1356           0 :                      m = (ind - 1)*nbond_c
    1357           0 :                      conn_info%c_bond_a(m + 1:m + nbond_c) = conn_info%c_bond_a(1:nbond_c) + a
    1358           0 :                      conn_info%c_bond_b(m + 1:m + nbond_c) = conn_info%c_bond_b(1:nbond_c) + a
    1359             :                   END IF
    1360             :                   ! Urey-Bradley
    1361        4846 :                   IF (nub > 0) THEN
    1362        2168 :                      m = (ind - 1)*nub
    1363       37428 :                      conn_info%ub_a(m + 1:m + nub) = conn_info%ub_a(1:nub) + a
    1364       37428 :                      conn_info%ub_b(m + 1:m + nub) = conn_info%ub_b(1:nub) + a
    1365       37428 :                      conn_info%ub_c(m + 1:m + nub) = conn_info%ub_c(1:nub) + a
    1366             :                   END IF
    1367             :                   ! ONFO
    1368        6172 :                   IF (nonfo > 0) THEN
    1369          14 :                      m = (ind - 1)*nonfo
    1370       28364 :                      conn_info%onfo_a(m + 1:m + nonfo) = conn_info%onfo_a(1:nonfo) + a
    1371       28364 :                      conn_info%onfo_b(m + 1:m + nonfo) = conn_info%onfo_b(1:nonfo) + a
    1372             :                   END IF
    1373             :                END DO
    1374             :             END DO
    1375             :          END DO
    1376             :       END IF
    1377             : 
    1378        9374 :    END SUBROUTINE topology_conn_multiple
    1379             : 
    1380             : END MODULE topology_connectivity_util

Generated by: LCOV version 1.15