43 #include "./base/base_uses.f90"
47 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'topology_util'
51 INTEGER,
POINTER,
DIMENSION(:) :: array1 => null()
56 INTEGER,
POINTER,
DIMENSION(:) :: array1 => null()
57 INTEGER,
POINTER,
DIMENSION(:) :: array2 => null()
73 INTERFACE reorder_structure
74 MODULE PROCEDURE reorder_structure1d, reorder_structure2d
91 LOGICAL,
INTENT(in),
OPTIONAL :: qmmm
92 TYPE(qmmm_env_mm_type),
OPTIONAL,
POINTER :: qmmm_env_mm
93 TYPE(section_vals_type),
POINTER :: subsys_section, force_env_section
95 CHARACTER(len=*),
PARAMETER :: routinen =
'topology_reorder_atoms'
97 CHARACTER(LEN=default_string_length) :: mol_id
98 CHARACTER(LEN=default_string_length),
POINTER :: molname(:), telement(:), &
99 tlabel_atmname(:), tlabel_molname(:), &
101 INTEGER :: handle, i, iatm, iindex, ikind, imol, imol_ref, iref, iund, iw, j, k, location, &
102 max_mol_num, mm_index, n, n_rep, n_var, natom, natom_loc, nkind, nlinks, old_hash, &
103 old_mol, output_unit, qm_index, unique_mol
104 INTEGER,
DIMENSION(:),
POINTER :: mm_link_atoms, qm_atom_index
105 INTEGER,
POINTER :: atm_map1(:), atm_map2(:), atm_map3(:), map_atom_type(:), &
106 map_mol_hash(:), mm_indexes_n(:), mm_indexes_v(:), mol_bnd(:, :), mol_hash(:), &
107 mol_num(:), new_position(:), order(:), tmp_n(:), tmp_v(:), wrk(:)
108 LOGICAL :: explicit, matches, my_qmmm
109 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: tr
110 REAL(kind=
dp),
POINTER :: tatm_charge(:), tatm_mass(:)
114 TYPE(cp_logger_type),
POINTER :: logger
115 TYPE(graph_type),
DIMENSION(:),
POINTER :: reference_set
116 TYPE(section_vals_type),
POINTER :: generate_section, isolated_section, &
117 qm_kinds, qmmm_link_section, &
119 TYPE(vertex),
DIMENSION(:),
POINTER :: reference, unordered
121 NULLIFY (logger, generate_section, isolated_section, tmp_v, tmp_n)
124 extension=
".subsysLog")
125 CALL timeset(routinen, handle)
127 IF (output_unit > 0)
WRITE (output_unit,
'(T2,"REORDER | ")')
130 IF (
PRESENT(qmmm) .AND.
PRESENT(qmmm_env_mm)) my_qmmm = qmmm
136 NULLIFY (new_position, reference_set)
137 NULLIFY (tlabel_atmname, telement, mol_num, tlabel_molname, tlabel_resname)
138 NULLIFY (tr, tatm_charge, tatm_mass, atm_map1, atm_map2, atm_map3)
141 cpassert(.NOT.
ASSOCIATED(atom_info%map_mol_num))
142 cpassert(.NOT.
ASSOCIATED(atom_info%map_mol_typ))
143 cpassert(.NOT.
ASSOCIATED(atom_info%map_mol_res))
145 ALLOCATE (new_position(natom))
146 ALLOCATE (mol_num(natom))
147 ALLOCATE (molname(natom))
148 ALLOCATE (tlabel_atmname(natom))
149 ALLOCATE (tlabel_molname(natom))
150 ALLOCATE (tlabel_resname(natom))
151 ALLOCATE (tr(3, natom))
152 ALLOCATE (tatm_charge(natom))
153 ALLOCATE (tatm_mass(natom))
154 ALLOCATE (telement(natom))
155 ALLOCATE (atm_map1(natom))
156 ALLOCATE (atm_map2(natom))
160 ALLOCATE (map_atom_type(natom))
162 ALLOCATE (atom_bond_list(natom))
164 map_atom_type(i) = atom_info%id_atmname(i)
165 ALLOCATE (atom_bond_list(i)%array1(0))
168 IF (
ASSOCIATED(conn_info%bond_a)) n =
SIZE(conn_info%bond_a)
169 CALL reorder_structure(atom_bond_list, conn_info%bond_a, conn_info%bond_b, n)
170 ALLOCATE (atom_info%map_mol_num(natom))
171 atom_info%map_mol_num = -1
172 CALL find_molecule(atom_bond_list, atom_info%map_mol_num, atom_info%id_molname)
173 max_mol_num = maxval(atom_info%map_mol_num)
175 ALLOCATE (mol_bnd(2, max_mol_num))
176 ALLOCATE (mol_hash(max_mol_num))
177 ALLOCATE (map_mol_hash(max_mol_num))
180 CALL sort(atom_info%map_mol_num, natom, atm_map1)
185 IF (old_mol .NE. atom_info%map_mol_num(i))
THEN
186 old_mol = atom_info%map_mol_num(i)
189 mol_bnd(2, imol) = i - 1
195 atm_map2(atm_map1(i)) = iindex
197 mol_bnd(2, imol) = natom
200 iund = max_mol_num/2 + 1
202 NULLIFY (reference, unordered)
204 DO j = 1, max_mol_num
205 CALL setup_graph(j, reference, map_atom_type, &
206 atom_bond_list, mol_bnd, atm_map1, atm_map2)
208 ALLOCATE (order(
SIZE(reference)))
212 DO i = 1,
SIZE(reference)
213 DEALLOCATE (reference(i)%bonds)
215 DEALLOCATE (reference)
218 CALL sort(mol_hash, max_mol_num, map_mol_hash)
223 IF (output_unit > 0)
THEN
224 WRITE (output_unit,
'(T2,"REORDER | ",A)') &
225 "Reordering Molecules. The Reordering of molecules will override all", &
226 "information regarding molecule names and residue names.", &
227 "New ones will be provided on the basis of the connectivity!"
229 DO j = 1, max_mol_num
230 IF (mol_hash(j) .NE. old_hash)
THEN
231 unique_mol = unique_mol + 1
232 old_hash = mol_hash(j)
233 CALL setup_graph_set(reference_set, unique_mol, map_mol_hash(j), &
234 map_atom_type, atom_bond_list, mol_bnd, atm_map1, atm_map2, &
237 mol_id = trim(adjustl(cp_to_string(unique_mol)))
238 DO i = 1,
SIZE(atm_map3)
239 natom_loc = natom_loc + 1
240 new_position(natom_loc) = atm_map3(i)
241 molname(natom_loc) = mol_id
242 mol_num(natom_loc) = unique_mol
244 DEALLOCATE (atm_map3)
246 CALL setup_graph(map_mol_hash(j), unordered, map_atom_type, &
247 atom_bond_list, mol_bnd, atm_map1, atm_map2, atm_map3)
248 DO imol_ref = 1, unique_mol
250 reference => reference_set(imol_ref)%graph
251 ALLOCATE (order(
SIZE(reference)))
258 ALLOCATE (wrk(
SIZE(order)))
259 CALL sort(order,
SIZE(order), wrk)
260 DO i = 1,
SIZE(order)
261 natom_loc = natom_loc + 1
262 new_position(natom_loc) = atm_map3(wrk(i))
263 molname(natom_loc) = mol_id
264 mol_num(natom_loc) = unique_mol
270 unique_mol = unique_mol + 1
271 CALL setup_graph_set(reference_set, unique_mol, map_mol_hash(j), &
272 map_atom_type, atom_bond_list, mol_bnd, atm_map1, atm_map2, &
275 mol_id = trim(adjustl(cp_to_string(unique_mol)))
276 DO i = 1,
SIZE(atm_map3)
277 natom_loc = natom_loc + 1
278 new_position(natom_loc) = atm_map3(i)
279 molname(natom_loc) = mol_id
280 mol_num(natom_loc) = unique_mol
282 DEALLOCATE (atm_map3)
284 DO i = 1,
SIZE(unordered)
285 DEALLOCATE (unordered(i)%bonds)
287 DEALLOCATE (unordered)
288 DEALLOCATE (atm_map3)
291 IF (output_unit > 0)
THEN
292 WRITE (output_unit,
'(T2,"REORDER | ",A,I7,A)')
"Number of unique molecules found:", unique_mol,
"."
294 cpassert(natom_loc == natom)
295 DEALLOCATE (map_atom_type)
296 DEALLOCATE (atm_map1)
297 DEALLOCATE (atm_map2)
299 DEALLOCATE (mol_hash)
300 DEALLOCATE (map_mol_hash)
303 DEALLOCATE (atom_bond_list(i)%array1)
305 DEALLOCATE (atom_bond_list)
306 DEALLOCATE (atom_info%map_mol_num)
308 DO i = 1,
SIZE(reference_set)
309 DO j = 1,
SIZE(reference_set(i)%graph)
310 DEALLOCATE (reference_set(i)%graph(j)%bonds)
312 DEALLOCATE (reference_set(i)%graph)
314 DEALLOCATE (reference_set)
317 location = new_position(iatm)
318 tlabel_molname(iatm) =
id2str(atom_info%id_molname(location))
319 tlabel_resname(iatm) =
id2str(atom_info%id_resname(location))
320 tlabel_atmname(iatm) =
id2str(atom_info%id_atmname(location))
321 telement(iatm) =
id2str(atom_info%id_element(location))
322 tr(1, iatm) = atom_info%r(1, location)
323 tr(2, iatm) = atom_info%r(2, location)
324 tr(3, iatm) = atom_info%r(3, location)
325 tatm_charge(iatm) = atom_info%atm_charge(location)
326 tatm_mass(iatm) = atom_info%atm_mass(location)
330 tlabel_molname(iatm) =
"MOL"//trim(molname(iatm))
331 tlabel_resname(iatm) =
"R"//trim(molname(iatm))
336 atom_info%id_molname(iatm) =
str2id(tlabel_molname(iatm))
337 atom_info%id_resname(iatm) =
str2id(tlabel_resname(iatm))
338 atom_info%id_atmname(iatm) =
str2id(tlabel_atmname(iatm))
339 atom_info%id_element(iatm) =
str2id(telement(iatm))
340 atom_info%resid(iatm) = mol_num(iatm)
341 atom_info%r(1, iatm) = tr(1, iatm)
342 atom_info%r(2, iatm) = tr(2, iatm)
343 atom_info%r(3, iatm) = tr(3, iatm)
344 atom_info%atm_charge(iatm) = tatm_charge(iatm)
345 atom_info%atm_mass(iatm) = tatm_mass(iatm)
349 ALLOCATE (wrk(
SIZE(new_position)))
350 CALL sort(new_position,
SIZE(new_position), wrk)
357 cpassert(
SIZE(qmmm_env_mm%qm_atom_index) /= 0)
358 cpassert(all(qmmm_env_mm%qm_atom_index /= 0))
359 ALLOCATE (qm_atom_index(
SIZE(qmmm_env_mm%qm_atom_index)))
360 DO iatm = 1,
SIZE(qmmm_env_mm%qm_atom_index)
361 qm_atom_index(iatm) = wrk(qmmm_env_mm%qm_atom_index(iatm))
363 qmmm_env_mm%qm_atom_index = qm_atom_index
364 cpassert(all(qmmm_env_mm%qm_atom_index /= 0))
365 DEALLOCATE (qm_atom_index)
375 ALLOCATE (mm_indexes_n(
SIZE(mm_indexes_v)))
376 DO j = 1,
SIZE(mm_indexes_v)
377 mm_indexes_n(j) = wrk(mm_indexes_v(j))
380 i_vals_ptr=mm_indexes_n, i_rep_val=k)
384 IF (qmmm_env_mm%qmmm_link)
THEN
386 cpassert(
SIZE(qmmm_env_mm%mm_link_atoms) > 0)
387 ALLOCATE (mm_link_atoms(
SIZE(qmmm_env_mm%mm_link_atoms)))
388 DO iatm = 1,
SIZE(qmmm_env_mm%mm_link_atoms)
389 mm_link_atoms(iatm) = wrk(qmmm_env_mm%mm_link_atoms(iatm))
391 qmmm_env_mm%mm_link_atoms = mm_link_atoms
392 cpassert(all(qmmm_env_mm%mm_link_atoms /= 0))
393 DEALLOCATE (mm_link_atoms)
397 cpassert(nlinks /= 0)
401 mm_index = wrk(mm_index)
402 qm_index = wrk(qm_index)
418 ALLOCATE (tmp_n(
SIZE(tmp_v)))
419 DO j = 1,
SIZE(tmp_v)
420 tmp_n(j) = wrk(tmp_v(j))
427 DEALLOCATE (new_position)
428 DEALLOCATE (tlabel_atmname)
429 DEALLOCATE (tlabel_molname)
430 DEALLOCATE (tlabel_resname)
431 DEALLOCATE (telement)
433 DEALLOCATE (tatm_charge)
434 DEALLOCATE (tatm_mass)
439 DEALLOCATE (conn_info%bond_a)
440 DEALLOCATE (conn_info%bond_b)
441 IF (output_unit > 0)
WRITE (output_unit,
'(T2,"REORDER | ")')
442 CALL timestop(handle)
444 "PRINT%TOPOLOGY_INFO/UTIL_INFO")
460 SUBROUTINE setup_graph_set(graph_set, idim, ind, array2, atom_bond_list, map_mol, &
461 atm_map1, atm_map2, atm_map3)
462 TYPE(graph_type),
DIMENSION(:),
POINTER :: graph_set
463 INTEGER,
INTENT(IN) :: idim, ind
464 INTEGER,
DIMENSION(:),
POINTER :: array2
466 INTEGER,
DIMENSION(:, :),
POINTER :: map_mol
467 INTEGER,
DIMENSION(:),
POINTER :: atm_map1, atm_map2, atm_map3
470 TYPE(graph_type),
DIMENSION(:),
POINTER :: tmp_graph_set
473 NULLIFY (tmp_graph_set)
474 IF (
ASSOCIATED(graph_set))
THEN
475 ldim =
SIZE(graph_set)
476 cpassert(ldim + 1 == idim)
478 NULLIFY (tmp_graph_set)
479 CALL allocate_graph_set(graph_set, tmp_graph_set)
481 CALL allocate_graph_set(tmp_graph_set, graph_set, ldim, ldim + 1)
482 CALL setup_graph(ind, graph_set(ldim + 1)%graph, array2, &
483 atom_bond_list, map_mol, atm_map1, atm_map2, atm_map3)
485 END SUBROUTINE setup_graph_set
495 SUBROUTINE allocate_graph_set(graph_set_in, graph_set_out, ldim_in, ldim_out)
496 TYPE(graph_type),
DIMENSION(:),
POINTER :: graph_set_in, graph_set_out
497 INTEGER,
INTENT(IN),
OPTIONAL :: ldim_in, ldim_out
499 INTEGER :: b_dim, i, j, mydim_in, mydim_out, v_dim
501 cpassert(.NOT.
ASSOCIATED(graph_set_out))
504 IF (
ASSOCIATED(graph_set_in))
THEN
505 mydim_in =
SIZE(graph_set_in)
506 mydim_out =
SIZE(graph_set_in)
508 IF (
PRESENT(ldim_in)) mydim_in = ldim_in
509 IF (
PRESENT(ldim_out)) mydim_out = ldim_out
510 ALLOCATE (graph_set_out(mydim_out))
512 NULLIFY (graph_set_out(i)%graph)
516 v_dim =
SIZE(graph_set_in(i)%graph)
517 ALLOCATE (graph_set_out(i)%graph(v_dim))
519 graph_set_out(i)%graph(j)%kind = graph_set_in(i)%graph(j)%kind
520 b_dim =
SIZE(graph_set_in(i)%graph(j)%bonds)
521 ALLOCATE (graph_set_out(i)%graph(j)%bonds(b_dim))
522 graph_set_out(i)%graph(j)%bonds = graph_set_in(i)%graph(j)%bonds
523 DEALLOCATE (graph_set_in(i)%graph(j)%bonds)
525 DEALLOCATE (graph_set_in(i)%graph)
527 IF (
ASSOCIATED(graph_set_in))
THEN
528 DEALLOCATE (graph_set_in)
531 END SUBROUTINE allocate_graph_set
545 SUBROUTINE setup_graph(ind, graph, array2, atom_bond_list, map_mol, &
546 atm_map1, atm_map2, atm_map3)
547 INTEGER,
INTENT(IN) :: ind
548 TYPE(vertex),
DIMENSION(:),
POINTER ::
graph
549 INTEGER,
DIMENSION(:),
POINTER :: array2
551 INTEGER,
DIMENSION(:, :),
POINTER :: map_mol
552 INTEGER,
DIMENSION(:),
POINTER :: atm_map1, atm_map2
553 INTEGER,
DIMENSION(:),
OPTIONAL,
POINTER :: atm_map3
555 INTEGER :: i, idim, ifirst, ilast, j, nbonds, &
558 IF (
PRESENT(atm_map3))
THEN
559 cpassert(.NOT.
ASSOCIATED(atm_map3))
561 cpassert(.NOT.
ASSOCIATED(
graph))
564 ifirst = map_mol(1, ind)
565 ilast = map_mol(2, ind)
566 nelement = ilast - ifirst + 1
567 ALLOCATE (
graph(nelement))
568 IF (
PRESENT(atm_map3))
THEN
569 ALLOCATE (atm_map3(nelement))
573 graph(idim)%kind = array2(atm_map1(i))
574 nbonds =
SIZE(atom_bond_list(atm_map1(i))%array1)
575 ALLOCATE (
graph(idim)%bonds(nbonds))
577 graph(idim)%bonds(j) = atm_map2(atom_bond_list(atm_map1(i))%array1(j))
579 IF (
PRESENT(atm_map3))
THEN
580 atm_map3(idim) = atm_map1(i)
584 END SUBROUTINE setup_graph
597 INTEGER,
DIMENSION(:),
POINTER :: ilist1
598 INTEGER,
DIMENSION(:),
OPTIONAL,
POINTER :: ilist2, ilist3, ilist4
599 INTEGER,
INTENT(IN) :: nsize, ndim
601 INTEGER :: i, iend, istart, ldim
602 INTEGER,
DIMENSION(:),
POINTER :: tmp, wrk
606 CALL sort(ilist1, ndim, wrk)
611 ilist2(i) = tmp(wrk(i))
617 ilist3(i) = tmp(wrk(i))
622 ilist3(i) = tmp(wrk(i))
626 ilist4(i) = tmp(wrk(i))
632 IF (ilist1(i) /= ilist1(istart))
THEN
634 ldim = iend - istart + 1
635 CALL reorder_list_array_low(ilist2, ilist3, ilist4, nsize, &
642 ldim = iend - istart + 1
643 CALL reorder_list_array_low(ilist2, ilist3, ilist4, nsize, &
660 RECURSIVE SUBROUTINE reorder_list_array_low(Ilist2, Ilist3, Ilist4, nsize, &
662 INTEGER,
DIMENSION(:),
OPTIONAL,
POINTER :: ilist2, ilist3, ilist4
663 INTEGER,
INTENT(IN) :: nsize, ldim, istart, iend
665 INTEGER,
DIMENSION(:),
POINTER :: tmp_2, tmp_3, tmp_4
669 ALLOCATE (tmp_2(ldim))
670 tmp_2(:) = ilist2(istart:iend)
672 ilist2(istart:iend) = tmp_2(:)
675 ALLOCATE (tmp_2(ldim))
676 ALLOCATE (tmp_3(ldim))
677 tmp_2(:) = ilist2(istart:iend)
678 tmp_3(:) = ilist3(istart:iend)
680 ilist2(istart:iend) = tmp_2(:)
681 ilist3(istart:iend) = tmp_3(:)
685 ALLOCATE (tmp_2(ldim))
686 ALLOCATE (tmp_3(ldim))
687 ALLOCATE (tmp_4(ldim))
688 tmp_2(:) = ilist2(istart:iend)
689 tmp_3(:) = ilist3(istart:iend)
690 tmp_4(:) = ilist4(istart:iend)
692 ilist2(istart:iend) = tmp_2(:)
693 ilist3(istart:iend) = tmp_3(:)
694 ilist4(istart:iend) = tmp_4(:)
700 END SUBROUTINE reorder_list_array_low
713 LOGICAL,
DIMENSION(:),
POINTER :: icheck
715 INTEGER,
INTENT(IN) :: i
716 INTEGER,
INTENT(INOUT) :: mol_natom
717 INTEGER,
DIMENSION(:),
POINTER :: mol_map
718 INTEGER,
INTENT(IN) :: my_mol
722 IF (mol_map(i) == my_mol)
THEN
724 DO j = 1,
SIZE(bond_list(i)%array1)
725 k = bond_list(i)%array1(j)
727 mol_natom = mol_natom + 1
746 INTEGER,
DIMENSION(:),
POINTER :: icheck
748 INTEGER,
INTENT(IN) :: i, my_mol
753 DO j = 1,
SIZE(bond_list(i)%array1)
754 k = bond_list(i)%array1(j)
770 SUBROUTINE reorder_structure1d(work, list1, list2, N)
772 INTENT(INOUT) :: work
773 INTEGER,
DIMENSION(:),
INTENT(IN) :: list1, list2
774 INTEGER,
INTENT(IN) :: n
776 INTEGER :: i, index1, index2, nsize
777 INTEGER,
DIMENSION(:),
POINTER :: wrk_tmp
783 wrk_tmp => work(index1)%array1
784 nsize =
SIZE(wrk_tmp)
785 ALLOCATE (work(index1)%array1(nsize + 1))
786 work(index1)%array1(1:nsize) = wrk_tmp
787 work(index1)%array1(nsize + 1) = index2
790 wrk_tmp => work(index2)%array1
791 nsize =
SIZE(wrk_tmp)
792 ALLOCATE (work(index2)%array1(nsize + 1))
793 work(index2)%array1(1:nsize) = wrk_tmp
794 work(index2)%array1(nsize + 1) = index1
798 END SUBROUTINE reorder_structure1d
810 SUBROUTINE reorder_structure2d(work, list1, list2, list3, N)
812 INTENT(INOUT) :: work
813 INTEGER,
DIMENSION(:),
INTENT(IN) :: list1, list2, list3
814 INTEGER,
INTENT(IN) :: n
816 INTEGER :: i, index1, index2, index3, nsize
817 INTEGER,
DIMENSION(:),
POINTER :: wrk_tmp
824 wrk_tmp => work(index1)%array1
825 nsize =
SIZE(wrk_tmp)
826 ALLOCATE (work(index1)%array1(nsize + 1))
827 work(index1)%array1(1:nsize) = wrk_tmp
828 work(index1)%array1(nsize + 1) = index2
831 wrk_tmp => work(index2)%array1
832 nsize =
SIZE(wrk_tmp)
833 ALLOCATE (work(index2)%array1(nsize + 1))
834 work(index2)%array1(1:nsize) = wrk_tmp
835 work(index2)%array1(nsize + 1) = index1
838 wrk_tmp => work(index1)%array2
839 nsize =
SIZE(wrk_tmp)
840 ALLOCATE (work(index1)%array2(nsize + 1))
841 work(index1)%array2(1:nsize) = wrk_tmp
842 work(index1)%array2(nsize + 1) = index3
845 wrk_tmp => work(index2)%array2
846 nsize =
SIZE(wrk_tmp)
847 ALLOCATE (work(index2)%array2(nsize + 1))
848 work(index2)%array2(1:nsize) = wrk_tmp
849 work(index2)%array2(nsize + 1) = -index3
853 END SUBROUTINE reorder_structure2d
866 INTEGER,
DIMENSION(:),
POINTER :: mol_info, mol_name
868 INTEGER :: i, my_mol_name, n, nmol
870 n =
SIZE(atom_bond_list)
873 IF (mol_info(i) == -1)
THEN
875 my_mol_name = mol_name(i)
876 CALL spread_mol(atom_bond_list, mol_info, i, nmol, my_mol_name, &
892 RECURSIVE SUBROUTINE spread_mol(atom_bond_list, mol_info, iatom, imol, &
893 my_mol_name, mol_name)
895 INTEGER,
DIMENSION(:),
POINTER :: mol_info
896 INTEGER,
INTENT(IN) :: iatom, imol, my_mol_name
897 INTEGER,
DIMENSION(:),
POINTER :: mol_name
901 mol_info(iatom) = imol
902 DO i = 1,
SIZE(atom_bond_list(iatom)%array1)
903 atom_b = atom_bond_list(iatom)%array1(i)
907 IF (mol_info(atom_b) == -1 .AND. my_mol_name == mol_name(atom_b))
THEN
908 CALL spread_mol(atom_bond_list, mol_info, atom_b, imol, my_mol_name, mol_name)
909 IF (mol_info(atom_b) /= imol) cpabort(
"internal error")
912 END SUBROUTINE spread_mol
921 TYPE(section_vals_type),
POINTER :: subsys_section
923 CHARACTER(len=*),
PARAMETER :: routinen =
'topology_set_atm_mass'
925 CHARACTER(LEN=2) :: upper_sym_1
926 CHARACTER(LEN=default_string_length) :: atmname_upper
927 CHARACTER(LEN=default_string_length), &
928 DIMENSION(:),
POINTER :: keyword
929 INTEGER :: handle, i, i_rep, iatom, ielem_found, &
931 LOGICAL :: user_defined
932 REAL(kind=
dp),
DIMENSION(:),
POINTER :: mass
934 TYPE(cp_logger_type),
POINTER :: logger
935 TYPE(section_vals_type),
POINTER :: kind_section
940 extension=
".subsysLog")
941 CALL timeset(routinen, handle)
949 ALLOCATE (keyword(n_rep))
950 ALLOCATE (mass(n_rep))
954 c_val=keyword(i_rep), i_rep_section=i_rep)
957 keyword_name=
"MASS", n_rep_val=i)
959 keyword_name=
"MASS", r_val=mass(i_rep))
965 user_defined = .false.
966 DO i = 1,
SIZE(keyword)
967 atmname_upper =
id2str(atom_info%id_atmname(iatom))
969 IF (trim(atmname_upper) == trim(keyword(i)) .AND. mass(i) /= huge(0.0_dp))
THEN
970 atom_info%atm_mass(iatom) = mass(i)
971 user_defined = .true.
976 IF (.NOT. user_defined)
THEN
977 upper_sym_1 =
id2str(atom_info%id_element(iatom))
978 CALL get_ptable_info(symbol=upper_sym_1, ielement=ielem_found, amass=atom_info%atm_mass(iatom))
980 IF (iw > 0)
WRITE (iw,
'(7X,A,A5,A,F12.5)')
"In topology_set_atm_mass :: element = ", &
981 id2str(atom_info%id_element(iatom)),
" a_mass ", atom_info%atm_mass(iatom)
986 CALL timestop(handle)
988 "PRINT%TOPOLOGY_INFO/UTIL_INFO")
999 TYPE(section_vals_type),
POINTER :: subsys_section
1001 CHARACTER(len=*),
PARAMETER :: routinen =
'topology_molecules_check'
1003 INTEGER :: counter, first, first_loc, handle, i, &
1004 iatom, iw, k, loc_counter, mol_num, &
1006 LOGICAL :: icheck_num, icheck_typ
1010 TYPE(cp_logger_type),
POINTER :: logger
1015 extension=
".subsysLog")
1016 CALL timeset(routinen, handle)
1022 IF (iw > 0)
WRITE (iw,
'(A)')
"Start of Molecule_Check", &
1023 " Checking consistency between the generated molecules"
1025 ALLOCATE (atom_bond_list(natom))
1027 ALLOCATE (atom_bond_list(i)%array1(0))
1030 IF (
ASSOCIATED(conn_info%bond_a)) n =
SIZE(conn_info%bond_a)
1031 CALL reorder_structure(atom_bond_list, conn_info%bond_a, conn_info%bond_b, n)
1033 mol_typ = atom_info%map_mol_typ(1)
1034 mol_num = atom_info%map_mol_num(1)
1040 icheck_num = (atom_info%map_mol_num(iatom) == mol_num)
1041 icheck_typ = (atom_info%map_mol_typ(iatom) == mol_typ)
1042 IF ((icheck_typ .AND. (.NOT. icheck_num)) .OR. (.NOT. icheck_typ))
THEN
1047 IF (counter /= loc_counter)
THEN
1048 CALL cp_abort(__location__, &
1049 "different number of atoms for same molecule kind"// &
1050 " molecule type = "//cp_to_string(mol_typ)// &
1051 " molecule number= "//cp_to_string(mol_num)// &
1052 " expected number of atoms="//cp_to_string(counter)//
" found="// &
1053 cp_to_string(loc_counter))
1056 IF (.NOT. icheck_typ)
THEN
1061 mol_typ = atom_info%map_mol_typ(iatom)
1063 IF (icheck_num)
THEN
1064 IF (icheck_typ) loc_counter = loc_counter + 1
1069 IF (atom_info%id_atmname(iatom) /= &
1070 atom_info%id_atmname(first + loc_counter - 1))
THEN
1071 CALL cp_abort(__location__, &
1072 "different atom name for same molecule kind"// &
1073 " atom number = "//cp_to_string(iatom)// &
1074 " molecule type = "//cp_to_string(mol_typ)// &
1075 " molecule number= "//cp_to_string(mol_num)// &
1076 " expected atom name="//trim(
id2str(atom_info%id_atmname(first + loc_counter - 1)))// &
1077 " found="//trim(
id2str(atom_info%id_atmname(iatom))))
1083 IF (
SIZE(atom_bond_list(iatom)%array1) /=
SIZE(atom_bond_list(first + loc_counter - 1)%array1))
THEN
1084 CALL cp_abort(__location__, &
1085 "different number of bonds for same molecule kind"// &
1086 " molecule type = "//cp_to_string(mol_typ)// &
1087 " molecule number= "//cp_to_string(mol_num)// &
1088 " expected bonds="// &
1089 cp_to_string(
SIZE(atom_bond_list(first + loc_counter - 1)%array1))//
" - "// &
1090 cp_to_string(
SIZE(atom_bond_list(iatom)%array1))// &
1091 " NOT FOUND! Check the connectivity of your system.")
1094 DO k = 1,
SIZE(atom_bond_list(iatom)%array1)
1095 IF (all(atom_bond_list(first + loc_counter - 1)%array1 - first /= &
1096 atom_bond_list(iatom)%array1(k) - first_loc))
THEN
1097 CALL cp_abort(__location__, &
1098 "different sequence of bonds for same molecule kind"// &
1099 " molecule type = "//cp_to_string(mol_typ)// &
1100 " molecule number= "//cp_to_string(mol_num)// &
1101 " NOT FOUND! Check the connectivity of your system.")
1105 mol_num = atom_info%map_mol_num(iatom)
1109 IF (mol_num == 1 .AND. icheck_typ) counter = counter + 1
1111 IF (iw > 0)
WRITE (iw,
'(A)')
"End of Molecule_Check"
1114 DEALLOCATE (atom_bond_list(i)%array1)
1116 DEALLOCATE (atom_bond_list)
1117 CALL timestop(handle)
1119 "PRINT%TOPOLOGY_INFO/UTIL_INFO")
1135 CHARACTER(len=*),
INTENT(IN) :: element_in, atom_name_in
1136 CHARACTER(len=default_string_length),
INTENT(OUT) :: element_out
1137 TYPE(section_vals_type),
POINTER :: subsys_section
1138 LOGICAL :: use_mm_map_first
1140 CHARACTER(len=default_string_length) :: atom_name, element_symbol, keyword
1141 INTEGER :: i, i_rep, n_rep
1142 LOGICAL :: defined_kind_section, found, in_ptable
1143 TYPE(section_vals_type),
POINTER :: kind_section
1146 element_symbol = element_in
1147 atom_name = atom_name_in
1149 defined_kind_section = .false.
1158 c_val=keyword, i_rep_section=i_rep)
1160 IF (trim(keyword) == trim(atom_name))
THEN
1162 keyword_name=
"ELEMENT", n_rep_val=i)
1165 keyword_name=
"ELEMENT", c_val=element_symbol)
1166 defined_kind_section = .true.
1169 element_symbol = element_in
1170 defined_kind_section = .true.
1179 IF (defined_kind_section .OR. .NOT. use_mm_map_first)
THEN
1182 IF (len_trim(element_symbol) <= 2)
CALL get_ptable_info(element_symbol, found=in_ptable)
1184 element_out = trim(element_symbol)
1190 IF (.NOT. found .AND. defined_kind_section) &
1191 CALL cp_abort(__location__,
"Element <"//trim(element_symbol)// &
1192 "> provided for KIND <"//trim(atom_name_in)//
"> "// &
1193 "which cannot be mapped with any standard element label. Please correct your "// &
1198 IF ((.NOT. found) .AND. (
ASSOCIATED(
amber_map)))
THEN
1201 IF (element_symbol ==
amber_map%kind(i))
THEN
1210 IF ((.NOT. found) .AND. (
ASSOCIATED(
charmm_map)))
THEN
1213 IF (element_symbol ==
charmm_map%kind(i))
THEN
1222 IF ((.NOT. found) .AND. (
ASSOCIATED(
gromos_map)))
THEN
1225 IF (element_symbol ==
gromos_map%kind(i))
THEN
1237 IF (.NOT. found)
THEN
1239 IF (len_trim(element_symbol) <= 2)
CALL get_ptable_info(element_symbol, found=in_ptable)
1241 element_out = trim(element_symbol)
1247 IF (.NOT. found)
THEN
1248 CALL cp_abort(__location__, &
1249 " Unknown element for KIND <"//trim(atom_name_in)//
">."// &
1250 " This problem can be fixed specifying properly elements in PDB"// &
1251 " or specifying a KIND section or getting in touch with one of"// &
program graph
Program to Map on grid the hills spawned during a metadynamics run.
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
uses a combination of graphs and hashing to determine if two molecules are topologically equivalent,...
subroutine, public hash_molecule(reference, kind_ref, hash)
hashes a molecule to a number. Molecules that are the (topologically) the same have the same hash....
subroutine, public reorder_graph(reference, unordered, order, matches)
If two molecules are topologically the same, finds the ordering that maps the unordered one on the or...
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Contains the mapping ATOM_KIND -> ELEMENT for the most common cases in CHARMM and AMBER This should a...
type(ff_map_type), pointer, public charmm_map
type(ff_map_type), pointer, public gromos_map
type(ff_map_type), pointer, public amber_map
Periodic Table related data definitions.
subroutine, public get_ptable_info(symbol, number, amass, ielement, covalent_radius, metallic_radius, vdw_radius, found)
Pass information about the kind given the element symbol.
generates a unique id number for a string (str2id) that can be used two compare two strings....
integer function, public str2id(str)
returns a unique id for a given string, and stores the string for later retrieval using the id.
character(len=default_string_length) function, public id2str(id)
returns the string associated with a given id
Utilities for string manipulations.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
Collection of subroutine needed for topology related things.
subroutine, public topology_molecules_check(topology, subsys_section)
Check and verify that all molecules of the same kind are bonded the same.
subroutine, public find_molecule(atom_bond_list, mol_info, mol_name)
each atom will be assigned a molecule number based on bonded fragments The array mol_info should be i...
recursive subroutine, public give_back_molecule(icheck, bond_list, i, mol_natom, mol_map, my_mol)
...
recursive subroutine, public reorder_list_array(Ilist1, Ilist2, Ilist3, Ilist4, nsize, ndim)
Order arrays of lists.
subroutine, public topology_reorder_atoms(topology, qmmm, qmmm_env_mm, subsys_section, force_env_section)
...
subroutine, public topology_set_atm_mass(topology, subsys_section)
Use info from periodic table and set atm_mass.
recursive subroutine, public tag_molecule(icheck, bond_list, i, my_mol)
gives back a mapping of molecules.. icheck needs to be initialized with -1
subroutine, public check_subsys_element(element_in, atom_name_in, element_out, subsys_section, use_mm_map_first)
Check and returns the ELEMENT label.
Control for reading in different topologies and coordinates.
All kind of helpful little routines.