Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \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 10502 : 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 10502 : INTEGER, DIMENSION(:), POINTER :: c_var_a, c_var_b, c_var_c, c_var_d, c_var_type, &
79 10502 : first_list, last_list, map_atom_mol, map_atom_type, map_cvar_mol, map_cvars, map_var_mol, &
80 10502 : map_vars, molecule_list
81 10502 : INTEGER, DIMENSION(:, :), POINTER :: bnd_ctype, bnd_type
82 : LOGICAL :: found, found_last
83 : TYPE(atom_info_type), POINTER :: atom_info
84 10502 : TYPE(atom_type), DIMENSION(:), POINTER :: atom_list
85 10502 : TYPE(bend_type), DIMENSION(:), POINTER :: bend_list
86 10502 : TYPE(bond_type), DIMENSION(:), POINTER :: bond_list
87 : TYPE(connectivity_info_type), POINTER :: conn_info
88 : TYPE(cp_logger_type), POINTER :: logger
89 10502 : TYPE(impr_type), DIMENSION(:), POINTER :: impr_list
90 10502 : TYPE(local_states_type), DIMENSION(:), POINTER :: lmi
91 : TYPE(molecule_kind_type), POINTER :: molecule_kind
92 : TYPE(molecule_type), POINTER :: molecule
93 10502 : TYPE(opbend_type), DIMENSION(:), POINTER :: opbend_list
94 10502 : TYPE(torsion_type), DIMENSION(:), POINTER :: torsion_list
95 10502 : TYPE(ub_type), DIMENSION(:), POINTER :: ub_list
96 :
97 10502 : NULLIFY (logger)
98 21004 : logger => cp_get_default_logger()
99 10502 : 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 10502 : extension=".subsysLog")
102 10502 : CALL timeset(routineN, handle)
103 :
104 10502 : atom_info => topology%atom_info
105 10502 : conn_info => topology%conn_info
106 31506 : ALLOCATE (map_atom_mol(topology%natoms))
107 21004 : ALLOCATE (map_atom_type(topology%natoms))
108 : !-----------------------------------------------------------------------------
109 : !-----------------------------------------------------------------------------
110 : ! 1. Set the topology%[nmol_type,nmol,nmol_conn]
111 : !-----------------------------------------------------------------------------
112 10502 : CALL timeset(routineN//"_1", handle2)
113 10502 : natom = topology%natoms
114 10502 : topology%nmol = 1
115 10502 : topology%nmol_type = 1
116 10502 : topology%nmol_conn = 0
117 766377 : map_atom_mol = -1
118 766377 : map_atom_type = -1
119 10502 : map_atom_mol(1) = 1
120 10502 : map_atom_type(1) = 1
121 755875 : DO i = 1, natom - 1
122 745373 : 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 126615 : topology%nmol_type = topology%nmol_type + 1
126 : END IF
127 745373 : 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 745373 : (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 295458 : topology%nmol = topology%nmol + 1
132 : END IF
133 745373 : map_atom_mol(i + 1) = topology%nmol
134 : IF ((atom_info%map_mol_typ(i + 1) == atom_info%map_mol_typ(i)) .AND. &
135 745373 : (atom_info%map_mol_num(i + 1) == atom_info%map_mol_num(i)) .AND. &
136 10502 : (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 10502 : IF (iw > 0) WRITE (iw, *) "topology%nmol ::", topology%nmol
141 10502 : IF (iw > 0) WRITE (iw, *) "topology%nmol_type ::", topology%nmol_type
142 10502 : IF (iw > 0) WRITE (iw, *) "topology%nmol_conn ::", topology%nmol_conn
143 10502 : 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 10502 : CALL timeset(routineN//"_1.1", handle2)
150 10502 : istart_mol = map_atom_mol(1)
151 10502 : istart_typ = map_atom_type(1)
152 755875 : DO i = 2, natom
153 755875 : IF ((map_atom_mol(i) /= istart_mol) .AND. (map_atom_type(i) == istart_typ)) THEN
154 505249 : map_atom_mol(i) = -map_atom_mol(i)
155 240124 : ELSE IF (map_atom_type(i) /= istart_typ) THEN
156 126615 : istart_mol = map_atom_mol(i)
157 126615 : istart_typ = map_atom_type(i)
158 : END IF
159 : END DO
160 10502 : CALL timestop(handle2)
161 : !-----------------------------------------------------------------------------
162 : !-----------------------------------------------------------------------------
163 : ! 2. Allocate the molecule_kind_set
164 : !-----------------------------------------------------------------------------
165 10502 : CALL timeset(routineN//"_2", handle2)
166 10502 : IF (topology%nmol_type <= 0) THEN
167 0 : CPABORT("No molecule kind defined")
168 : ELSE
169 10502 : NULLIFY (molecule_kind_set)
170 10502 : i = topology%nmol_type
171 10502 : CALL allocate_molecule_kind_set(molecule_kind_set, i)
172 10528 : IF (iw > 0) WRITE (iw, *) " Allocated molecule_kind_set, Dimenstion of ", &
173 52 : SIZE(molecule_kind_set)
174 : END IF
175 10502 : CALL timestop(handle2)
176 : !-----------------------------------------------------------------------------
177 : !-----------------------------------------------------------------------------
178 : ! 3. Allocate the molecule_set
179 : !-----------------------------------------------------------------------------
180 10502 : CALL timeset(routineN//"_3", handle2)
181 10502 : IF (topology%nmol <= 0) THEN
182 0 : CPABORT("No molecule defined")
183 : ELSE
184 10502 : NULLIFY (molecule_set)
185 10502 : i = topology%nmol
186 10502 : CALL allocate_molecule_set(molecule_set, i)
187 10528 : IF (iw > 0) WRITE (iw, *) " Allocated molecule_set, dimension of ", &
188 52 : topology%nmol
189 : END IF
190 10502 : CALL timestop(handle2)
191 : !-----------------------------------------------------------------------------
192 : !-----------------------------------------------------------------------------
193 : ! 4. Set the molecule_kind_set%[kind_number,name,nsgf,nelectron]
194 : !-----------------------------------------------------------------------------
195 10502 : CALL timeset(routineN//"_4", handle2)
196 10502 : natom = topology%natoms
197 10502 : ikind = -1
198 766377 : DO i = 1, natom
199 766377 : IF (ikind /= map_atom_type(i)) THEN
200 137117 : ikind = map_atom_type(i)
201 137117 : molecule_kind => molecule_kind_set(ikind)
202 137117 : nsgf = 0
203 137117 : nelectron = 0
204 137117 : 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 137117 : nelectron=nelectron)
211 : END IF
212 : END DO
213 10502 : CALL timestop(handle2)
214 : !-----------------------------------------------------------------------------
215 : !-----------------------------------------------------------------------------
216 : ! 5. Set the molecule_list for molecule_kind in molecule_kind_set
217 : !-----------------------------------------------------------------------------
218 10502 : CALL timeset(routineN//"_5", handle2)
219 10502 : natom = topology%natoms
220 10502 : ikind = map_atom_type(1)
221 10502 : imol = ABS(map_atom_mol(1))
222 10502 : counter = 0
223 290690 : DO i = 1, natom - 1
224 282957 : IF (ikind /= map_atom_type(i + 1)) THEN
225 126615 : found = .TRUE.
226 126615 : found_last = .FALSE.
227 126615 : imol = ABS(map_atom_mol(i))
228 156342 : ELSEIF (ikind == topology%nmol_type) THEN
229 2769 : found = .TRUE.
230 2769 : found_last = .TRUE.
231 2769 : imol = ABS(map_atom_mol(natom))
232 : ELSE
233 : found = .FALSE.
234 : found_last = .FALSE.
235 : END IF
236 :
237 10502 : IF (found) THEN
238 388152 : ALLOCATE (molecule_list(imol - counter))
239 427611 : DO j = 1, SIZE(molecule_list)
240 427611 : molecule_list(j) = j + counter
241 : END DO
242 129384 : molecule_kind => molecule_kind_set(ikind)
243 : CALL set_molecule_kind(molecule_kind=molecule_kind, &
244 129384 : molecule_list=molecule_list)
245 129384 : IF (iw > 0) WRITE (iw, *) " molecule_list", ikind, molecule_list(:)
246 129384 : IF (found_last) EXIT
247 126615 : counter = imol
248 126615 : 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 10502 : IF (i == natom) THEN
253 7733 : imol = ABS(map_atom_mol(natom))
254 : ! Last atom is also a molecule by itself
255 23199 : ALLOCATE (molecule_list(imol - counter))
256 15466 : DO j = 1, SIZE(molecule_list)
257 15466 : molecule_list(j) = j + counter
258 : END DO
259 7733 : molecule_kind => molecule_kind_set(ikind)
260 : CALL set_molecule_kind(molecule_kind=molecule_kind, &
261 7733 : molecule_list=molecule_list)
262 7733 : IF (iw > 0) WRITE (iw, *) " molecule_list", ikind, molecule_list(:)
263 : END IF
264 10502 : CALL timestop(handle2)
265 : !-----------------------------------------------------------------------------
266 : !-----------------------------------------------------------------------------
267 : ! 6. Set the molecule_set(imol)%molecule_kind via set_molecule
268 : !-----------------------------------------------------------------------------
269 10502 : CALL timeset(routineN//"_6", handle2)
270 147619 : DO ikind = 1, SIZE(molecule_kind_set)
271 137117 : molecule_kind => molecule_kind_set(ikind)
272 : CALL get_molecule_kind(molecule_kind=molecule_kind, &
273 137117 : molecule_list=molecule_list)
274 453579 : DO i = 1, SIZE(molecule_list)
275 305960 : molecule => molecule_set(molecule_list(i))
276 443077 : CALL set_molecule(molecule, molecule_kind=molecule_kind)
277 : END DO
278 : END DO
279 10502 : CALL timestop(handle2)
280 : !-----------------------------------------------------------------------------
281 : !-----------------------------------------------------------------------------
282 : ! 7. Set the molecule_set(imol)%[first_atom,last_atom] via set_molecule_set
283 : !-----------------------------------------------------------------------------
284 31506 : ALLOCATE (first_list(SIZE(molecule_set)))
285 21004 : ALLOCATE (last_list(SIZE(molecule_set)))
286 10502 : CALL timeset(routineN//"_7", handle2)
287 316462 : first_list(:) = 0
288 316462 : last_list(:) = 0
289 10502 : ityp = atom_info%map_mol_typ(1)
290 10502 : inum = atom_info%map_mol_num(1)
291 10502 : ires = atom_info%map_mol_res(1)
292 10502 : imol = 1
293 10502 : first_list(1) = 1
294 755875 : DO j = 2, natom
295 : IF ((atom_info%map_mol_typ(j) /= ityp) .OR. &
296 745373 : (atom_info%map_mol_num(j) /= inum) .OR. &
297 10502 : (atom_info%map_mol_res(j) /= ires)) THEN
298 295458 : ityp = atom_info%map_mol_typ(j)
299 295458 : inum = atom_info%map_mol_num(j)
300 295458 : ires = atom_info%map_mol_res(j)
301 295458 : imol = imol + 1
302 295458 : first_list(imol) = j
303 : END IF
304 : END DO
305 10502 : CPASSERT(imol == topology%nmol)
306 305960 : DO ikind = 1, topology%nmol - 1
307 305960 : last_list(ikind) = first_list(ikind + 1) - 1
308 : END DO
309 10502 : last_list(topology%nmol) = topology%natoms
310 10502 : CALL set_molecule_set(molecule_set, first_list, last_list)
311 10502 : CALL timestop(handle2)
312 : !-----------------------------------------------------------------------------
313 : !-----------------------------------------------------------------------------
314 : ! 8. Set and NULLIFY the molecule_set(imol)%lmi via set_molecule_set
315 : !-----------------------------------------------------------------------------
316 10502 : CALL timeset(routineN//"_8", handle2)
317 316462 : DO imol = 1, SIZE(molecule_set)
318 305960 : molecule => molecule_set(imol)
319 305960 : NULLIFY (lmi)
320 316462 : CALL set_molecule(molecule, lmi=lmi)
321 : END DO
322 10502 : CALL timestop(handle2)
323 : !-----------------------------------------------------------------------------
324 : !-----------------------------------------------------------------------------
325 : ! 9. Set the atom_list for molecule_kind in molecule_kind_set (PART 1)
326 : !-----------------------------------------------------------------------------
327 10502 : CALL timeset(routineN//"_9", handle2)
328 10502 : counter = 0
329 316462 : DO imol = 1, SIZE(molecule_set)
330 305960 : molecule => molecule_set(imol)
331 305960 : molecule_kind => molecule_set(imol)%molecule_kind
332 : CALL get_molecule_kind(molecule_kind=molecule_kind, &
333 305960 : kind_number=i)
334 316462 : IF (counter /= i) THEN
335 137117 : counter = i
336 : CALL get_molecule(molecule=molecule, &
337 137117 : first_atom=first, last_atom=last)
338 137117 : natom = 0
339 137117 : IF (first /= 0 .AND. last /= 0) natom = last - first + 1
340 661977 : ALLOCATE (atom_list(natom))
341 387743 : DO i = 1, natom
342 : !Atomic kind information will be filled in (PART 2)
343 250626 : NULLIFY (atom_list(i)%atomic_kind)
344 250626 : atom_list(i)%id_name = atom_info%id_atmname(i + first - 1)
345 251416 : IF (iw > 0) WRITE (iw, '(5X,A,3I5,1X,A5)') "atom_list ", &
346 138697 : imol, counter, i, TRIM(id2str(atom_list(i)%id_name))
347 : END DO
348 137117 : CALL set_molecule_kind(molecule_kind=molecule_kind, atom_list=atom_list)
349 : END IF
350 : END DO
351 10502 : CALL timestop(handle2)
352 : !-----------------------------------------------------------------------------
353 : !-----------------------------------------------------------------------------
354 : ! 10. Set the molecule_kind%[nbond,bond_list] via set_molecule_kind
355 : !-----------------------------------------------------------------------------
356 10502 : CALL timeset(routineN//"_10", handle2)
357 : ! First map bonds on molecules
358 10502 : nvar1 = 0
359 10502 : nvar2 = 0
360 10502 : NULLIFY (map_vars, map_cvars, bnd_type, bnd_ctype)
361 10502 : IF (ASSOCIATED(conn_info%bond_a)) nvar1 = SIZE(conn_info%bond_a)
362 10502 : IF (ASSOCIATED(conn_info%c_bond_a)) nvar2 = SIZE(conn_info%c_bond_a)
363 10502 : nval_tot1 = nvar1
364 10502 : nval_tot2 = 0
365 23575 : ALLOCATE (map_var_mol(nvar1))
366 21158 : ALLOCATE (map_cvar_mol(nvar2))
367 519621 : map_var_mol = -1
368 13368 : map_cvar_mol = -1
369 519621 : DO i = 1, nvar1
370 509119 : j1 = map_atom_mol(conn_info%bond_a(i))
371 509119 : j2 = map_atom_mol(conn_info%bond_b(i))
372 519621 : IF (j1 == j2) THEN
373 506253 : IF (j1 > 0) map_var_mol(i) = map_atom_type(conn_info%bond_a(i))
374 : END IF
375 : END DO
376 13368 : 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 13368 : IF (j1 > 0) map_cvar_mol(i) = map_atom_type(min_index)
380 : END DO
381 10502 : CALL find_bnd_typ(topology%nmol_type, map_vars, map_var_mol, bnd_type, nvar1)
382 10502 : CALL find_bnd_typ(topology%nmol_type, map_cvars, map_cvar_mol, bnd_ctype, nvar2)
383 147619 : DO i = 1, topology%nmol_type
384 137117 : intra_bonds = 0
385 137117 : inter_bonds = 0
386 197791 : IF (ALL(bnd_type(:, i) > 0)) THEN
387 30337 : intra_bonds = bnd_type(2, i) - bnd_type(1, i) + 1
388 : END IF
389 142785 : IF (ALL(bnd_ctype(:, i) > 0)) THEN
390 2834 : inter_bonds = bnd_ctype(2, i) - bnd_ctype(1, i) + 1
391 : END IF
392 137117 : ibond = intra_bonds + inter_bonds
393 137117 : 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 137117 : molecule_kind => molecule_kind_set(i)
399 137117 : nval_tot2 = nval_tot2 + ibond*SIZE(molecule_kind%molecule_list)
400 :
401 421680 : ALLOCATE (bond_list(ibond))
402 137117 : ibond = 0
403 358138 : DO j = bnd_type(1, i), bnd_type(2, i)
404 221021 : IF (j == 0) CYCLE
405 114241 : ibond = ibond + 1
406 114241 : jind = map_vars(j)
407 114241 : first = first_list(map_atom_mol(conn_info%bond_a(jind)))
408 114241 : bond_list(ibond)%a = conn_info%bond_a(jind) - first + 1
409 114241 : 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 114241 : bond_list(ibond)%id_type = do_ff_charmm
412 114241 : 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 114241 : NULLIFY (bond_list(ibond)%bond_kind)
417 251358 : 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 274266 : DO j = bnd_ctype(1, i), bnd_ctype(2, i)
428 137149 : 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 139983 : 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 147619 : nbond=SIZE(bond_list), bond_list=bond_list)
454 : END DO
455 10502 : 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 10502 : CPASSERT(nval_tot1 == nval_tot2)
466 10502 : DEALLOCATE (map_var_mol)
467 10502 : DEALLOCATE (map_cvar_mol)
468 10502 : DEALLOCATE (map_vars)
469 10502 : DEALLOCATE (map_cvars)
470 10502 : DEALLOCATE (bnd_type)
471 10502 : DEALLOCATE (bnd_ctype)
472 10502 : 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 10502 : CALL timeset(routineN//"_11_pre", handle2)
479 10502 : idim = 0
480 10502 : ALLOCATE (c_var_a(idim))
481 10502 : ALLOCATE (c_var_b(idim))
482 10502 : ALLOCATE (c_var_c(idim))
483 10502 : found = ASSOCIATED(conn_info%theta_type)
484 10502 : IF (found) THEN
485 14 : ALLOCATE (c_var_type(idim))
486 : END IF
487 10502 : IF (ASSOCIATED(conn_info%c_bond_a) .AND. ASSOCIATED(conn_info%theta_a)) THEN
488 232076 : DO j = 1, SIZE(conn_info%theta_a)
489 223901 : j1 = map_atom_mol(conn_info%theta_a(j))
490 223901 : j2 = map_atom_mol(conn_info%theta_b(j))
491 223901 : j3 = map_atom_mol(conn_info%theta_c(j))
492 232076 : IF (j1 /= j2 .OR. j2 /= j3) THEN
493 11392 : idim = idim + 1
494 : END IF
495 : END DO
496 8175 : CALL reallocate(c_var_a, 1, idim)
497 8175 : CALL reallocate(c_var_b, 1, idim)
498 8175 : CALL reallocate(c_var_c, 1, idim)
499 8175 : IF (found) THEN
500 0 : CALL reallocate(c_var_type, 1, idim)
501 : END IF
502 8175 : idim = 0
503 232076 : DO j = 1, SIZE(conn_info%theta_a)
504 223901 : j1 = map_atom_mol(conn_info%theta_a(j))
505 223901 : j2 = map_atom_mol(conn_info%theta_b(j))
506 223901 : j3 = map_atom_mol(conn_info%theta_c(j))
507 232076 : 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 10502 : CALL timestop(handle2)
519 10502 : CALL timeset(routineN//"_11", handle2)
520 : ! map bends on molecules
521 10502 : nvar1 = 0
522 10502 : nvar2 = 0
523 : NULLIFY (map_vars, map_cvars, bnd_type, bnd_ctype)
524 10502 : IF (ASSOCIATED(conn_info%theta_a)) nvar1 = SIZE(conn_info%theta_a)
525 10502 : IF (ASSOCIATED(c_var_a)) nvar2 = SIZE(c_var_a)
526 10502 : nval_tot1 = nvar1
527 10502 : nval_tot2 = 0
528 23405 : ALLOCATE (map_var_mol(nvar1))
529 21158 : ALLOCATE (map_cvar_mol(nvar2))
530 283635 : map_var_mol = -1
531 21894 : map_cvar_mol = -1
532 283635 : DO i = 1, nvar1
533 273133 : j1 = map_atom_mol(conn_info%theta_a(i))
534 273133 : j2 = map_atom_mol(conn_info%theta_b(i))
535 273133 : j3 = map_atom_mol(conn_info%theta_c(i))
536 283635 : IF (j1 == j2 .AND. j2 == j3) THEN
537 261741 : IF (j1 > 0) map_var_mol(i) = map_atom_type(conn_info%theta_a(i))
538 : END IF
539 : END DO
540 21894 : 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 21894 : IF (j1 > 0) map_cvar_mol(i) = map_atom_type(min_index)
544 : END DO
545 10502 : CALL find_bnd_typ(topology%nmol_type, map_vars, map_var_mol, bnd_type, nvar1)
546 10502 : CALL find_bnd_typ(topology%nmol_type, map_cvars, map_cvar_mol, bnd_ctype, nvar2)
547 147619 : DO i = 1, topology%nmol_type
548 137117 : intra_bends = 0
549 137117 : inter_bends = 0
550 196779 : IF (ALL(bnd_type(:, i) > 0)) THEN
551 29831 : intra_bends = bnd_type(2, i) - bnd_type(1, i) + 1
552 : END IF
553 142785 : IF (ALL(bnd_ctype(:, i) > 0)) THEN
554 2834 : inter_bends = bnd_ctype(2, i) - bnd_ctype(1, i) + 1
555 : END IF
556 137117 : ibend = intra_bends + inter_bends
557 137117 : 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 137117 : molecule_kind => molecule_kind_set(i)
563 137117 : nval_tot2 = nval_tot2 + ibend*SIZE(molecule_kind%molecule_list)
564 446417 : ALLOCATE (bend_list(ibend))
565 137117 : ibend = 0
566 375361 : DO j = bnd_type(1, i), bnd_type(2, i)
567 238244 : IF (j == 0) CYCLE
568 130958 : ibend = ibend + 1
569 130958 : jind = map_vars(j)
570 130958 : first = first_list(map_atom_mol(conn_info%theta_a(jind)))
571 130958 : bend_list(ibend)%a = conn_info%theta_a(jind) - first + 1
572 130958 : bend_list(ibend)%b = conn_info%theta_b(jind) - first + 1
573 130958 : 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 130958 : bend_list(ibend)%id_type = do_ff_charmm
576 130958 : 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 130958 : NULLIFY (bend_list(ibend)%bend_kind)
581 268075 : 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 282792 : DO j = bnd_ctype(1, i), bnd_ctype(2, i)
594 145675 : 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 148509 : 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 147619 : nbend=SIZE(bend_list), bend_list=bend_list)
623 : END DO
624 10502 : CPASSERT(nval_tot1 == nval_tot2)
625 10502 : DEALLOCATE (map_var_mol)
626 10502 : DEALLOCATE (map_cvar_mol)
627 10502 : DEALLOCATE (map_vars)
628 10502 : DEALLOCATE (map_cvars)
629 10502 : DEALLOCATE (bnd_type)
630 10502 : DEALLOCATE (bnd_ctype)
631 10502 : DEALLOCATE (c_var_a)
632 10502 : DEALLOCATE (c_var_b)
633 10502 : DEALLOCATE (c_var_c)
634 10502 : IF (found) THEN
635 14 : DEALLOCATE (c_var_type)
636 : END IF
637 10502 : CALL timestop(handle2)
638 : !-----------------------------------------------------------------------------
639 : !-----------------------------------------------------------------------------
640 : ! 12. Set the molecule_kind%[nub,ub_list] via set_molecule_kind
641 : !-----------------------------------------------------------------------------
642 10502 : CALL timeset(routineN//"_12_pre", handle2)
643 10502 : idim = 0
644 10502 : ALLOCATE (c_var_a(idim))
645 10502 : ALLOCATE (c_var_b(idim))
646 10502 : ALLOCATE (c_var_c(idim))
647 10502 : IF (ASSOCIATED(conn_info%c_bond_a) .AND. ASSOCIATED(conn_info%ub_a)) THEN
648 232076 : DO j = 1, SIZE(conn_info%ub_a)
649 223901 : j1 = map_atom_mol(conn_info%ub_a(j))
650 223901 : j2 = map_atom_mol(conn_info%ub_b(j))
651 223901 : j3 = map_atom_mol(conn_info%ub_c(j))
652 232076 : IF (j1 /= j2 .OR. j2 /= j3) THEN
653 11392 : idim = idim + 1
654 : END IF
655 : END DO
656 8175 : CALL reallocate(c_var_a, 1, idim)
657 8175 : CALL reallocate(c_var_b, 1, idim)
658 8175 : CALL reallocate(c_var_c, 1, idim)
659 8175 : idim = 0
660 232076 : DO j = 1, SIZE(conn_info%ub_a)
661 223901 : j1 = map_atom_mol(conn_info%ub_a(j))
662 223901 : j2 = map_atom_mol(conn_info%ub_b(j))
663 223901 : j3 = map_atom_mol(conn_info%ub_c(j))
664 232076 : 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 10502 : CALL timestop(handle2)
673 10502 : CALL timeset(routineN//"_12", handle2)
674 : ! map UBs on molecules
675 10502 : nvar1 = 0
676 10502 : nvar2 = 0
677 : NULLIFY (map_vars, map_cvars, bnd_type, bnd_ctype)
678 10502 : IF (ASSOCIATED(conn_info%ub_a)) nvar1 = SIZE(conn_info%ub_a)
679 10502 : IF (ASSOCIATED(c_var_a)) nvar2 = SIZE(c_var_a)
680 10502 : nval_tot1 = nvar1
681 10502 : nval_tot2 = 0
682 23391 : ALLOCATE (map_var_mol(nvar1))
683 21158 : ALLOCATE (map_cvar_mol(nvar2))
684 283477 : map_var_mol = -1
685 21894 : map_cvar_mol = -1
686 283477 : DO i = 1, nvar1
687 272975 : j1 = map_atom_mol(conn_info%ub_a(i))
688 272975 : j2 = map_atom_mol(conn_info%ub_b(i))
689 272975 : j3 = map_atom_mol(conn_info%ub_c(i))
690 283477 : IF (j1 == j2 .AND. j2 == j3) THEN
691 261583 : IF (j1 > 0) map_var_mol(i) = map_atom_type(conn_info%ub_a(i))
692 : END IF
693 : END DO
694 21894 : 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 21894 : IF (j1 > 0) map_cvar_mol(i) = map_atom_type(min_index)
698 : END DO
699 10502 : CALL find_bnd_typ(topology%nmol_type, map_vars, map_var_mol, bnd_type, nvar1)
700 10502 : CALL find_bnd_typ(topology%nmol_type, map_cvars, map_cvar_mol, bnd_ctype, nvar2)
701 147619 : DO i = 1, topology%nmol_type
702 137117 : intra_ubs = 0
703 137117 : inter_ubs = 0
704 196751 : IF (ALL(bnd_type(:, i) > 0)) THEN
705 29817 : intra_ubs = bnd_type(2, i) - bnd_type(1, i) + 1
706 : END IF
707 142785 : IF (ALL(bnd_ctype(:, i) > 0)) THEN
708 2834 : inter_ubs = bnd_ctype(2, i) - bnd_ctype(1, i) + 1
709 : END IF
710 137117 : iub = intra_ubs + inter_ubs
711 137117 : 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 137117 : molecule_kind => molecule_kind_set(i)
717 137117 : nval_tot2 = nval_tot2 + iub*SIZE(molecule_kind%molecule_list)
718 446245 : ALLOCATE (ub_list(iub))
719 137117 : iub = 0
720 375217 : DO j = bnd_type(1, i), bnd_type(2, i)
721 238100 : IF (j == 0) CYCLE
722 130800 : iub = iub + 1
723 130800 : jind = map_vars(j)
724 130800 : first = first_list(map_atom_mol(conn_info%ub_a(jind)))
725 130800 : ub_list(iub)%a = conn_info%ub_a(jind) - first + 1
726 130800 : ub_list(iub)%b = conn_info%ub_b(jind) - first + 1
727 130800 : ub_list(iub)%c = conn_info%ub_c(jind) - first + 1
728 130800 : ub_list(iub)%id_type = do_ff_charmm
729 : !point this to the right ub_kind_type if using force field
730 130800 : NULLIFY (ub_list(iub)%ub_kind)
731 267917 : 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 282792 : DO j = bnd_ctype(1, i), bnd_ctype(2, i)
744 145675 : 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 148509 : 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 147619 : nub=SIZE(ub_list), ub_list=ub_list)
769 : END DO
770 10502 : CPASSERT(nval_tot1 == nval_tot2)
771 10502 : DEALLOCATE (map_var_mol)
772 10502 : DEALLOCATE (map_cvar_mol)
773 10502 : DEALLOCATE (map_vars)
774 10502 : DEALLOCATE (map_cvars)
775 10502 : DEALLOCATE (bnd_type)
776 10502 : DEALLOCATE (bnd_ctype)
777 10502 : DEALLOCATE (c_var_a)
778 10502 : DEALLOCATE (c_var_b)
779 10502 : DEALLOCATE (c_var_c)
780 10502 : 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 10502 : CALL timeset(routineN//"_13_pre", handle2)
787 10502 : idim = 0
788 10502 : ALLOCATE (c_var_a(idim))
789 10502 : ALLOCATE (c_var_b(idim))
790 10502 : ALLOCATE (c_var_c(idim))
791 10502 : ALLOCATE (c_var_d(idim))
792 10502 : found = ASSOCIATED(conn_info%phi_type)
793 10502 : IF (found) THEN
794 14 : ALLOCATE (c_var_type(idim))
795 : END IF
796 10502 : IF (ASSOCIATED(conn_info%c_bond_a) .AND. ASSOCIATED(conn_info%phi_a)) THEN
797 144870 : DO j = 1, SIZE(conn_info%phi_a)
798 136695 : j1 = map_atom_mol(conn_info%phi_a(j))
799 136695 : j2 = map_atom_mol(conn_info%phi_b(j))
800 136695 : j3 = map_atom_mol(conn_info%phi_c(j))
801 136695 : j4 = map_atom_mol(conn_info%phi_d(j))
802 144870 : IF (j1 /= j2 .OR. j2 /= j3 .OR. j3 /= j4) THEN
803 31630 : idim = idim + 1
804 : END IF
805 : END DO
806 8175 : CALL reallocate(c_var_a, 1, idim)
807 8175 : CALL reallocate(c_var_b, 1, idim)
808 8175 : CALL reallocate(c_var_c, 1, idim)
809 8175 : CALL reallocate(c_var_d, 1, idim)
810 8175 : IF (found) THEN
811 0 : CALL reallocate(c_var_type, 1, idim)
812 : END IF
813 8175 : idim = 0
814 144870 : DO j = 1, SIZE(conn_info%phi_a)
815 136695 : j1 = map_atom_mol(conn_info%phi_a(j))
816 136695 : j2 = map_atom_mol(conn_info%phi_b(j))
817 136695 : j3 = map_atom_mol(conn_info%phi_c(j))
818 136695 : j4 = map_atom_mol(conn_info%phi_d(j))
819 144870 : 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 10502 : CALL timestop(handle2)
832 10502 : CALL timeset(routineN//"_13", handle2)
833 : ! map torsions on molecules
834 10502 : nvar1 = 0
835 10502 : nvar2 = 0
836 : NULLIFY (map_vars, map_cvars, bnd_type, bnd_ctype)
837 10502 : IF (ASSOCIATED(conn_info%phi_a)) nvar1 = SIZE(conn_info%phi_a)
838 10502 : IF (ASSOCIATED(c_var_a)) nvar2 = SIZE(c_var_a)
839 10502 : nval_tot1 = nvar1
840 10502 : nval_tot2 = 0
841 21660 : ALLOCATE (map_var_mol(nvar1))
842 21156 : ALLOCATE (map_cvar_mol(nvar2))
843 178275 : map_var_mol = -1
844 42132 : map_cvar_mol = -1
845 178275 : DO i = 1, nvar1
846 167773 : j1 = map_atom_mol(conn_info%phi_a(i))
847 167773 : j2 = map_atom_mol(conn_info%phi_b(i))
848 167773 : j3 = map_atom_mol(conn_info%phi_c(i))
849 167773 : j4 = map_atom_mol(conn_info%phi_d(i))
850 178275 : IF (j1 == j2 .AND. j2 == j3 .AND. j3 == j4) THEN
851 136143 : IF (j1 > 0) map_var_mol(i) = map_atom_type(conn_info%phi_a(i))
852 : END IF
853 : END DO
854 42132 : 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 42132 : IF (j1 > 0) map_cvar_mol(i) = map_atom_type(min_index)
858 : END DO
859 10502 : CALL find_bnd_typ(topology%nmol_type, map_vars, map_var_mol, bnd_type, nvar1)
860 10502 : CALL find_bnd_typ(topology%nmol_type, map_cvars, map_cvar_mol, bnd_ctype, nvar2)
861 147619 : DO i = 1, topology%nmol_type
862 137117 : intra_torsions = 0
863 137117 : inter_torsions = 0
864 148361 : IF (ALL(bnd_type(:, i) > 0)) THEN
865 5622 : intra_torsions = bnd_type(2, i) - bnd_type(1, i) + 1
866 : END IF
867 142781 : IF (ALL(bnd_ctype(:, i) > 0)) THEN
868 2832 : inter_torsions = bnd_ctype(2, i) - bnd_ctype(1, i) + 1
869 : END IF
870 137117 : itorsion = intra_torsions + inter_torsions
871 137117 : 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 137117 : molecule_kind => molecule_kind_set(i)
877 137117 : nval_tot2 = nval_tot2 + itorsion*SIZE(molecule_kind%molecule_list)
878 438781 : ALLOCATE (torsion_list(itorsion))
879 137117 : itorsion = 0
880 395907 : DO j = bnd_type(1, i), bnd_type(2, i)
881 258790 : IF (j == 0) CYCLE
882 127295 : itorsion = itorsion + 1
883 127295 : jind = map_vars(j)
884 127295 : first = first_list(map_atom_mol(conn_info%phi_a(jind)))
885 127295 : torsion_list(itorsion)%a = conn_info%phi_a(jind) - first + 1
886 127295 : torsion_list(itorsion)%b = conn_info%phi_b(jind) - first + 1
887 127295 : torsion_list(itorsion)%c = conn_info%phi_c(jind) - first + 1
888 127295 : 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 127295 : torsion_list(itorsion)%id_type = do_ff_charmm
891 127295 : 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 127295 : NULLIFY (torsion_list(itorsion)%torsion_kind)
896 264412 : 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 303032 : DO j = bnd_ctype(1, i), bnd_ctype(2, i)
911 165915 : 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 168747 : 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 147619 : ntorsion=SIZE(torsion_list), torsion_list=torsion_list)
943 : END DO
944 10502 : CPASSERT(nval_tot1 == nval_tot2)
945 10502 : DEALLOCATE (map_var_mol)
946 10502 : DEALLOCATE (map_cvar_mol)
947 10502 : DEALLOCATE (map_vars)
948 10502 : DEALLOCATE (map_cvars)
949 10502 : DEALLOCATE (bnd_type)
950 10502 : DEALLOCATE (bnd_ctype)
951 10502 : DEALLOCATE (c_var_a)
952 10502 : DEALLOCATE (c_var_b)
953 10502 : DEALLOCATE (c_var_c)
954 10502 : DEALLOCATE (c_var_d)
955 10502 : IF (found) THEN
956 14 : DEALLOCATE (c_var_type)
957 : END IF
958 10502 : 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 10502 : CALL timeset(routineN//"_14_pre", handle2)
966 10502 : idim = 0
967 10502 : ALLOCATE (c_var_a(idim))
968 10502 : ALLOCATE (c_var_b(idim))
969 10502 : ALLOCATE (c_var_c(idim))
970 10502 : ALLOCATE (c_var_d(idim))
971 10502 : found = ASSOCIATED(conn_info%impr_type)
972 10502 : IF (found) THEN
973 14 : ALLOCATE (c_var_type(idim))
974 : END IF
975 10502 : IF (ASSOCIATED(conn_info%c_bond_a) .AND. ASSOCIATED(conn_info%impr_a)) THEN
976 12589 : 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 12589 : IF (j1 /= j2 .OR. j2 /= j3 .OR. j3 /= j4) THEN
982 3124 : idim = idim + 1
983 : END IF
984 : END DO
985 8175 : CALL reallocate(c_var_a, 1, idim)
986 8175 : CALL reallocate(c_var_b, 1, idim)
987 8175 : CALL reallocate(c_var_c, 1, idim)
988 8175 : CALL reallocate(c_var_d, 1, idim)
989 8175 : IF (found) THEN
990 0 : CALL reallocate(c_var_type, 1, idim)
991 : END IF
992 8175 : idim = 0
993 12589 : 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 12589 : 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 10502 : CALL timestop(handle2)
1011 10502 : CALL timeset(routineN//"_14", handle2)
1012 : ! map imprs on molecules
1013 10502 : nvar1 = 0
1014 10502 : nvar2 = 0
1015 : NULLIFY (map_vars, map_cvars, bnd_type, bnd_ctype)
1016 10502 : IF (ASSOCIATED(conn_info%impr_a)) nvar1 = SIZE(conn_info%impr_a)
1017 10502 : IF (ASSOCIATED(c_var_a)) nvar2 = SIZE(c_var_a)
1018 10502 : nval_tot1 = nvar1
1019 10502 : nval_tot2 = 0
1020 21150 : ALLOCATE (map_var_mol(nvar1))
1021 21044 : ALLOCATE (map_cvar_mol(nvar2))
1022 15912 : map_var_mol = -1
1023 13626 : map_cvar_mol = -1
1024 15912 : 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 15912 : 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 13626 : 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 13626 : IF (j1 > 0) map_cvar_mol(i) = map_atom_type(min_index)
1037 : END DO
1038 10502 : CALL find_bnd_typ(topology%nmol_type, map_vars, map_var_mol, bnd_type, nvar1)
1039 10502 : CALL find_bnd_typ(topology%nmol_type, map_cvars, map_cvar_mol, bnd_ctype, nvar2)
1040 147619 : DO i = 1, topology%nmol_type
1041 137117 : intra_imprs = 0
1042 137117 : inter_imprs = 0
1043 138205 : IF (ALL(bnd_type(:, i) > 0)) THEN
1044 544 : intra_imprs = bnd_type(2, i) - bnd_type(1, i) + 1
1045 : END IF
1046 140241 : IF (ALL(bnd_ctype(:, i) > 0)) THEN
1047 1562 : inter_imprs = bnd_ctype(2, i) - bnd_ctype(1, i) + 1
1048 : END IF
1049 137117 : iimpr = intra_imprs + inter_imprs
1050 137117 : 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 137117 : molecule_kind => molecule_kind_set(i)
1059 137117 : nval_tot2 = nval_tot2 + iimpr*SIZE(molecule_kind%molecule_list)
1060 281306 : ALLOCATE (impr_list(iimpr), STAT=stat)
1061 144189 : ALLOCATE (opbend_list(iimpr), STAT=stat)
1062 137117 : CPASSERT(stat == 0)
1063 137117 : iimpr = 0
1064 275952 : DO j = bnd_type(1, i), bnd_type(2, i)
1065 138835 : 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 139379 : 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 275796 : DO j = bnd_ctype(1, i), bnd_ctype(2, i)
1117 138679 : 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 140241 : 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 137117 : nimpr=SIZE(impr_list), impr_list=impr_list)
1167 : CALL set_molecule_kind(molecule_kind=molecule_kind, &
1168 147619 : nopbend=SIZE(opbend_list), opbend_list=opbend_list)
1169 : END DO
1170 10502 : CPASSERT(nval_tot1 == nval_tot2)
1171 10502 : DEALLOCATE (map_var_mol)
1172 10502 : DEALLOCATE (map_cvar_mol)
1173 10502 : DEALLOCATE (map_vars)
1174 10502 : DEALLOCATE (map_cvars)
1175 10502 : DEALLOCATE (bnd_type)
1176 10502 : DEALLOCATE (bnd_ctype)
1177 10502 : DEALLOCATE (c_var_a)
1178 10502 : DEALLOCATE (c_var_b)
1179 10502 : DEALLOCATE (c_var_c)
1180 10502 : DEALLOCATE (c_var_d)
1181 10502 : IF (found) THEN
1182 14 : DEALLOCATE (c_var_type)
1183 : END IF
1184 10502 : CALL timestop(handle2)
1185 : !-----------------------------------------------------------------------------
1186 : !-----------------------------------------------------------------------------
1187 : ! Finally deallocate some stuff.
1188 : !-----------------------------------------------------------------------------
1189 10502 : DEALLOCATE (first_list)
1190 10502 : DEALLOCATE (last_list)
1191 10502 : DEALLOCATE (map_atom_mol)
1192 10502 : DEALLOCATE (map_atom_type)
1193 10502 : CALL timestop(handle)
1194 : CALL cp_print_key_finished_output(iw, logger, subsys_section, &
1195 10502 : "PRINT%TOPOLOGY_INFO/UTIL_INFO")
1196 220542 : 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 105020 : 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 218855 : ALLOCATE (map_vars(nvar1))
1217 105020 : CALL sort(map_var_mol, nvar1, map_vars)
1218 315060 : ALLOCATE (bnd_type(2, nmol_type))
1219 4218530 : bnd_type = 0
1220 105020 : IF (nvar1 == 0) RETURN
1221 731669 : DO j = 1, nvar1
1222 731669 : IF (map_var_mol(j) /= -1) EXIT
1223 : END DO
1224 8815 : IF (j == nvar1 + 1) RETURN
1225 8783 : i = map_var_mol(j)
1226 8783 : bnd_type(1, i) = j
1227 574743 : DO ibond = j, nvar1
1228 574743 : IF (map_var_mol(ibond) /= i) THEN
1229 100264 : bnd_type(2, i) = ibond - 1
1230 100264 : i = map_var_mol(ibond)
1231 100264 : bnd_type(1, i) = ibond
1232 : END IF
1233 : END DO
1234 8783 : 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 10502 : 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 10502 : INTEGER, DIMENSION(:), POINTER :: multiple_unit_cell
1252 : TYPE(connectivity_info_type), POINTER :: conn_info
1253 :
1254 10502 : NULLIFY (multiple_unit_cell)
1255 : CALL section_vals_val_get(subsys_section, "TOPOLOGY%MULTIPLE_UNIT_CELL", &
1256 10502 : i_vals=multiple_unit_cell)
1257 41574 : IF (ANY(multiple_unit_cell /= 1)) THEN
1258 592 : fac = PRODUCT(multiple_unit_cell)
1259 148 : conn_info => topology%conn_info
1260 :
1261 148 : nbond = 0
1262 148 : IF (ASSOCIATED(conn_info%bond_a)) THEN
1263 148 : nbond = SIZE(conn_info%bond_a)
1264 148 : CALL reallocate(conn_info%bond_a, 1, nbond*fac)
1265 148 : CALL reallocate(conn_info%bond_b, 1, nbond*fac)
1266 : END IF
1267 :
1268 148 : ntheta = 0
1269 148 : IF (ASSOCIATED(conn_info%theta_a)) THEN
1270 148 : ntheta = SIZE(conn_info%theta_a)
1271 148 : CALL reallocate(conn_info%theta_a, 1, ntheta*fac)
1272 148 : CALL reallocate(conn_info%theta_b, 1, ntheta*fac)
1273 148 : CALL reallocate(conn_info%theta_c, 1, ntheta*fac)
1274 : END IF
1275 :
1276 148 : nphi = 0
1277 148 : IF (ASSOCIATED(conn_info%phi_a)) THEN
1278 148 : nphi = SIZE(conn_info%phi_a)
1279 148 : CALL reallocate(conn_info%phi_a, 1, nphi*fac)
1280 148 : CALL reallocate(conn_info%phi_b, 1, nphi*fac)
1281 148 : CALL reallocate(conn_info%phi_c, 1, nphi*fac)
1282 148 : CALL reallocate(conn_info%phi_d, 1, nphi*fac)
1283 : END IF
1284 :
1285 148 : nimpr = 0
1286 148 : IF (ASSOCIATED(conn_info%impr_a)) THEN
1287 148 : nimpr = SIZE(conn_info%impr_a)
1288 148 : CALL reallocate(conn_info%impr_a, 1, nimpr*fac)
1289 148 : CALL reallocate(conn_info%impr_b, 1, nimpr*fac)
1290 148 : CALL reallocate(conn_info%impr_c, 1, nimpr*fac)
1291 148 : CALL reallocate(conn_info%impr_d, 1, nimpr*fac)
1292 : END IF
1293 :
1294 148 : nbond_c = 0
1295 148 : IF (ASSOCIATED(conn_info%c_bond_a)) THEN
1296 116 : nbond_c = SIZE(conn_info%c_bond_a)
1297 116 : CALL reallocate(conn_info%c_bond_a, 1, nbond_c*fac)
1298 116 : CALL reallocate(conn_info%c_bond_b, 1, nbond_c*fac)
1299 : END IF
1300 :
1301 148 : nub = 0
1302 148 : IF (ASSOCIATED(conn_info%ub_a)) THEN
1303 148 : nub = SIZE(conn_info%ub_a)
1304 148 : CALL reallocate(conn_info%ub_a, 1, nub*fac)
1305 148 : CALL reallocate(conn_info%ub_b, 1, nub*fac)
1306 148 : CALL reallocate(conn_info%ub_c, 1, nub*fac)
1307 : END IF
1308 :
1309 148 : nonfo = 0
1310 148 : IF (ASSOCIATED(conn_info%onfo_a)) THEN
1311 148 : nonfo = SIZE(conn_info%onfo_a)
1312 148 : CALL reallocate(conn_info%onfo_a, 1, nonfo*fac)
1313 148 : CALL reallocate(conn_info%onfo_b, 1, nonfo*fac)
1314 : END IF
1315 :
1316 148 : natoms_orig = topology%natoms/fac
1317 148 : ind = 0
1318 556 : DO k = 1, multiple_unit_cell(3)
1319 1870 : DO j = 1, multiple_unit_cell(2)
1320 6698 : DO i = 1, multiple_unit_cell(1)
1321 4976 : ind = ind + 1
1322 4976 : IF (ind == 1) CYCLE
1323 4828 : a = (ind - 1)*natoms_orig
1324 :
1325 : ! Bonds
1326 4828 : 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 37232 : conn_info%bond_b(m + 1:m + nbond) = conn_info%bond_b(1:nbond) + a
1330 : END IF
1331 : ! Theta
1332 4828 : 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 39596 : conn_info%theta_b(m + 1:m + ntheta) = conn_info%theta_b(1:ntheta) + a
1336 39596 : conn_info%theta_c(m + 1:m + ntheta) = conn_info%theta_c(1:ntheta) + a
1337 : END IF
1338 : ! Phi
1339 4828 : 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 35770 : conn_info%phi_b(m + 1:m + nphi) = conn_info%phi_b(1:nphi) + a
1343 35770 : conn_info%phi_c(m + 1:m + nphi) = conn_info%phi_c(1:nphi) + a
1344 35770 : conn_info%phi_d(m + 1:m + nphi) = conn_info%phi_d(1:nphi) + a
1345 : END IF
1346 : ! Impropers
1347 4828 : 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 4828 : 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 4828 : 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 39596 : conn_info%ub_b(m + 1:m + nub) = conn_info%ub_b(1:nub) + a
1365 39596 : conn_info%ub_c(m + 1:m + nub) = conn_info%ub_c(1:nub) + a
1366 : END IF
1367 : ! ONFO
1368 6142 : 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 28378 : 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 10502 : END SUBROUTINE topology_conn_multiple
1379 :
1380 : END MODULE topology_connectivity_util
|