85#include "./base/base_uses.f90"
89 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'force_fields_all'
92 LOGICAL,
PARAMETER :: debug_this_module = .false.
133 INTEGER,
INTENT(IN) :: iw
135 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_bond'
137 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
139 INTEGER :: atm_a, atm_b, counter, first, handle2, &
140 i, j, k, last, natom, nbond
141 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
142 INTEGER,
POINTER :: map_bond_kind(:)
146 TYPE(
bond_type),
DIMENSION(:),
POINTER :: bond_list
150 CALL timeset(routinen, handle2)
153 WRITE (unit=iw, fmt=
"(/,T2,A)") &
154 "FORCEFIELD| Checking for unique bond terms"
157 DO i = 1,
SIZE(molecule_kind_set)
158 molecule_kind => molecule_kind_set(i)
160 molecule_list=molecule_list, &
162 nbond=nbond, bond_list=bond_list)
163 molecule => molecule_set(molecule_list(1))
164 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
166 ALLOCATE (map_bond_kind(nbond))
175 atm_a = bond_list(j)%a
176 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
179 atm_b = bond_list(j)%b
180 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
185 atm_a = bond_list(k)%a
186 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
189 atm_b = bond_list(k)%b
190 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
193 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
194 ((name_atm_b) == (name_atm_b2))) .OR. &
195 (((name_atm_a) == (name_atm_b2)) .AND. &
196 ((name_atm_b) == (name_atm_a2))))
THEN
198 map_bond_kind(j) = map_bond_kind(k)
202 IF (.NOT. found)
THEN
203 counter = counter + 1
204 map_bond_kind(j) = counter
208 NULLIFY (bond_kind_set)
211 bond_list(j)%bond_kind => bond_kind_set(map_bond_kind(j))
214 bond_kind_set=bond_kind_set, bond_list=bond_list)
215 DEALLOCATE (map_bond_kind)
218 CALL timestop(handle2)
236 INTEGER,
INTENT(IN) :: iw
238 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_bend'
240 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
241 name_atm_b2, name_atm_c, name_atm_c2
242 INTEGER :: atm_a, atm_b, atm_c, counter, first, &
243 handle2, i, j, k, last, natom, nbend
244 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
245 INTEGER,
POINTER :: map_bend_kind(:)
249 TYPE(
bend_type),
DIMENSION(:),
POINTER :: bend_list
253 CALL timeset(routinen, handle2)
256 WRITE (unit=iw, fmt=
"(/,T2,A)") &
257 "FORCEFIELD| Checking for unique bend terms"
260 DO i = 1,
SIZE(molecule_kind_set)
261 molecule_kind => molecule_kind_set(i)
263 molecule_list=molecule_list, &
265 nbend=nbend, bend_list=bend_list)
266 molecule => molecule_set(molecule_list(1))
267 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
269 ALLOCATE (map_bend_kind(nbend))
278 atm_a = bend_list(j)%a
279 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
282 atm_b = bend_list(j)%b
283 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
286 atm_c = bend_list(j)%c
287 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
292 atm_a = bend_list(k)%a
293 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
296 atm_b = bend_list(k)%b
297 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
300 atm_c = bend_list(k)%c
301 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
304 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
305 ((name_atm_b) == (name_atm_b2)) .AND. &
306 ((name_atm_c) == (name_atm_c2))) .OR. &
307 (((name_atm_a) == (name_atm_c2)) .AND. &
308 ((name_atm_b) == (name_atm_b2)) .AND. &
309 ((name_atm_c) == (name_atm_a2))))
THEN
311 map_bend_kind(j) = map_bend_kind(k)
315 IF (.NOT. found)
THEN
316 counter = counter + 1
317 map_bend_kind(j) = counter
321 NULLIFY (bend_kind_set)
324 bend_list(j)%bend_kind => bend_kind_set(map_bend_kind(j))
327 bend_kind_set=bend_kind_set, bend_list=bend_list)
328 DEALLOCATE (map_bend_kind)
332 CALL timestop(handle2)
348 INTEGER,
INTENT(IN) :: iw
350 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_ub'
352 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
353 name_atm_b2, name_atm_c, name_atm_c2
354 INTEGER :: atm_a, atm_b, atm_c, counter, first, &
355 handle2, i, j, k, last, natom, nub
356 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
357 INTEGER,
POINTER :: map_ub_kind(:)
362 TYPE(
ub_kind_type),
DIMENSION(:),
POINTER :: ub_kind_set
363 TYPE(
ub_type),
DIMENSION(:),
POINTER :: ub_list
365 CALL timeset(routinen, handle2)
368 WRITE (unit=iw, fmt=
"(/,T2,A)") &
369 "FORCEFIELD| Checking for unique Urey-Bradley terms"
372 DO i = 1,
SIZE(molecule_kind_set)
373 molecule_kind => molecule_kind_set(i)
375 molecule_list=molecule_list, &
377 nub=nub, ub_list=ub_list)
378 molecule => molecule_set(molecule_list(1))
379 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
381 ALLOCATE (map_ub_kind(nub))
385 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
389 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
393 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
399 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
403 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
407 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
410 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
411 ((name_atm_b) == (name_atm_b2)) .AND. &
412 ((name_atm_c) == (name_atm_c2))) .OR. &
413 (((name_atm_a) == (name_atm_c2)) .AND. &
414 ((name_atm_b) == (name_atm_b2)) .AND. &
415 ((name_atm_c) == (name_atm_a2))))
THEN
417 map_ub_kind(j) = map_ub_kind(k)
421 IF (.NOT. found)
THEN
422 counter = counter + 1
423 map_ub_kind(j) = counter
428 ub_list(j)%ub_kind => ub_kind_set(map_ub_kind(j))
431 ub_kind_set=ub_kind_set, ub_list=ub_list)
432 DEALLOCATE (map_ub_kind)
435 CALL timestop(handle2)
453 INTEGER,
INTENT(IN) :: iw
455 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_tors'
457 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
458 name_atm_b2, name_atm_c, name_atm_c2, &
459 name_atm_d, name_atm_d2
460 INTEGER :: atm_a, atm_b, atm_c, atm_d, counter, &
461 first, handle2, i, j, k, last, natom, &
463 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
464 INTEGER,
POINTER :: map_torsion_kind(:)
465 LOGICAL :: chk_reverse, found
470 TYPE(
torsion_type),
DIMENSION(:),
POINTER :: torsion_list
472 CALL timeset(routinen, handle2)
475 WRITE (unit=iw, fmt=
"(/,T2,A)") &
476 "FORCEFIELD| Checking for unique torsion terms"
483 DO i = 1,
SIZE(molecule_kind_set)
484 molecule_kind => molecule_kind_set(i)
486 molecule_list=molecule_list, &
488 ntorsion=ntorsion, torsion_list=torsion_list)
489 molecule => molecule_set(molecule_list(1))
490 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
491 IF (ntorsion > 0)
THEN
492 ALLOCATE (map_torsion_kind(ntorsion))
496 map_torsion_kind(j) = j
501 atm_a = torsion_list(j)%a
502 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
505 atm_b = torsion_list(j)%b
506 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
509 atm_c = torsion_list(j)%c
510 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
513 atm_d = torsion_list(j)%d
514 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
519 atm_a = torsion_list(k)%a
520 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
523 atm_b = torsion_list(k)%b
524 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
527 atm_c = torsion_list(k)%c
528 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
531 atm_d = torsion_list(k)%d
532 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
535 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
536 ((name_atm_b) == (name_atm_b2)) .AND. &
537 ((name_atm_c) == (name_atm_c2)) .AND. &
538 ((name_atm_d) == (name_atm_d2))) .OR. &
540 ((name_atm_a) == (name_atm_d2)) .AND. &
541 ((name_atm_b) == (name_atm_c2)) .AND. &
542 ((name_atm_c) == (name_atm_b2)) .AND. &
543 ((name_atm_d) == (name_atm_a2))))
THEN
545 map_torsion_kind(j) = map_torsion_kind(k)
549 IF (.NOT. found)
THEN
550 counter = counter + 1
551 map_torsion_kind(j) = counter
555 NULLIFY (torsion_kind_set)
558 torsion_list(j)%torsion_kind => torsion_kind_set(map_torsion_kind(j))
561 torsion_kind_set=torsion_kind_set, torsion_list=torsion_list)
562 DEALLOCATE (map_torsion_kind)
566 CALL timestop(handle2)
584 INTEGER,
INTENT(IN) :: iw
586 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_impr'
588 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
589 name_atm_b2, name_atm_c, name_atm_c2, &
590 name_atm_d, name_atm_d2
591 INTEGER :: atm_a, atm_b, atm_c, atm_d, counter, &
592 first, handle2, i, j, k, last, natom, &
594 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
595 INTEGER,
POINTER :: map_impr_kind(:)
599 TYPE(
impr_type),
DIMENSION(:),
POINTER :: impr_list
603 CALL timeset(routinen, handle2)
606 WRITE (unit=iw, fmt=
"(/,T2,A)") &
607 "FORCEFIELD| Checking for unique improper terms"
610 DO i = 1,
SIZE(molecule_kind_set)
611 molecule_kind => molecule_kind_set(i)
613 molecule_list=molecule_list, &
615 nimpr=nimpr, impr_list=impr_list)
616 molecule => molecule_set(molecule_list(1))
618 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
621 ALLOCATE (map_impr_kind(nimpr))
630 atm_a = impr_list(j)%a
631 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
634 atm_b = impr_list(j)%b
635 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
638 atm_c = impr_list(j)%c
639 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
642 atm_d = impr_list(j)%d
643 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
648 atm_a = impr_list(k)%a
649 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
652 atm_b = impr_list(k)%b
653 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
656 atm_c = impr_list(k)%c
657 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
660 atm_d = impr_list(k)%d
661 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
664 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
665 ((name_atm_b) == (name_atm_b2)) .AND. &
666 ((name_atm_c) == (name_atm_c2)) .AND. &
667 ((name_atm_d) == (name_atm_d2))) .OR. &
668 (((name_atm_a) == (name_atm_a2)) .AND. &
669 ((name_atm_b) == (name_atm_b2)) .AND. &
670 ((name_atm_c) == (name_atm_d2)) .AND. &
671 ((name_atm_d) == (name_atm_c2))))
THEN
673 map_impr_kind(j) = map_impr_kind(k)
677 IF (.NOT. found)
THEN
678 counter = counter + 1
679 map_impr_kind(j) = counter
683 NULLIFY (impr_kind_set)
686 impr_list(j)%impr_kind => impr_kind_set(map_impr_kind(j))
689 impr_kind_set=impr_kind_set, impr_list=impr_list)
690 DEALLOCATE (map_impr_kind)
693 CALL timestop(handle2)
713 INTEGER,
INTENT(IN) :: iw
715 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_opbend'
717 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
718 name_atm_b2, name_atm_c, name_atm_c2, &
719 name_atm_d, name_atm_d2
720 INTEGER :: atm_a, atm_b, atm_c, atm_d, counter, &
721 first, handle2, i, j, k, last, natom, &
723 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
724 INTEGER,
POINTER :: map_opbend_kind(:)
730 TYPE(
opbend_type),
DIMENSION(:),
POINTER :: opbend_list
732 CALL timeset(routinen, handle2)
735 WRITE (unit=iw, fmt=
"(/,T2,A)") &
736 "FORCEFIELD| Checking for unique out-of-plane bend terms"
739 DO i = 1,
SIZE(molecule_kind_set)
740 molecule_kind => molecule_kind_set(i)
742 molecule_list=molecule_list, &
744 nopbend=nopbend, opbend_list=opbend_list)
745 molecule => molecule_set(molecule_list(1))
746 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
747 IF (nopbend > 0)
THEN
748 ALLOCATE (map_opbend_kind(nopbend))
752 map_opbend_kind(j) = j
757 atm_a = opbend_list(j)%a
758 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
761 atm_b = opbend_list(j)%b
762 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
765 atm_c = opbend_list(j)%c
766 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
769 atm_d = opbend_list(j)%d
770 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
775 atm_a = opbend_list(k)%a
776 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
779 atm_b = opbend_list(k)%b
780 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
783 atm_c = opbend_list(k)%c
784 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
787 atm_d = opbend_list(k)%d
788 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
791 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
792 ((name_atm_b) == (name_atm_b2)) .AND. &
793 ((name_atm_c) == (name_atm_c2)) .AND. &
794 ((name_atm_d) == (name_atm_d2))) .OR. &
795 (((name_atm_a) == (name_atm_a2)) .AND. &
796 ((name_atm_b) == (name_atm_c2)) .AND. &
797 ((name_atm_c) == (name_atm_b2)) .AND. &
798 ((name_atm_d) == (name_atm_d2))))
THEN
800 map_opbend_kind(j) = map_opbend_kind(k)
804 IF (.NOT. found)
THEN
805 counter = counter + 1
806 map_opbend_kind(j) = counter
810 NULLIFY (opbend_kind_set)
813 opbend_list(j)%opbend_kind => opbend_kind_set(map_opbend_kind(j))
816 opbend_kind_set=opbend_kind_set, opbend_list=opbend_list)
817 DEALLOCATE (map_opbend_kind)
820 CALL timestop(handle2)
838 chm_info, inp_info, gro_info, amb_info, iw)
844 CHARACTER(LEN=default_string_length), &
845 DIMENSION(:),
POINTER :: ainfo
850 INTEGER,
INTENT(IN) :: iw
852 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_bond'
854 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_b
855 INTEGER :: atm_a, atm_b, first, handle2, i, itype, &
856 j, k, last, natom, nbond
857 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
858 LOGICAL :: found, only_qm
860 TYPE(
bond_type),
DIMENSION(:),
POINTER :: bond_list
864 CALL timeset(routinen, handle2)
867 WRITE (unit=iw, fmt=
"(/,T2,A)") &
868 "FORCEFIELD| Checking for bond terms"
871 DO i = 1,
SIZE(molecule_kind_set)
872 molecule_kind => molecule_kind_set(i)
874 molecule_list=molecule_list, &
876 nbond=nbond, bond_list=bond_list)
877 molecule => molecule_set(molecule_list(1))
878 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
880 atm_a = bond_list(j)%a
881 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
884 atm_b = bond_list(j)%b
885 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
894 IF (
ASSOCIATED(gro_info%bond_k))
THEN
895 k =
SIZE(gro_info%bond_k)
896 itype = bond_list(j)%itype
898 bond_list(j)%bond_kind%k(1) = gro_info%bond_k(itype)
899 bond_list(j)%bond_kind%r0 = gro_info%bond_r0(itype)
902 bond_list(j)%bond_kind%k(1) = gro_info%solvent_k(itype)
903 bond_list(j)%bond_kind%r0 = gro_info%solvent_r0(itype)
905 bond_list(j)%bond_kind%id_type = gro_info%ff_gromos_type
906 bond_list(j)%id_type = gro_info%ff_gromos_type
911 IF (
ASSOCIATED(chm_info%bond_a))
THEN
912 DO k = 1,
SIZE(chm_info%bond_a)
913 IF ((((chm_info%bond_a(k)) == (name_atm_a)) .AND. &
914 ((chm_info%bond_b(k)) == (name_atm_b))) .OR. &
915 (((chm_info%bond_a(k)) == (name_atm_b)) .AND. &
916 ((chm_info%bond_b(k)) == (name_atm_a))))
THEN
918 bond_list(j)%bond_kind%k(1) = chm_info%bond_k(k)
919 bond_list(j)%bond_kind%r0 = chm_info%bond_r0(k)
920 CALL issue_duplications(found,
"Bond", name_atm_a, name_atm_b)
928 IF (
ASSOCIATED(amb_info%bond_a))
THEN
929 DO k = 1,
SIZE(amb_info%bond_a)
930 IF ((((amb_info%bond_a(k)) == (name_atm_a)) .AND. &
931 ((amb_info%bond_b(k)) == (name_atm_b))) .OR. &
932 (((amb_info%bond_a(k)) == (name_atm_b)) .AND. &
933 ((amb_info%bond_b(k)) == (name_atm_a))))
THEN
935 bond_list(j)%bond_kind%k(1) = amb_info%bond_k(k)
936 bond_list(j)%bond_kind%r0 = amb_info%bond_r0(k)
937 CALL issue_duplications(found,
"Bond", name_atm_a, name_atm_b)
945 IF (
ASSOCIATED(inp_info%bond_a))
THEN
946 DO k = 1,
SIZE(inp_info%bond_a)
947 IF ((((inp_info%bond_a(k)) == (name_atm_a)) .AND. &
948 ((inp_info%bond_b(k)) == (name_atm_b))) .OR. &
949 (((inp_info%bond_a(k)) == (name_atm_b)) .AND. &
950 ((inp_info%bond_b(k)) == (name_atm_a))))
THEN
951 bond_list(j)%bond_kind%id_type = inp_info%bond_kind(k)
952 bond_list(j)%bond_kind%k(:) = inp_info%bond_k(:, k)
953 bond_list(j)%bond_kind%r0 = inp_info%bond_r0(k)
954 bond_list(j)%bond_kind%cs = inp_info%bond_cs(k)
955 CALL issue_duplications(found,
"Bond", name_atm_a, name_atm_b)
962 IF (.NOT. found)
CALL store_ff_missing_par(atm1=trim(name_atm_a), &
963 atm2=trim(name_atm_b), &
979 CALL timestop(handle2)
997 chm_info, inp_info, gro_info, amb_info, iw)
1003 CHARACTER(LEN=default_string_length), &
1004 DIMENSION(:),
POINTER :: ainfo
1009 INTEGER,
INTENT(IN) :: iw
1011 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_bend'
1013 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_b, name_atm_c
1014 INTEGER :: atm_a, atm_b, atm_c, first, handle2, i, &
1015 itype, j, k, l, last, natom, nbend
1016 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
1017 LOGICAL :: found, only_qm
1019 TYPE(
bend_type),
DIMENSION(:),
POINTER :: bend_list
1023 CALL timeset(routinen, handle2)
1026 WRITE (unit=iw, fmt=
"(/,T2,A)") &
1027 "FORCEFIELD| Checking for bend terms"
1030 DO i = 1,
SIZE(molecule_kind_set)
1031 molecule_kind => molecule_kind_set(i)
1033 molecule_list=molecule_list, &
1035 nbend=nbend, bend_list=bend_list)
1036 molecule => molecule_set(molecule_list(1))
1037 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
1039 atm_a = bend_list(j)%a
1040 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
1043 atm_b = bend_list(j)%b
1044 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
1047 atm_c = bend_list(j)%c
1048 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
1058 IF (
ASSOCIATED(gro_info%bend_k))
THEN
1059 k =
SIZE(gro_info%bend_k)
1060 itype = bend_list(j)%itype
1062 bend_list(j)%bend_kind%k = gro_info%bend_k(itype)
1063 bend_list(j)%bend_kind%theta0 = gro_info%bend_theta0(itype)
1065 bend_list(j)%bend_kind%k = gro_info%bend_k(itype/k)
1066 bend_list(j)%bend_kind%theta0 = gro_info%bend_theta0(itype/k)
1068 bend_list(j)%bend_kind%id_type = gro_info%ff_gromos_type
1069 bend_list(j)%id_type = gro_info%ff_gromos_type
1074 IF (
ASSOCIATED(chm_info%bend_a))
THEN
1075 DO k = 1,
SIZE(chm_info%bend_a)
1076 IF ((((chm_info%bend_a(k)) == (name_atm_a)) .AND. &
1077 ((chm_info%bend_b(k)) == (name_atm_b)) .AND. &
1078 ((chm_info%bend_c(k)) == (name_atm_c))) .OR. &
1079 (((chm_info%bend_a(k)) == (name_atm_c)) .AND. &
1080 ((chm_info%bend_b(k)) == (name_atm_b)) .AND. &
1081 ((chm_info%bend_c(k)) == (name_atm_a))))
THEN
1083 bend_list(j)%bend_kind%k = chm_info%bend_k(k)
1084 bend_list(j)%bend_kind%theta0 = chm_info%bend_theta0(k)
1085 CALL issue_duplications(found,
"Bend", name_atm_a, name_atm_b, &
1094 IF (
ASSOCIATED(amb_info%bend_a))
THEN
1095 DO k = 1,
SIZE(amb_info%bend_a)
1096 IF ((((amb_info%bend_a(k)) == (name_atm_a)) .AND. &
1097 ((amb_info%bend_b(k)) == (name_atm_b)) .AND. &
1098 ((amb_info%bend_c(k)) == (name_atm_c))) .OR. &
1099 (((amb_info%bend_a(k)) == (name_atm_c)) .AND. &
1100 ((amb_info%bend_b(k)) == (name_atm_b)) .AND. &
1101 ((amb_info%bend_c(k)) == (name_atm_a))))
THEN
1103 bend_list(j)%bend_kind%k = amb_info%bend_k(k)
1104 bend_list(j)%bend_kind%theta0 = amb_info%bend_theta0(k)
1105 CALL issue_duplications(found,
"Bend", name_atm_a, name_atm_b, &
1114 IF (
ASSOCIATED(inp_info%bend_a))
THEN
1115 DO k = 1,
SIZE(inp_info%bend_a)
1116 IF ((((inp_info%bend_a(k)) == (name_atm_a)) .AND. &
1117 ((inp_info%bend_b(k)) == (name_atm_b)) .AND. &
1118 ((inp_info%bend_c(k)) == (name_atm_c))) .OR. &
1119 (((inp_info%bend_a(k)) == (name_atm_c)) .AND. &
1120 ((inp_info%bend_b(k)) == (name_atm_b)) .AND. &
1121 ((inp_info%bend_c(k)) == (name_atm_a))))
THEN
1122 bend_list(j)%bend_kind%id_type = inp_info%bend_kind(k)
1123 bend_list(j)%bend_kind%k = inp_info%bend_k(k)
1124 bend_list(j)%bend_kind%theta0 = inp_info%bend_theta0(k)
1125 bend_list(j)%bend_kind%cb = inp_info%bend_cb(k)
1126 bend_list(j)%bend_kind%r012 = inp_info%bend_r012(k)
1127 bend_list(j)%bend_kind%r032 = inp_info%bend_r032(k)
1128 bend_list(j)%bend_kind%kbs12 = inp_info%bend_kbs12(k)
1129 bend_list(j)%bend_kind%kbs32 = inp_info%bend_kbs32(k)
1130 bend_list(j)%bend_kind%kss = inp_info%bend_kss(k)
1131 bend_list(j)%bend_kind%legendre%order = inp_info%bend_legendre(k)%order
1132 IF (bend_list(j)%bend_kind%legendre%order /= 0)
THEN
1133 IF (
ASSOCIATED(bend_list(j)%bend_kind%legendre%coeffs))
THEN
1134 DEALLOCATE (bend_list(j)%bend_kind%legendre%coeffs)
1136 ALLOCATE (bend_list(j)%bend_kind%legendre%coeffs(bend_list(j)%bend_kind%legendre%order))
1137 DO l = 1, bend_list(j)%bend_kind%legendre%order
1138 bend_list(j)%bend_kind%legendre%coeffs(l) = inp_info%bend_legendre(k)%coeffs(l)
1141 CALL issue_duplications(found,
"Bend", name_atm_a, name_atm_b, &
1149 IF (.NOT. found)
CALL store_ff_missing_par(atm1=trim(name_atm_a), &
1150 atm2=trim(name_atm_b), &
1151 atm3=trim(name_atm_c), &
1153 type_name=
"Angle", &
1162 bend_list=bend_list)
1164 CALL timestop(handle2)
1179 Ainfo, chm_info, inp_info, iw)
1184 CHARACTER(LEN=default_string_length), &
1185 DIMENSION(:),
POINTER :: ainfo
1190 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_ub'
1192 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_b, name_atm_c
1193 INTEGER :: atm_a, atm_b, atm_c, first, handle2, i, &
1194 j, k, last, natom, nub
1195 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
1196 LOGICAL :: found, only_qm
1200 TYPE(
ub_type),
DIMENSION(:),
POINTER :: ub_list
1202 CALL timeset(routinen, handle2)
1205 WRITE (unit=iw, fmt=
"(/,T2,A)") &
1206 "FORCEFIELD| Checking for Urey-Bradley (UB) terms"
1209 DO i = 1,
SIZE(molecule_kind_set)
1210 molecule_kind => molecule_kind_set(i)
1212 molecule_list=molecule_list, &
1214 nub=nub, ub_list=ub_list)
1215 molecule => molecule_set(molecule_list(1))
1216 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
1218 atm_a = ub_list(j)%a
1219 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
1222 atm_b = ub_list(j)%b
1223 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
1226 atm_c = ub_list(j)%c
1227 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
1240 IF (
ASSOCIATED(chm_info%ub_a))
THEN
1241 DO k = 1,
SIZE(chm_info%ub_a)
1242 IF ((((chm_info%ub_a(k)) == (name_atm_a)) .AND. &
1243 ((chm_info%ub_b(k)) == (name_atm_b)) .AND. &
1244 ((chm_info%ub_c(k)) == (name_atm_c))) .OR. &
1245 (((chm_info%ub_a(k)) == (name_atm_c)) .AND. &
1246 ((chm_info%ub_b(k)) == (name_atm_b)) .AND. &
1247 ((chm_info%ub_c(k)) == (name_atm_a))))
THEN
1249 ub_list(j)%ub_kind%k(1) = chm_info%ub_k(k)
1250 ub_list(j)%ub_kind%r0 = chm_info%ub_r0(k)
1252 WRITE (unit=iw, fmt=
"(T2,A)") &
1253 "FORCEFIELD| Found Urey-Bradley term (CHARMM) for the atomic kinds "// &
1254 trim(name_atm_a)//
", "//trim(name_atm_b)//
" and "//trim(name_atm_c)
1256 CALL issue_duplications(found,
"Urey-Bradley", name_atm_a, &
1257 name_atm_b, name_atm_c)
1268 IF (
ASSOCIATED(inp_info%ub_a))
THEN
1269 DO k = 1,
SIZE(inp_info%ub_a)
1270 IF ((((inp_info%ub_a(k)) == (name_atm_a)) .AND. &
1271 ((inp_info%ub_b(k)) == (name_atm_b)) .AND. &
1272 ((inp_info%ub_c(k)) == (name_atm_c))) .OR. &
1273 (((inp_info%ub_a(k)) == (name_atm_c)) .AND. &
1274 ((inp_info%ub_b(k)) == (name_atm_b)) .AND. &
1275 ((inp_info%ub_c(k)) == (name_atm_a))))
THEN
1276 ub_list(j)%ub_kind%id_type = inp_info%ub_kind(k)
1277 ub_list(j)%ub_kind%k(:) = inp_info%ub_k(:, k)
1278 ub_list(j)%ub_kind%r0 = inp_info%ub_r0(k)
1280 WRITE (unit=iw, fmt=
"(T2,A)") &
1281 "FORCEFIELD| Found Urey-Bradley term (input) for the atomic kinds "// &
1282 trim(name_atm_a)//
", "//trim(name_atm_b)//
" and "//trim(name_atm_c)
1284 CALL issue_duplications(found,
"Urey-Bradley", name_atm_a, &
1285 name_atm_b, name_atm_c)
1292 IF (.NOT. found)
THEN
1293 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
1294 atm2=trim(name_atm_b), &
1295 atm3=trim(name_atm_c), &
1296 type_name=
"Urey-Bradley", &
1300 ub_list(j)%ub_kind%k = 0.0_dp
1301 ub_list(j)%ub_kind%r0 = 0.0_dp
1316 CALL timestop(handle2)
1333 Ainfo, chm_info, inp_info, gro_info, amb_info, iw)
1338 CHARACTER(LEN=default_string_length), &
1339 DIMENSION(:),
POINTER :: ainfo
1344 INTEGER,
INTENT(IN) :: iw
1346 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_tors'
1348 CHARACTER(LEN=default_string_length) :: ldum, molecule_name, name_atm_a, &
1349 name_atm_b, name_atm_c, name_atm_d
1350 INTEGER :: atm_a, atm_b, atm_c, atm_d, first, &
1351 handle2, i, imul, itype, j, k, k_end, &
1352 k_start, last, natom, ntorsion, &
1354 INTEGER,
DIMENSION(4) :: glob_atm_id
1355 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
1356 LOGICAL :: found, only_qm
1360 TYPE(
torsion_type),
DIMENSION(:),
POINTER :: torsion_list
1362 CALL timeset(routinen, handle2)
1365 WRITE (unit=iw, fmt=
"(/,T2,A)") &
1366 "FORCEFIELD| Checking for torsion terms"
1369 DO i = 1,
SIZE(molecule_kind_set)
1370 molecule_kind => molecule_kind_set(i)
1372 molecule_list=molecule_list, &
1373 name=molecule_name, &
1375 ntorsion=ntorsion, &
1376 torsion_list=torsion_list)
1377 molecule => molecule_set(molecule_list(1))
1382 IF (torsion_list(j)%torsion_kind%id_type ==
do_ff_undef)
THEN
1383 atm_a = torsion_list(j)%a
1384 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
1387 atm_b = torsion_list(j)%b
1388 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
1391 atm_c = torsion_list(j)%c
1392 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
1395 atm_d = torsion_list(j)%d
1396 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
1407 IF (
ASSOCIATED(gro_info%torsion_k))
THEN
1408 k =
SIZE(gro_info%torsion_k)
1409 itype = torsion_list(j)%itype
1411 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, 1)
1412 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, 1)
1413 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, 1)
1414 torsion_list(j)%torsion_kind%nmul = 1
1415 torsion_list(j)%torsion_kind%m(1) = gro_info%torsion_m(itype)
1416 torsion_list(j)%torsion_kind%k(1) = gro_info%torsion_k(itype)
1417 torsion_list(j)%torsion_kind%phi0(1) = gro_info%torsion_phi0(itype)
1419 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, 1)
1420 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, 1)
1421 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, 1)
1422 torsion_list(j)%torsion_kind%nmul = 1
1423 torsion_list(j)%torsion_kind%m(1) = gro_info%torsion_m(itype/k)
1424 torsion_list(j)%torsion_kind%k(1) = gro_info%torsion_k(itype/k)
1425 torsion_list(j)%torsion_kind%phi0(1) = gro_info%torsion_phi0(itype/k)
1427 torsion_list(j)%torsion_kind%id_type = gro_info%ff_gromos_type
1428 torsion_list(j)%id_type = gro_info%ff_gromos_type
1430 imul = torsion_list(j)%torsion_kind%nmul
1434 IF (
ASSOCIATED(chm_info%torsion_a))
THEN
1435 DO k = 1,
SIZE(chm_info%torsion_a)
1436 IF ((((chm_info%torsion_a(k)) == (name_atm_a)) .AND. &
1437 ((chm_info%torsion_b(k)) == (name_atm_b)) .AND. &
1438 ((chm_info%torsion_c(k)) == (name_atm_c)) .AND. &
1439 ((chm_info%torsion_d(k)) == (name_atm_d))) .OR. &
1440 (((chm_info%torsion_a(k)) == (name_atm_d)) .AND. &
1441 ((chm_info%torsion_b(k)) == (name_atm_c)) .AND. &
1442 ((chm_info%torsion_c(k)) == (name_atm_b)) .AND. &
1443 ((chm_info%torsion_d(k)) == (name_atm_a))))
THEN
1444 imul = torsion_list(j)%torsion_kind%nmul + 1
1445 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
1446 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
1447 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
1449 torsion_list(j)%torsion_kind%k(imul) = chm_info%torsion_k(k)
1450 torsion_list(j)%torsion_kind%m(imul) = chm_info%torsion_m(k)
1451 torsion_list(j)%torsion_kind%phi0(imul) = chm_info%torsion_phi0(k)
1452 torsion_list(j)%torsion_kind%nmul = imul
1457 IF (.NOT. found)
THEN
1458 DO k = 1,
SIZE(chm_info%torsion_a)
1459 IF ((((chm_info%torsion_a(k)) == (
"X")) .AND. &
1460 ((chm_info%torsion_b(k)) == (name_atm_b)) .AND. &
1461 ((chm_info%torsion_c(k)) == (name_atm_c)) .AND. &
1462 ((chm_info%torsion_d(k)) == (
"X"))) .OR. &
1463 (((chm_info%torsion_a(k)) == (
"X")) .AND. &
1464 ((chm_info%torsion_b(k)) == (name_atm_c)) .AND. &
1465 ((chm_info%torsion_c(k)) == (name_atm_b)) .AND. &
1466 ((chm_info%torsion_d(k)) == (
"X"))))
THEN
1467 imul = torsion_list(j)%torsion_kind%nmul + 1
1468 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
1469 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
1470 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
1472 torsion_list(j)%torsion_kind%k(imul) = chm_info%torsion_k(k)
1473 torsion_list(j)%torsion_kind%m(imul) = chm_info%torsion_m(k)
1474 torsion_list(j)%torsion_kind%phi0(imul) = chm_info%torsion_phi0(k)
1475 torsion_list(j)%torsion_kind%nmul = imul
1485 IF (
ASSOCIATED(amb_info%torsion_a))
THEN
1487 glob_atm_id(1) = atm_a + first - 1
1488 glob_atm_id(2) = atm_b + first - 1
1489 glob_atm_id(3) = atm_c + first - 1
1490 glob_atm_id(4) = atm_d + first - 1
1495 k_start = bsearch_leftmost_2d(amb_info%raw_torsion_id, glob_atm_id(1))
1496 k_end = ubound(amb_info%raw_torsion_id, dim=2)
1499 IF (k_start /= 0)
THEN
1501 DO k = k_start, k_end
1502 IF (glob_atm_id(1) < amb_info%raw_torsion_id(1, k))
EXIT
1503 IF (any((glob_atm_id - amb_info%raw_torsion_id(1:4, k)) /= 0)) cycle
1505 raw_parm_id = amb_info%raw_torsion_id(5, k)
1506 imul = torsion_list(j)%torsion_kind%nmul + 1
1507 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
1508 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
1509 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
1510 torsion_list(j)%torsion_kind%id_type =
do_ff_amber
1511 torsion_list(j)%torsion_kind%k(imul) = amb_info%raw_torsion_k(raw_parm_id)
1512 torsion_list(j)%torsion_kind%m(imul) = nint(amb_info%raw_torsion_m(raw_parm_id))
1513 torsion_list(j)%torsion_kind%phi0(imul) = amb_info%raw_torsion_phi0(raw_parm_id)
1514 torsion_list(j)%torsion_kind%nmul = imul
1523 IF (
ASSOCIATED(inp_info%torsion_a))
THEN
1524 DO k = 1,
SIZE(inp_info%torsion_a)
1525 IF ((((inp_info%torsion_a(k)) == (name_atm_a)) .AND. &
1526 ((inp_info%torsion_b(k)) == (name_atm_b)) .AND. &
1527 ((inp_info%torsion_c(k)) == (name_atm_c)) .AND. &
1528 ((inp_info%torsion_d(k)) == (name_atm_d))) .OR. &
1529 (((inp_info%torsion_a(k)) == (name_atm_d)) .AND. &
1530 ((inp_info%torsion_b(k)) == (name_atm_c)) .AND. &
1531 ((inp_info%torsion_c(k)) == (name_atm_b)) .AND. &
1532 ((inp_info%torsion_d(k)) == (name_atm_a))))
THEN
1533 imul = torsion_list(j)%torsion_kind%nmul + 1
1534 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
1535 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
1536 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
1537 torsion_list(j)%torsion_kind%id_type = inp_info%torsion_kind(k)
1538 torsion_list(j)%torsion_kind%k(imul) = inp_info%torsion_k(k)
1539 torsion_list(j)%torsion_kind%m(imul) = inp_info%torsion_m(k)
1540 torsion_list(j)%torsion_kind%phi0(imul) = inp_info%torsion_phi0(k)
1541 torsion_list(j)%torsion_kind%nmul = imul
1551 WRITE (unit=iw, fmt=
"(T2,A)") &
1552 "FORCEFIELD| No torsion term found"
1553 ELSE IF (imul == 1)
THEN
1554 WRITE (unit=iw, fmt=
"(T2,A)") &
1555 "FORCEFIELD| Found torsion term for the atomic kinds "// &
1556 trim(name_atm_a)//
", "//trim(name_atm_b)// &
1557 ", "//trim(name_atm_c)// &
1558 " and "//trim(name_atm_d)
1560 WRITE (unit=iw, fmt=
"(T2,A)") &
1561 "FORCEFIELD| Found multiple ("//trim(ldum)// &
1562 ") torsion terms for the atomic kinds "// &
1563 trim(name_atm_a)//
", "//trim(name_atm_b)// &
1564 ", "//trim(name_atm_c)// &
1565 " and "//trim(name_atm_d)
1569 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
1570 atm2=trim(name_atm_b), &
1571 atm3=trim(name_atm_c), &
1572 atm4=trim(name_atm_d), &
1573 type_name=
"Torsion", &
1575 torsion_list(j)%torsion_kind%id_type =
do_ff_undef
1582 WRITE (unit=iw, fmt=
"(T2,A,I0,4(A,I0))") &
1583 "FORCEFIELD| Torsion ", j,
" for molecule kind "//trim(molecule_name)// &
1584 trim(name_atm_a)// &
1585 "-"//trim(name_atm_b)//
"-"//trim(name_atm_c)//
"-"// &
1586 trim(name_atm_d)//
" (", torsion_list(j)%a,
", ", &
1587 torsion_list(j)%b,
", ", torsion_list(j)%c,
", ", &
1590 torsion_list(j)%torsion_kind%id_type =
do_ff_undef
1599 torsion_list=torsion_list)
1603 CALL timestop(handle2)
1619 Ainfo, chm_info, inp_info, gro_info, iw)
1624 CHARACTER(LEN=default_string_length), &
1625 DIMENSION(:),
POINTER :: ainfo
1629 INTEGER,
INTENT(IN) :: iw
1631 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_impr'
1633 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_b, name_atm_c, &
1635 INTEGER :: atm_a, atm_b, atm_c, atm_d, first, &
1636 handle2, i, itype, j, k, last, natom, &
1638 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
1639 LOGICAL :: found, only_qm
1641 TYPE(
impr_type),
DIMENSION(:),
POINTER :: impr_list
1645 CALL timeset(routinen, handle2)
1648 WRITE (unit=iw, fmt=
"(/,T2,A)") &
1649 "FORCEFIELD| Checking for improper terms"
1652 DO i = 1,
SIZE(molecule_kind_set)
1654 molecule_kind => molecule_kind_set(i)
1656 molecule_list=molecule_list, &
1659 impr_list=impr_list)
1661 molecule => molecule_set(molecule_list(1))
1662 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
1665 atm_a = impr_list(j)%a
1666 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
1669 atm_b = impr_list(j)%b
1670 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
1673 atm_c = impr_list(j)%c
1674 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
1677 atm_d = impr_list(j)%d
1678 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
1689 IF (
ASSOCIATED(gro_info%impr_k))
THEN
1690 k =
SIZE(gro_info%impr_k)
1691 itype = impr_list(j)%itype
1693 impr_list(j)%impr_kind%k = gro_info%impr_k(itype)
1694 impr_list(j)%impr_kind%phi0 = gro_info%impr_phi0(itype)
1696 impr_list(j)%impr_kind%k = gro_info%impr_k(itype)
1697 impr_list(j)%impr_kind%phi0 = gro_info%impr_phi0(itype)
1700 impr_list(j)%impr_kind%id_type = gro_info%ff_gromos_type
1701 impr_list(j)%id_type = gro_info%ff_gromos_type
1705 IF (
ASSOCIATED(chm_info%impr_a))
THEN
1706 DO k = 1,
SIZE(chm_info%impr_a)
1707 IF ((((chm_info%impr_a(k)) == (name_atm_a)) .AND. &
1708 ((chm_info%impr_b(k)) == (name_atm_b)) .AND. &
1709 ((chm_info%impr_c(k)) == (name_atm_c)) .AND. &
1710 ((chm_info%impr_d(k)) == (name_atm_d))) .OR. &
1711 (((chm_info%impr_a(k)) == (name_atm_d)) .AND. &
1712 ((chm_info%impr_b(k)) == (name_atm_c)) .AND. &
1713 ((chm_info%impr_c(k)) == (name_atm_b)) .AND. &
1714 ((chm_info%impr_d(k)) == (name_atm_a))))
THEN
1716 impr_list(j)%impr_kind%k = chm_info%impr_k(k)
1717 impr_list(j)%impr_kind%phi0 = chm_info%impr_phi0(k)
1718 CALL issue_duplications(found,
"Impropers", name_atm_a, name_atm_b, &
1719 name_atm_c, name_atm_d)
1724 IF (.NOT. found)
THEN
1725 DO k = 1,
SIZE(chm_info%impr_a)
1726 IF ((((chm_info%impr_a(k)) == (name_atm_a)) .AND. &
1727 ((chm_info%impr_b(k)) == (
"X")) .AND. &
1728 ((chm_info%impr_c(k)) == (
"X")) .AND. &
1729 ((chm_info%impr_d(k)) == (name_atm_d))) .OR. &
1730 (((chm_info%impr_a(k)) == (name_atm_d)) .AND. &
1731 ((chm_info%impr_b(k)) == (
"X")) .AND. &
1732 ((chm_info%impr_c(k)) == (
"X")) .AND. &
1733 ((chm_info%impr_d(k)) == (name_atm_a))))
THEN
1735 impr_list(j)%impr_kind%k = chm_info%impr_k(k)
1736 impr_list(j)%impr_kind%phi0 = chm_info%impr_phi0(k)
1737 CALL issue_duplications(found,
"Impropers", name_atm_a, name_atm_b, &
1738 name_atm_c, name_atm_d)
1750 IF (
ASSOCIATED(inp_info%impr_a))
THEN
1751 DO k = 1,
SIZE(inp_info%impr_a)
1752 IF (((inp_info%impr_a(k)) == (name_atm_a)) .AND. &
1753 ((inp_info%impr_b(k)) == (name_atm_b)) .AND. &
1754 ((((inp_info%impr_c(k)) == (name_atm_c)) .AND. &
1755 ((inp_info%impr_d(k)) == (name_atm_d))) .OR. &
1756 (((inp_info%impr_c(k)) == (name_atm_d)) .AND. &
1757 ((inp_info%impr_d(k)) == (name_atm_c)))))
THEN
1758 impr_list(j)%impr_kind%id_type = inp_info%impr_kind(k)
1759 impr_list(j)%impr_kind%k = inp_info%impr_k(k)
1760 IF (((inp_info%impr_c(k)) == (name_atm_c)) .AND. &
1761 ((inp_info%impr_d(k)) == (name_atm_d)))
THEN
1762 impr_list(j)%impr_kind%phi0 = inp_info%impr_phi0(k)
1764 impr_list(j)%impr_kind%phi0 = -inp_info%impr_phi0(k)
1775 CALL issue_duplications(found,
"Impropers", name_atm_a, name_atm_b, &
1776 name_atm_c, name_atm_d)
1783 IF (.NOT. found)
THEN
1784 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
1785 atm2=trim(name_atm_b), &
1786 atm3=trim(name_atm_c), &
1787 atm4=trim(name_atm_d), &
1788 type_name=
"Improper", &
1790 impr_list(j)%impr_kind%k = 0.0_dp
1791 impr_list(j)%impr_kind%phi0 = 0.0_dp
1800 WRITE (unit=iw, fmt=
"(T2,A)") &
1801 "FORCEFIELD| Found improper term for "//trim(name_atm_a)// &
1802 "-"//trim(name_atm_b)//
"-"//trim(name_atm_c)//
"-"// &
1816 CALL timestop(handle2)
1838 CHARACTER(LEN=default_string_length), &
1839 DIMENSION(:),
POINTER :: ainfo
1841 INTEGER,
INTENT(IN) :: iw
1843 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_opbend'
1845 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_b, name_atm_c, &
1847 INTEGER :: atm_a, atm_b, atm_c, atm_d, first, &
1848 handle2, i, j, k, last, natom, nopbend
1849 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
1850 LOGICAL :: found, only_qm
1854 TYPE(
opbend_type),
DIMENSION(:),
POINTER :: opbend_list
1856 CALL timeset(routinen, handle2)
1859 WRITE (unit=iw, fmt=
"(/,T2,A)") &
1860 "FORCEFIELD| Checking for out-of-plane bend terms"
1863 DO i = 1,
SIZE(molecule_kind_set)
1864 molecule_kind => molecule_kind_set(i)
1866 molecule_list=molecule_list, &
1868 nopbend=nopbend, opbend_list=opbend_list)
1869 molecule => molecule_set(molecule_list(1))
1871 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
1873 atm_a = opbend_list(j)%a
1874 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
1877 atm_b = opbend_list(j)%b
1878 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
1881 atm_c = opbend_list(j)%c
1882 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
1885 atm_d = opbend_list(j)%d
1886 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
1897 IF (
ASSOCIATED(inp_info%opbend_a))
THEN
1898 DO k = 1,
SIZE(inp_info%opbend_a)
1899 IF (((inp_info%opbend_a(k)) == (name_atm_a)) .AND. &
1900 ((inp_info%opbend_d(k)) == (name_atm_d)) .AND. &
1901 ((((inp_info%opbend_c(k)) == (name_atm_c)) .AND. &
1902 ((inp_info%opbend_b(k)) == (name_atm_b))) .OR. &
1903 (((inp_info%opbend_c(k)) == (name_atm_b)) .AND. &
1904 ((inp_info%opbend_b(k)) == (name_atm_c)))))
THEN
1905 opbend_list(j)%opbend_kind%id_type = inp_info%opbend_kind(k)
1906 opbend_list(j)%opbend_kind%k = inp_info%opbend_k(k)
1907 IF (((inp_info%opbend_c(k)) == (name_atm_c)) .AND. &
1908 ((inp_info%opbend_b(k)) == (name_atm_b)))
THEN
1909 opbend_list(j)%opbend_kind%phi0 = inp_info%opbend_phi0(k)
1911 opbend_list(j)%opbend_kind%phi0 = -inp_info%opbend_phi0(k)
1921 CALL issue_duplications(found,
"Out of plane bend", name_atm_a, name_atm_b, &
1922 name_atm_c, name_atm_d)
1929 IF (.NOT. found)
THEN
1930 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
1931 atm2=trim(name_atm_b), &
1932 atm3=trim(name_atm_c), &
1933 atm4=trim(name_atm_d), &
1934 type_name=
"Out of plane bend", &
1936 opbend_list(j)%opbend_kind%k = 0.0_dp
1937 opbend_list(j)%opbend_kind%phi0 = 0.0_dp
1955 CALL timestop(handle2)
1972 my_qmmm, qmmm_env, inp_info, iw4)
1974 REAL(kind=
dp),
DIMENSION(:),
POINTER :: charges
1980 INTEGER,
INTENT(IN) :: iw4
1982 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_charges'
1984 CHARACTER(LEN=default_string_length) :: atmname
1985 INTEGER :: handle, iatom, ilink, j, nval
1986 LOGICAL :: found_p, is_link_atom, is_ok, &
1987 only_manybody, only_qm
1988 REAL(kind=
dp) :: charge, charge_tot, rval, scale_factor
1994 CALL timeset(routinen, handle)
2000 IF (
ASSOCIATED(inp_info%shell_list))
THEN
2001 cpabort(
"Array of charges is not implemented for the core-shell model")
2005 cpassert(.NOT. (
ASSOCIATED(charges)))
2006 ALLOCATE (charges(
SIZE(particle_set)))
2010 cpassert(nval ==
SIZE(charges))
2017 charges(iatom) = rval
2020 atomic_kind => particle_set(iatom)%atomic_kind
2022 fist_potential=fist_potential, &
2028 IF (charge /= -huge(0.0_dp)) &
2029 CALL cp_warn(__location__, &
2030 "The charge for atom index ("//
cp_to_string(iatom)//
") and atom name ("// &
2031 trim(atmname)//
") was already defined. The charge associated to this kind"// &
2032 " will be set to an uninitialized value and only the atom specific charge will be used! ")
2033 charge = -huge(0.0_dp)
2036 IF (
ASSOCIATED(inp_info%nonbonded))
THEN
2037 IF (
ASSOCIATED(inp_info%nonbonded%pot))
THEN
2039 only_manybody = .true.
2041 DO j = 1,
SIZE(inp_info%nonbonded%pot)
2042 IF (atmname == inp_info%nonbonded%pot(j)%pot%at1 .OR. &
2043 atmname == inp_info%nonbonded%pot(j)%pot%at2)
THEN
2044 SELECT CASE (inp_info%nonbonded%pot(j)%pot%type(1))
2049 only_manybody = .false.
2055 IF (only_manybody .AND. found_p)
THEN
2056 charges(iatom) = 0.0_dp
2062 IF (only_qm .AND. my_qmmm)
THEN
2064 scale_factor = 0.0_dp
2065 IF (is_link_atom)
THEN
2067 DO ilink = 1,
SIZE(qmmm_env%mm_link_atoms)
2068 IF (iatom == qmmm_env%mm_link_atoms(ilink))
EXIT
2070 cpassert(ilink <=
SIZE(qmmm_env%mm_link_atoms))
2071 scale_factor = qmmm_env%fist_scale_charge_link(ilink)
2073 charges(iatom) = charges(iatom)*scale_factor
2079 charge_tot = sum(charges)
2083 WRITE (unit=iw4, fmt=
"(/,T2,A,T61,F20.10)") &
2084 "FORCEFIELD| Total charge of the classical system: ", charge_tot
2087 CALL timestop(handle)
2104 Ainfo, my_qmmm, inp_info)
2108 LOGICAL,
INTENT(INOUT) :: fatal
2109 INTEGER,
INTENT(IN) :: iw, iw4
2110 CHARACTER(LEN=default_string_length), &
2111 DIMENSION(:),
POINTER :: ainfo
2112 LOGICAL,
INTENT(IN) :: my_qmmm
2115 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_charge'
2117 CHARACTER(LEN=default_string_length) :: atmname
2118 INTEGER :: handle, i, ilink, j
2119 INTEGER,
DIMENSION(:),
POINTER :: my_atom_list
2120 LOGICAL :: found, found_p, is_link_atom, is_shell, &
2121 only_manybody, only_qm
2122 REAL(kind=
dp) :: charge, charge_tot, cs_charge, &
2127 CALL timeset(routinen, handle)
2131 DO i = 1,
SIZE(atomic_kind_set)
2132 atomic_kind => atomic_kind_set(i)
2134 fist_potential=fist_potential, &
2135 atom_list=my_atom_list, &
2143 IF (charge /= -huge(0.0_dp)) found = .true.
2146 IF (
ASSOCIATED(inp_info%charge_atm))
THEN
2147 IF (iw > 0)
WRITE (unit=iw, fmt=
"(A)")
""
2148 DO j = 1,
SIZE(inp_info%charge_atm)
2149 IF (debug_this_module)
THEN
2151 WRITE (unit=iw, fmt=
"(T2,A)") &
2152 "Checking charges for the atomic kinds "// &
2153 trim(inp_info%charge_atm(j))//
" and "//trim(atmname)
2156 IF ((inp_info%charge_atm(j)) == atmname)
THEN
2157 charge = inp_info%charge(j)
2158 CALL issue_duplications(found,
"Charge", atmname)
2166 IF (
ASSOCIATED(inp_info%shell_list))
THEN
2167 DO j = 1,
SIZE(inp_info%shell_list)
2168 IF ((inp_info%shell_list(j)%atm_name) == atmname)
THEN
2170 cs_charge = inp_info%shell_list(j)%shell%charge_core + &
2171 inp_info%shell_list(j)%shell%charge_shell
2175 CALL cp_warn(__location__, &
2176 "CORE-SHELL model defined for KIND ("//trim(atmname)//
")"// &
2177 " ignoring charge definition! ")
2185 IF (
ASSOCIATED(inp_info%nonbonded))
THEN
2186 IF (
ASSOCIATED(inp_info%nonbonded%pot))
THEN
2188 only_manybody = .true.
2190 DO j = 1,
SIZE(inp_info%nonbonded%pot)
2191 IF (atmname == inp_info%nonbonded%pot(j)%pot%at1 .OR. &
2192 atmname == inp_info%nonbonded%pot(j)%pot%at2)
THEN
2193 SELECT CASE (inp_info%nonbonded%pot(j)%pot%type(1))
2199 only_manybody = .false.
2205 IF (only_manybody .AND. found_p)
THEN
2211 IF (.NOT. found)
THEN
2215 CALL store_ff_missing_par(atm1=trim(atmname), &
2217 type_name=
"Charge", &
2223 IF (only_qm .AND. my_qmmm)
THEN
2225 scale_factor = 0.0_dp
2226 IF (is_link_atom)
THEN
2230 DO ilink = 1,
SIZE(qmmm_env%mm_link_atoms)
2231 IF (any(my_atom_list == qmmm_env%mm_link_atoms(ilink)))
EXIT
2233 cpassert(ilink <=
SIZE(qmmm_env%mm_link_atoms))
2234 scale_factor = qmmm_env%fist_scale_charge_link(ilink)
2236 charge = charge*scale_factor
2244 charge_tot = charge_tot + atomic_kind%natom*cs_charge
2246 charge_tot = charge_tot + atomic_kind%natom*charge
2253 WRITE (unit=iw4, fmt=
"(/,T2,A,T61,F20.10)") &
2254 "FORCEFIELD| Total charge of the classical system: ", charge_tot
2257 CALL timestop(handle)
2271 INTEGER,
INTENT(IN) :: iw
2274 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_radius'
2276 CHARACTER(LEN=default_string_length) :: inp_kind_name, kind_name
2277 INTEGER :: handle, i, i_rep, n_rep
2279 REAL(kind=
dp) :: mm_radius
2284 CALL timeset(routinen, handle)
2289 DO i = 1,
SIZE(atomic_kind_set)
2290 atomic_kind => atomic_kind_set(i)
2292 fist_potential=fist_potential, name=kind_name)
2299 IF (iw > 0)
WRITE (unit=iw, fmt=
"(A)")
""
2303 c_val=inp_kind_name, i_rep_section=i_rep)
2306 WRITE (unit=iw, fmt=
"(T2,A)") &
2307 "FORCEFIELD| Matching atomic kinds "//trim(kind_name)// &
2308 " and "//trim(inp_kind_name)//
" for MM_RADIUS"
2310 IF (trim(kind_name) == trim(inp_kind_name))
THEN
2312 keyword_name=
"MM_RADIUS", r_val=mm_radius)
2313 CALL issue_duplications(found,
"MM_RADIUS", kind_name)
2317 CALL set_potential(potential=fist_potential, mm_radius=mm_radius)
2320 CALL timestop(handle)
2334 INTEGER,
INTENT(IN) :: iw
2337 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_pol'
2339 CHARACTER(LEN=default_string_length) :: kind_name
2340 INTEGER :: handle, i, j
2342 REAL(kind=
dp) :: apol, cpol
2346 CALL timeset(routinen, handle)
2349 WRITE (unit=iw, fmt=
"(/,T2,A)") &
2350 "FORCEFIELD| Checking for polarisable forcefield terms"
2353 DO i = 1,
SIZE(atomic_kind_set)
2354 atomic_kind => atomic_kind_set(i)
2356 fist_potential=fist_potential, &
2358 CALL get_potential(potential=fist_potential, apol=apol, cpol=cpol)
2362 IF (iw > 0)
WRITE (unit=iw, fmt=
"(A)")
""
2364 IF (
ASSOCIATED(inp_info%apol_atm))
THEN
2365 DO j = 1,
SIZE(inp_info%apol_atm)
2367 WRITE (unit=iw, fmt=
"(T2,A)") &
2368 "FORCEFIELD| Matching atomic kinds "//trim(kind_name)// &
2369 " and "//trim(inp_info%apol_atm(j))//
" for APOL"
2371 IF ((inp_info%apol_atm(j)) == kind_name)
THEN
2372 apol = inp_info%apol(j)
2373 CALL issue_duplications(found,
"APOL", kind_name)
2379 IF (
ASSOCIATED(inp_info%cpol_atm))
THEN
2380 DO j = 1,
SIZE(inp_info%cpol_atm)
2382 WRITE (unit=iw, fmt=
"(T2,A)") &
2383 "FORCEFIELD| Matching atomic kinds "//trim(kind_name)// &
2384 " and "//trim(inp_info%cpol_atm(j))//
" for CPOL"
2386 IF ((inp_info%cpol_atm(j)) == kind_name)
THEN
2387 cpol = inp_info%cpol(j)
2388 CALL issue_duplications(found,
"CPOL", kind_name)
2394 CALL set_potential(potential=fist_potential, apol=apol, cpol=cpol)
2398 CALL timestop(handle)
2414 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_damp'
2416 CHARACTER(len=default_string_length) :: atm_name1, atm_name2, my_atm_name1, &
2418 INTEGER :: handle2, i, j, k, nkinds
2423 CALL timeset(routinen, handle2)
2426 WRITE (unit=iw, fmt=
"(/,T2,A)") &
2427 "FORCEFIELD| Checking for damping terms"
2431 nkinds =
SIZE(atomic_kind_set)
2433 DO j = 1,
SIZE(atomic_kind_set)
2435 atomic_kind => atomic_kind_set(j)
2441 IF (
ASSOCIATED(inp_info%damping_list))
THEN
2442 DO i = 1,
SIZE(inp_info%damping_list)
2443 my_atm_name1 = inp_info%damping_list(i)%atm_name1
2444 my_atm_name2 = inp_info%damping_list(i)%atm_name2
2445 IF (debug_this_module)
THEN
2447 WRITE (unit=iw, fmt=
"(T2,A)") &
2448 "FORCEFIELD| Check damping for the atomic kinds "// &
2449 trim(my_atm_name1)//
" and "//trim(atm_name1)
2452 IF (my_atm_name1 == atm_name1)
THEN
2453 IF (.NOT.
ASSOCIATED(damping))
THEN
2457 DO k = 1,
SIZE(atomic_kind_set)
2458 atomic_kind2 => atomic_kind_set(k)
2462 IF (my_atm_name2 == atm_name2)
THEN
2463 IF (damping%damp(k)%bij /= huge(0.0_dp)) found = .true.
2464 CALL issue_duplications(found,
"Damping", atm_name1)
2466 SELECT CASE (trim(inp_info%damping_list(i)%dtype))
2467 CASE (
'TANG-TOENNIES')
2470 cpabort(
"Unknown damping type.")
2472 damping%damp(k)%order = inp_info%damping_list(i)%order
2473 damping%damp(k)%bij = inp_info%damping_list(i)%bij
2474 damping%damp(k)%cij = inp_info%damping_list(i)%cij
2477 IF (.NOT. found)
THEN
2478 CALL cp_warn(__location__, &
2479 "Atom "//trim(my_atm_name2)// &
2480 " in damping parameters for atom "//trim(my_atm_name1)// &
2493 CALL timestop(handle2)
2512 molecule_kind_set, molecule_set, root_section, subsys_section, &
2513 shell_particle_set, core_particle_set, cell, iw, inp_info)
2520 TYPE(
particle_type),
DIMENSION(:),
POINTER :: shell_particle_set, core_particle_set
2525 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_shell'
2527 CHARACTER(LEN=default_string_length) :: atmname
2528 INTEGER :: counter, first, first_shell, handle2, i, &
2529 j, last, last_shell, n, natom, nmol, &
2531 INTEGER,
DIMENSION(:),
POINTER :: molecule_list, shell_list_tmp
2532 LOGICAL :: core_coord_read, found_shell, is_a_shell, is_link_atom, null_massfrac, only_qm, &
2533 save_mem, shell_adiabatic, shell_coord_read
2534 REAL(kind=
dp) :: atmmass
2540 TYPE(
shell_type),
DIMENSION(:),
POINTER :: shell_list
2542 CALL timeset(routinen, handle2)
2547 null_massfrac = .false.
2548 core_coord_read = .false.
2549 shell_coord_read = .false.
2551 NULLIFY (global_section)
2556 WRITE (unit=iw, fmt=
"(/,T2,A)") &
2557 "FORCEFIELD| Checking for core-shell terms"
2560 DO i = 1,
SIZE(atomic_kind_set)
2561 atomic_kind => atomic_kind_set(i)
2565 found_shell = .false.
2570 IF (
ASSOCIATED(inp_info%shell_list))
THEN
2571 DO j = 1,
SIZE(inp_info%shell_list)
2572 IF (debug_this_module)
THEN
2574 WRITE (unit=iw, fmt=
"(T2,A)") &
2575 "Checking shells for the atomic kinds "// &
2576 trim(inp_info%shell_list(j)%atm_name)//
" and "//trim(atmname)
2579 IF ((inp_info%shell_list(j)%atm_name) == atmname)
THEN
2581 shell=shell, mass=atmmass, natom=natom)
2582 IF (.NOT.
ASSOCIATED(shell))
ALLOCATE (shell)
2583 nshell_tot = nshell_tot + natom
2584 shell%charge_core = inp_info%shell_list(j)%shell%charge_core
2585 shell%charge_shell = inp_info%shell_list(j)%shell%charge_shell
2586 shell%massfrac = inp_info%shell_list(j)%shell%massfrac
2587 IF (shell%massfrac < epsilon(1.0_dp)) null_massfrac = .true.
2588 shell%k2_spring = inp_info%shell_list(j)%shell%k2_spring
2589 shell%k4_spring = inp_info%shell_list(j)%shell%k4_spring
2590 shell%max_dist = inp_info%shell_list(j)%shell%max_dist
2591 shell%shell_cutoff = inp_info%shell_list(j)%shell%shell_cutoff
2592 shell%mass_shell = shell%massfrac*atmmass
2593 shell%mass_core = atmmass - shell%mass_shell
2594 CALL issue_duplications(found_shell,
"Shell", atmname)
2595 found_shell = .true.
2597 shell=shell, shell_active=.true.)
2604 WRITE (unit=iw, fmt=
"(/,T2,A,T61,I20)") &
2605 "FORCEFIELD| Total number of particles with a shell:", nshell_tot
2608 NULLIFY (shell_particle_set)
2609 NULLIFY (core_particle_set)
2610 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, shell_adiabatic=shell_adiabatic)
2611 IF (nshell_tot > 0)
THEN
2612 IF (shell_adiabatic .AND. null_massfrac)
THEN
2613 cpabort(
"Shell-model adiabatic: at least one shell_kind has mass zero")
2620 DO i = 1,
SIZE(particle_set)
2621 NULLIFY (atomic_kind)
2623 atomic_kind => particle_set(i)%atomic_kind
2624 CALL get_atomic_kind(atomic_kind=atomic_kind, shell_active=is_a_shell)
2625 IF (is_a_shell)
THEN
2626 counter = counter + 1
2627 particle_set(i)%shell_index = counter
2628 shell_particle_set(counter)%shell_index = counter
2629 shell_particle_set(counter)%atomic_kind => particle_set(i)%atomic_kind
2630 shell_particle_set(counter)%r(1:3) = particle_set(i)%r(1:3)
2631 shell_particle_set(counter)%atom_index = i
2632 core_particle_set(counter)%shell_index = counter
2633 core_particle_set(counter)%atomic_kind => particle_set(i)%atomic_kind
2634 core_particle_set(counter)%r(1:3) = particle_set(i)%r(1:3)
2635 core_particle_set(counter)%atom_index = i
2637 particle_set(i)%shell_index = 0
2640 cpassert(counter == nshell_tot)
2645 subsys_section, shell_coord_read)
2647 subsys_section, core_coord_read)
2649 IF (nshell_tot > 0)
THEN
2652 IF (shell_adiabatic)
THEN
2653 IF (.NOT. (core_coord_read .AND. shell_coord_read))
THEN
2655 subsys_section, core_particle_set, &
2659 IF (.NOT. shell_coord_read)
THEN
2661 subsys_section, save_mem=save_mem)
2666 DO i = 1,
SIZE(molecule_kind_set)
2667 molecule_kind => molecule_kind_set(i)
2668 CALL get_molecule_kind(molecule_kind=molecule_kind, molecule_list=molecule_list, &
2669 natom=natom, nmolecule=nmol)
2670 molecule => molecule_set(molecule_list(1))
2671 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
2672 ALLOCATE (shell_list_tmp(natom))
2675 atomic_kind => particle_set(j)%atomic_kind
2676 CALL get_atomic_kind(atomic_kind=atomic_kind, shell_active=is_a_shell)
2677 IF (is_a_shell)
THEN
2678 counter = counter + 1
2679 shell_list_tmp(counter) = j - first + 1
2680 first_shell = min(first_shell, max(1, particle_set(j)%shell_index))
2683 IF (counter /= 0)
THEN
2685 DO j = 1,
SIZE(molecule_list)
2686 last_shell = first_shell + counter - 1
2687 molecule => molecule_set(molecule_list(j))
2688 molecule%first_shell = first_shell
2689 molecule%last_shell = last_shell
2690 first_shell = last_shell + 1
2694 IF (
ASSOCIATED(shell_list))
THEN
2695 DEALLOCATE (shell_list)
2697 ALLOCATE (shell_list(counter))
2699 shell_list(j)%a = shell_list_tmp(j)
2700 atomic_kind => particle_set(shell_list_tmp(j) + first - 1)%atomic_kind
2701 CALL get_atomic_kind(atomic_kind=atomic_kind, name=atmname, shell=shell)
2703 shell_list(j)%name = atmname
2704 shell_list(j)%shell_kind => shell
2706 CALL set_molecule_kind(molecule_kind=molecule_kind, nshell=counter, shell_list=shell_list)
2708 DEALLOCATE (shell_list_tmp)
2709 n = n + nmol*counter
2713 cpassert(first_shell - 1 == nshell_tot)
2714 cpassert(n == nshell_tot)
2716 CALL timestop(handle2)
2735 Ainfo, chm_info, inp_info, gro_info, amb_info, potparm_nonbond14, ewald_env)
2741 CHARACTER(LEN=default_string_length), &
2742 DIMENSION(:),
POINTER :: ainfo
2750 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_nonbond14'
2752 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a_local, &
2753 name_atm_b, name_atm_b_local
2754 INTEGER :: handle2, i, ii, j, jj, k, match_names
2755 LOGICAL :: found, found_a, found_b, only_qm, &
2757 REAL(kind=
dp) :: epsilon0, epsilon_a, epsilon_b, &
2758 ewald_rcut, rmin, rmin2_a, rmin2_b
2762 CALL timeset(routinen, handle2)
2764 use_qmmm_ff = qmmm_env%use_qmmm_ff
2768 WRITE (unit=iw, fmt=
"(/,T2,A)") &
2769 "FORCEFIELD| Checking for nonbonded14 terms"
2775 DO i = 1,
SIZE(atomic_kind_set)
2776 atomic_kind => atomic_kind_set(i)
2778 DO j = i,
SIZE(atomic_kind_set)
2779 atomic_kind => atomic_kind_set(j)
2784 name_atm_a = name_atm_a_local
2785 name_atm_b = name_atm_b_local
2789 pot => potparm_nonbond14%pot(i, j)%pot
2792 IF (
ASSOCIATED(gro_info%nonbond_a_14))
THEN
2795 DO k = 1,
SIZE(gro_info%nonbond_a_14)
2796 IF (trim(name_atm_a) == trim(gro_info%nonbond_a_14(k)))
THEN
2802 DO k = 1,
SIZE(gro_info%nonbond_a_14)
2803 IF (trim(name_atm_b) == trim(gro_info%nonbond_a_14(k)))
THEN
2809 IF (ii /= 0 .AND. jj /= 0)
THEN
2812 pot%at1 = name_atm_a
2813 pot%at2 = name_atm_b
2814 pot%set(1)%lj%epsilon = 1.0_dp
2815 pot%set(1)%lj%sigma6 = gro_info%nonbond_c6_14(ii, jj)
2816 pot%set(1)%lj%sigma12 = gro_info%nonbond_c12_14(ii, jj)
2817 pot%rcutsq = (10.0_dp*
bohr)**2
2818 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, name_atm_b)
2826 IF (
ASSOCIATED(chm_info%nonbond_a_14))
THEN
2827 DO k = 1,
SIZE(chm_info%nonbond_a_14)
2828 IF ((name_atm_a) == (chm_info%nonbond_a_14(k)))
THEN
2830 rmin2_a = chm_info%nonbond_rmin2_14(k)
2831 epsilon_a = chm_info%nonbond_eps_14(k)
2835 DO k = 1,
SIZE(chm_info%nonbond_a_14)
2836 IF ((name_atm_b) == (chm_info%nonbond_a_14(k)))
THEN
2838 rmin2_b = chm_info%nonbond_rmin2_14(k)
2839 epsilon_b = chm_info%nonbond_eps_14(k)
2844 IF (
ASSOCIATED(chm_info%nonbond_a))
THEN
2845 IF (.NOT. found_a)
THEN
2846 DO k = 1,
SIZE(chm_info%nonbond_a)
2847 IF ((name_atm_a) == (chm_info%nonbond_a(k)))
THEN
2849 rmin2_a = chm_info%nonbond_rmin2(k)
2850 epsilon_a = chm_info%nonbond_eps(k)
2854 IF (.NOT. found_b)
THEN
2855 DO k = 1,
SIZE(chm_info%nonbond_a)
2856 IF ((name_atm_b) == (chm_info%nonbond_a(k)))
THEN
2858 rmin2_b = chm_info%nonbond_rmin2(k)
2859 epsilon_b = chm_info%nonbond_eps(k)
2864 IF (ii /= 0 .AND. jj /= 0)
THEN
2865 rmin = rmin2_a + rmin2_b
2867 epsilon0 = sqrt(abs(epsilon_a*epsilon_b))
2870 pot%at1 = name_atm_a
2871 pot%at2 = name_atm_b
2872 pot%set(1)%lj%epsilon = epsilon0
2873 pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
2874 pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
2875 pot%rcutsq = (10.0_dp*
bohr)**2
2876 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, name_atm_b)
2881 IF (
ASSOCIATED(amb_info%nonbond_a))
THEN
2884 IF (.NOT. found_a)
THEN
2885 DO k = 1,
SIZE(amb_info%nonbond_a)
2886 IF ((name_atm_a) == (amb_info%nonbond_a(k)))
THEN
2888 rmin2_a = amb_info%nonbond_rmin2(k)
2889 epsilon_a = amb_info%nonbond_eps(k)
2893 IF (.NOT. found_b)
THEN
2894 DO k = 1,
SIZE(amb_info%nonbond_a)
2895 IF ((name_atm_b) == (amb_info%nonbond_a(k)))
THEN
2897 rmin2_b = amb_info%nonbond_rmin2(k)
2898 epsilon_b = amb_info%nonbond_eps(k)
2902 IF (ii /= 0 .AND. jj /= 0)
THEN
2903 rmin = rmin2_a + rmin2_b
2905 epsilon0 = sqrt(abs(epsilon_a*epsilon_b))
2908 pot%at1 = name_atm_a
2909 pot%at2 = name_atm_b
2910 pot%set(1)%lj%epsilon = epsilon0
2911 pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
2912 pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
2913 pot%rcutsq = (10.0_dp*
bohr)**2
2914 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, &
2921 IF (
ASSOCIATED(inp_info%nonbonded14))
THEN
2922 DO k = 1,
SIZE(inp_info%nonbonded14%pot)
2923 IF (iw > 0)
WRITE (iw, *)
" TESTING ", trim(name_atm_a), trim(name_atm_b), &
2924 " with ", trim(inp_info%nonbonded14%pot(k)%pot%at1), &
2925 trim(inp_info%nonbonded14%pot(k)%pot%at2)
2926 IF ((((name_atm_a) == (inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
2927 ((name_atm_b) == (inp_info%nonbonded14%pot(k)%pot%at2))) .OR. &
2928 (((name_atm_b) == (inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
2929 ((name_atm_a) == (inp_info%nonbonded14%pot(k)%pot%at2))))
THEN
2930 IF (ff_type%multiple_potential)
THEN
2933 CALL cp_warn(__location__, &
2934 "Multiple ONFO declaration: "//trim(name_atm_a)// &
2935 " and "//trim(name_atm_b)//
" ADDING! ")
2936 potparm_nonbond14%pot(i, j)%pot => pot
2937 potparm_nonbond14%pot(j, i)%pot => pot
2941 CALL cp_warn(__location__, &
2942 "Multiple ONFO declarations: "//trim(name_atm_a)// &
2943 " and "//trim(name_atm_b)//
" OVERWRITING! ")
2945 IF (iw > 0)
WRITE (iw, *)
" FOUND ", trim(name_atm_a),
" ", trim(name_atm_b)
2953 IF (use_qmmm_ff)
THEN
2955 IF ((name_atm_a) == (name_atm_a_local)) match_names = match_names + 1
2956 IF ((name_atm_b) == (name_atm_b_local)) match_names = match_names + 1
2957 IF (match_names == 1)
THEN
2958 IF (
ASSOCIATED(qmmm_env%inp_info%nonbonded14))
THEN
2959 DO k = 1,
SIZE(qmmm_env%inp_info%nonbonded14%pot)
2960 IF (debug_this_module)
THEN
2962 WRITE (unit=iw, fmt=
"(T2,A)") &
2963 "FORCEFIELD| Testing "//trim(name_atm_a)//
"-"//trim(name_atm_b)// &
2964 " with "//trim(qmmm_env%inp_info%nonbonded14%pot(k)%pot%at1)//
"-"// &
2965 trim(qmmm_env%inp_info%nonbonded14%pot(k)%pot%at2)
2968 IF ((((name_atm_a) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
2969 ((name_atm_b) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at2))) .OR. &
2970 (((name_atm_b) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
2971 ((name_atm_a) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at2))))
THEN
2972 IF (qmmm_env%multiple_potential)
THEN
2975 CALL cp_warn(__location__, &
2976 "Multiple ONFO declaration: "//trim(name_atm_a)// &
2977 " and "//trim(name_atm_b)//
" Adding QM/MM forcefield specifications")
2978 potparm_nonbond14%pot(i, j)%pot => pot
2979 potparm_nonbond14%pot(j, i)%pot => pot
2983 CALL cp_warn(__location__, &
2984 "Multiple ONFO declaration: "//trim(name_atm_a)// &
2985 " and "//trim(name_atm_b)//
" OVERWRITING QM/MM forcefield specifications! ")
2987 IF (iw > 0)
WRITE (iw, *)
" FOUND ", trim(name_atm_a), &
2988 " ", trim(name_atm_b)
2996 IF (.NOT. found)
THEN
2997 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
2998 atm2=trim(name_atm_b), &
2999 type_name=
"Spline_Bond_Env", &
3003 pot%at1 = name_atm_a
3004 pot%at2 = name_atm_b
3008 IF (ff_type%rcut_nb > 0.0_dp)
THEN
3009 pot%rcutsq = ff_type%rcut_nb*ff_type%rcut_nb
3013 pot%rcutsq = max(pot%rcutsq, ewald_rcut*ewald_rcut)
3022 CALL timestop(handle2)
3042 iw, Ainfo, chm_info, inp_info, gro_info, amb_info, potparm_nonbond, &
3050 CHARACTER(LEN=default_string_length), &
3051 DIMENSION(:),
POINTER :: ainfo
3059 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_nonbond'
3061 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a_local, &
3062 name_atm_b, name_atm_b_local
3063 INTEGER :: handle2, i, ii, j, jj, k, match_names
3064 LOGICAL :: found, is_a_shell, is_b_shell, only_qm, &
3066 REAL(kind=
dp) :: epsilon0, ewald_rcut, rmin
3070 CALL timeset(routinen, handle2)
3072 use_qmmm_ff = qmmm_env%use_qmmm_ff
3076 WRITE (unit=iw, fmt=
"(/,T2,A)") &
3077 "FORCEFIELD| Checking for nonbonded terms"
3083 DO i = 1,
SIZE(atomic_kind_set)
3085 atomic_kind => atomic_kind_set(i)
3087 CALL get_atomic_kind(atomic_kind=atomic_kind, name=name_atm_a_local, &
3088 shell_active=is_a_shell)
3090 DO j = i,
SIZE(atomic_kind_set)
3092 atomic_kind => atomic_kind_set(j)
3094 CALL get_atomic_kind(atomic_kind=atomic_kind, name=name_atm_b_local, &
3095 shell_active=is_b_shell)
3099 name_atm_a = name_atm_a_local
3100 name_atm_b = name_atm_b_local
3104 pot => potparm_nonbond%pot(i, j)%pot
3107 WRITE (unit=iw, fmt=
"(/,T2,A)") &
3108 "FORCEFIELD| Checking for nonbonded terms between the atomic kinds "// &
3109 trim(name_atm_a)//
" and "//trim(name_atm_b)
3113 IF (
ASSOCIATED(gro_info%nonbond_a))
THEN
3116 DO k = 1,
SIZE(gro_info%nonbond_a)
3117 IF (trim(name_atm_a) == trim(gro_info%nonbond_a(k)))
THEN
3122 DO k = 1,
SIZE(gro_info%nonbond_a)
3123 IF (trim(name_atm_b) == trim(gro_info%nonbond_a(k)))
THEN
3129 IF (ii /= 0 .AND. jj /= 0)
THEN
3132 pot%at1 = name_atm_a
3133 pot%at2 = name_atm_b
3134 pot%set(1)%lj%epsilon = 1.0_dp
3135 pot%set(1)%lj%sigma6 = gro_info%nonbond_c6(ii, jj)
3136 pot%set(1)%lj%sigma12 = gro_info%nonbond_c12(ii, jj)
3137 pot%rcutsq = (10.0_dp*
bohr)**2
3138 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, name_atm_b)
3144 IF (
ASSOCIATED(chm_info%nonbond_a))
THEN
3147 DO k = 1,
SIZE(chm_info%nonbond_a)
3148 IF ((name_atm_a) == (chm_info%nonbond_a(k)))
THEN
3152 DO k = 1,
SIZE(chm_info%nonbond_a)
3153 IF ((name_atm_b) == (chm_info%nonbond_a(k)))
THEN
3158 IF (ii /= 0 .AND. jj /= 0)
THEN
3159 rmin = chm_info%nonbond_rmin2(ii) + chm_info%nonbond_rmin2(jj)
3160 epsilon0 = sqrt(chm_info%nonbond_eps(ii)* &
3161 chm_info%nonbond_eps(jj))
3164 pot%at1 = name_atm_a
3165 pot%at2 = name_atm_b
3166 pot%set(1)%lj%epsilon = epsilon0
3167 pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
3168 pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
3169 pot%rcutsq = (10.0_dp*
bohr)**2
3170 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, name_atm_b)
3176 IF (
ASSOCIATED(amb_info%nonbond_a))
THEN
3179 DO k = 1,
SIZE(amb_info%nonbond_a)
3180 IF ((name_atm_a) == (amb_info%nonbond_a(k)))
THEN
3184 DO k = 1,
SIZE(amb_info%nonbond_a)
3185 IF ((name_atm_b) == (amb_info%nonbond_a(k)))
THEN
3190 IF (ii /= 0 .AND. jj /= 0)
THEN
3191 rmin = amb_info%nonbond_rmin2(ii) + amb_info%nonbond_rmin2(jj)
3192 epsilon0 = sqrt(amb_info%nonbond_eps(ii)*amb_info%nonbond_eps(jj))
3195 pot%at1 = name_atm_a
3196 pot%at2 = name_atm_b
3197 pot%set(1)%lj%epsilon = epsilon0
3198 pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
3199 pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
3200 pot%rcutsq = (10.0_dp*
bohr)**2
3201 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, name_atm_b)
3207 IF (
ASSOCIATED(inp_info%nonbonded))
THEN
3208 DO k = 1,
SIZE(inp_info%nonbonded%pot)
3209 IF ((trim(inp_info%nonbonded%pot(k)%pot%at1) ==
"*") .OR. &
3210 (trim(inp_info%nonbonded%pot(k)%pot%at2) ==
"*")) cycle
3211 IF (debug_this_module)
THEN
3213 WRITE (unit=iw, fmt=
"(T2,A)") &
3214 "FORCEFIELD| Testing "//trim(name_atm_a)//
"-"//trim(name_atm_b)// &
3215 " with "//trim(inp_info%nonbonded%pot(k)%pot%at1)//
"-"// &
3216 trim(inp_info%nonbonded%pot(k)%pot%at2)
3219 IF ((((name_atm_a) == (inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
3220 ((name_atm_b) == (inp_info%nonbonded%pot(k)%pot%at2))) .OR. &
3221 (((name_atm_b) == (inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
3222 ((name_atm_a) == (inp_info%nonbonded%pot(k)%pot%at2))))
THEN
3224 WRITE (unit=iw, fmt=
"(T2,A)") &
3225 "FORCEFIELD| Found nonbonded term "// &
3226 trim(name_atm_a)//
"-"//trim(name_atm_b)
3228 IF (ff_type%multiple_potential)
THEN
3231 CALL cp_warn(__location__, &
3232 "Multiple NONBONDED declarations for "//trim(name_atm_a)// &
3233 "-"//trim(name_atm_b)//
" -> ADDING")
3234 potparm_nonbond%pot(i, j)%pot => pot
3235 potparm_nonbond%pot(j, i)%pot => pot
3239 CALL cp_warn(__location__, &
3240 "Multiple NONBONDED declarations for "//trim(name_atm_a)// &
3241 "-"//trim(name_atm_b)//
" -> OVERWRITING")
3248 IF (.NOT. found)
THEN
3249 DO k = 1,
SIZE(inp_info%nonbonded%pot)
3250 IF ((trim(inp_info%nonbonded%pot(k)%pot%at1) ==
"*") .EQV. &
3251 (trim(inp_info%nonbonded%pot(k)%pot%at2) ==
"*")) cycle
3252 IF (debug_this_module)
THEN
3254 WRITE (unit=iw, fmt=
"(T2,A)") &
3255 "FORCEFIELD| Testing "//trim(name_atm_a)//
"-"//trim(name_atm_b)// &
3256 " with "//trim(inp_info%nonbonded%pot(k)%pot%at1)//
"-"// &
3257 trim(inp_info%nonbonded%pot(k)%pot%at2)
3260 IF ((name_atm_a == inp_info%nonbonded%pot(k)%pot%at1) .OR. &
3261 (name_atm_b == inp_info%nonbonded%pot(k)%pot%at2) .OR. &
3262 (name_atm_b == inp_info%nonbonded%pot(k)%pot%at1) .OR. &
3263 (name_atm_a == inp_info%nonbonded%pot(k)%pot%at2))
THEN
3265 WRITE (unit=iw, fmt=
"(T2,A)") &
3266 "FORCEFIELD| Found one wildcard for "// &
3267 trim(name_atm_a)//
"-"//trim(name_atm_b)
3269 IF (ff_type%multiple_potential)
THEN
3272 CALL cp_warn(__location__, &
3273 "Multiple NONBONDED declarations "//trim(name_atm_a)// &
3274 "-"//trim(name_atm_b)//
" -> ADDING")
3275 potparm_nonbond%pot(i, j)%pot => pot
3276 potparm_nonbond%pot(j, i)%pot => pot
3280 CALL cp_warn(__location__, &
3281 "Multiple NONBONDED declarations "//trim(name_atm_a)// &
3282 "-"//trim(name_atm_b)//
" -> OVERWRITING")
3290 IF (.NOT. found)
THEN
3291 DO k = 1,
SIZE(inp_info%nonbonded%pot)
3292 IF ((trim(inp_info%nonbonded%pot(k)%pot%at1) /=
"*") .OR. &
3293 (trim(inp_info%nonbonded%pot(k)%pot%at2) /=
"*")) cycle
3294 IF (debug_this_module)
THEN
3296 WRITE (unit=iw, fmt=
"(T2,A)") &
3297 "FORCEFIELD| Testing "//trim(name_atm_a)//
"-"//trim(name_atm_b)// &
3298 " with "//trim(inp_info%nonbonded%pot(k)%pot%at1)//
"-"// &
3299 trim(inp_info%nonbonded%pot(k)%pot%at2)
3303 WRITE (unit=iw, fmt=
"(T2,A)") &
3304 "FORCEFIELD| Found wildcards for both "// &
3305 trim(name_atm_a)//
" and "//trim(name_atm_b)
3307 IF (ff_type%multiple_potential)
THEN
3310 CALL cp_warn(__location__, &
3311 "Multiple NONBONDED declarations "//trim(name_atm_a)// &
3312 " - "//trim(name_atm_b)//
" -> ADDING")
3313 potparm_nonbond%pot(i, j)%pot => pot
3314 potparm_nonbond%pot(j, i)%pot => pot
3318 CALL cp_warn(__location__, &
3319 "Multiple NONBONDED declarations "//trim(name_atm_a)// &
3320 " - "//trim(name_atm_b)//
" -> OVERWRITING")
3329 IF (use_qmmm_ff)
THEN
3331 IF ((name_atm_a) == (name_atm_a_local)) match_names = match_names + 1
3332 IF ((name_atm_b) == (name_atm_b_local)) match_names = match_names + 1
3333 IF (match_names == 1)
THEN
3334 IF (
ASSOCIATED(qmmm_env%inp_info%nonbonded))
THEN
3335 DO k = 1,
SIZE(qmmm_env%inp_info%nonbonded%pot)
3336 IF (debug_this_module)
THEN
3338 WRITE (unit=iw, fmt=
"(T2,A)") &
3339 "FORCEFIELD| Testing "//trim(name_atm_a)//
"-"//trim(name_atm_b)// &
3340 " with "//trim(qmmm_env%inp_info%nonbonded%pot(k)%pot%at1), &
3341 trim(qmmm_env%inp_info%nonbonded%pot(k)%pot%at2)
3344 IF ((((name_atm_a) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
3345 ((name_atm_b) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at2))) .OR. &
3346 (((name_atm_b) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
3347 ((name_atm_a) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at2))))
THEN
3349 WRITE (unit=iw, fmt=
"(T2,A)") &
3350 "FORCEFIELD| Found "//trim(name_atm_a)//
"-"//trim(name_atm_b)//
" (QM/MM)"
3352 IF (qmmm_env%multiple_potential)
THEN
3355 CALL cp_warn(__location__, &
3356 "Multiple NONBONDED declarations for "//trim(name_atm_a)// &
3357 " and "//trim(name_atm_b)//
" -> ADDING QM/MM forcefield specifications")
3358 potparm_nonbond%pot(i, j)%pot => pot
3359 potparm_nonbond%pot(j, i)%pot => pot
3363 CALL cp_warn(__location__, &
3364 "Multiple NONBONDED declarations for "//trim(name_atm_a)// &
3365 " and "//trim(name_atm_b)//
" -> OVERWRITING QM/MM forcefield specifications")
3374 IF (.NOT. found)
THEN
3375 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
3376 atm2=trim(name_atm_b), &
3377 type_name=
"Spline_Non_Bond_Env", &
3383 IF (ff_type%rcut_nb > 0.0_dp)
THEN
3384 pot%rcutsq = ff_type%rcut_nb*ff_type%rcut_nb
3388 pot%rcutsq = max(pot%rcutsq, ewald_rcut*ewald_rcut)
3390 IF ((is_a_shell .AND. .NOT. is_b_shell) .OR. (is_b_shell .AND. .NOT. is_a_shell))
THEN
3392 ELSE IF (is_a_shell .AND. is_b_shell)
THEN
3393 pot%shell_type =
sh_sh
3406 CALL timestop(handle2)
3422 potparm, do_zbl, nonbonded_type)
3426 INTEGER :: iw2, iw3, iw4
3428 LOGICAL,
INTENT(IN) :: do_zbl
3429 CHARACTER(LEN=*),
INTENT(IN) :: nonbonded_type
3431 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_splines'
3433 INTEGER :: handle2, ikind, jkind, n
3437 CALL timeset(routinen, handle2)
3440 WRITE (unit=iw2, fmt=
"(/,T2,A)") &
3441 "FORCEFIELD| Splining nonbonded terms"
3446 NULLIFY (spline_env)
3448 do_zbl, shift_cutoff=ff_type%shift_cutoff)
3451 atomic_kind_set, eps_spline=ff_type%eps_spline, &
3452 max_energy=ff_type%max_energy, rlow_nb=ff_type%rlow_nb, &
3453 emax_spline=ff_type%emax_spline, npoints=ff_type%npoints, &
3454 iw=iw2, iw2=iw3, iw3=iw4, &
3455 do_zbl=do_zbl, shift_cutoff=ff_type%shift_cutoff, &
3456 nonbonded_type=nonbonded_type)
3459 DO ikind = 1,
SIZE(potparm%pot, 1)
3460 DO jkind = ikind,
SIZE(potparm%pot, 2)
3461 n = spline_env%spltab(ikind, jkind)
3462 spl_p => spline_env%spl_pp(n)%spl_p
3465 potparm%pot(ikind, jkind)%pot%pair_spline_data => spl_p
3469 DEALLOCATE (spline_env)
3470 NULLIFY (spline_env)
3473 WRITE (unit=iw2, fmt=
"(/,T2,A)") &
3474 "FORCEFIELD| Splining done"
3477 CALL timestop(handle2)
3496 INTEGER,
INTENT(IN) :: iw
3498 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_eicut'
3500 INTEGER :: ewald_type, handle, i1, i2, nkinds
3501 REAL(kind=
dp) :: alpha, beta, mm_radius1, mm_radius2, &
3502 rcut2, rcut2_ewald, tmp
3503 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: interaction_cutoffs
3506 CALL timeset(routinen, handle)
3509 WRITE (unit=iw, fmt=
"(/,T2,A)") &
3510 "FORCEFIELD| Computing the electrostatic interactions cutoffs"
3514 nkinds =
SIZE(atomic_kind_set)
3518 ALLOCATE (interaction_cutoffs(3, nkinds, nkinds))
3519 interaction_cutoffs = 0.0_dp
3522 IF (ff_type%shift_cutoff)
THEN
3523 CALL ewald_env_get(ewald_env, alpha=alpha, ewald_type=ewald_type, &
3525 rcut2_ewald = rcut2_ewald*rcut2_ewald
3527 atomic_kind => atomic_kind_set(i1)
3531 IF (
ASSOCIATED(potparm_nonbond))
THEN
3532 rcut2 = max(potparm_nonbond%pot(i1, i2)%pot%rcutsq, rcut2_ewald)
3535 atomic_kind => atomic_kind_set(i2)
3539 1.0_dp, ewald_type, alpha, 0.0_dp, 0.0_dp)
3541 IF (mm_radius1 > 0.0_dp)
THEN
3547 1.0_dp, ewald_type, alpha, beta, 0.0_dp)
3549 IF (mm_radius1 + mm_radius2 > 0.0_dp)
THEN
3550 beta =
sqrthalf/sqrt(mm_radius1*mm_radius1 + mm_radius2*mm_radius2)
3555 1.0_dp, ewald_type, alpha, beta, 0.0_dp)
3561 CALL ewald_env_set(ewald_env, interaction_cutoffs=interaction_cutoffs)
3563 CALL timestop(handle)
3578 SUBROUTINE issue_duplications(found, tag_label, name_atm_a, name_atm_b, &
3579 name_atm_c, name_atm_d)
3581 LOGICAL,
INTENT(IN) :: found
3582 CHARACTER(LEN=*),
INTENT(IN) :: tag_label, name_atm_a
3583 CHARACTER(LEN=*),
INTENT(IN),
OPTIONAL :: name_atm_b, name_atm_c, name_atm_d
3585 CHARACTER(LEN=default_string_length) :: item
3587 item =
"("//trim(name_atm_a)
3588 IF (
PRESENT(name_atm_b))
THEN
3589 item = trim(item)//
", "//trim(name_atm_b)
3591 IF (
PRESENT(name_atm_c))
THEN
3592 item = trim(item)//
", "//trim(name_atm_c)
3594 IF (
PRESENT(name_atm_d))
THEN
3595 item = trim(item)//
", "//trim(name_atm_d)
3597 item = trim(item)//
")"
3599 cpwarn(
"Found multiple "//trim(tag_label)//
" terms for "//trim(item)//
" -> OVERWRITING")
3602 END SUBROUTINE issue_duplications
3614 SUBROUTINE store_ff_missing_par(atm1, atm2, atm3, atm4, type_name, fatal, array)
3615 CHARACTER(LEN=*),
INTENT(IN) :: atm1
3616 CHARACTER(LEN=*),
INTENT(IN),
OPTIONAL :: atm2, atm3, atm4
3617 CHARACTER(LEN=*),
INTENT(IN) :: type_name
3618 LOGICAL,
INTENT(INOUT),
OPTIONAL :: fatal
3619 CHARACTER(LEN=default_string_length), &
3620 DIMENSION(:),
POINTER :: array
3622 CHARACTER(LEN=10) :: sfmt
3623 CHARACTER(LEN=9) :: my_atm1, my_atm2, my_atm3, my_atm4
3624 CHARACTER(LEN=default_path_length) :: my_format
3625 INTEGER :: fmt, i, nsize
3630 my_format =
'(T2,"FORCEFIELD| Missing ","'//trim(type_name)// &
3632 IF (
PRESENT(atm2)) fmt = fmt + 1
3633 IF (
PRESENT(atm3)) fmt = fmt + 1
3634 IF (
PRESENT(atm4)) fmt = fmt + 1
3637 my_format =
'(T2,"FORCEFIELD| Missing ","'//trim(type_name)// &
3638 '",T40,"(",A9,'//trim(sfmt)//
'(",",A9),")")'
3639 IF (
PRESENT(fatal)) fatal = .true.
3641 IF (
ASSOCIATED(array)) nsize =
SIZE(array)
3643 IF (nsize >= 1)
THEN
3645 SELECT CASE (type_name)
3647 IF (index(array(i) (21:39),
"Bond") == 0) cycle
3648 my_atm1 = array(i) (41:49)
3649 my_atm2 = array(i) (51:59)
3652 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2)) .OR. &
3653 ((atm1 == my_atm2) .AND. (atm2 == my_atm1))) found = .true.
3655 IF (index(array(i) (21:39),
"Angle") == 0) cycle
3656 my_atm1 = array(i) (41:49)
3657 my_atm2 = array(i) (51:59)
3658 my_atm3 = array(i) (61:69)
3662 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3)) .OR. &
3663 ((atm1 == my_atm3) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm1))) &
3665 CASE (
"Urey-Bradley")
3666 IF (index(array(i) (21:39),
"Urey-Bradley") == 0) cycle
3667 my_atm1 = array(i) (41:49)
3668 my_atm2 = array(i) (51:59)
3669 my_atm3 = array(i) (61:69)
3673 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3)) .OR. &
3674 ((atm1 == my_atm3) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm1))) &
3677 IF (index(array(i) (21:39),
"Torsion") == 0) cycle
3678 my_atm1 = array(i) (41:49)
3679 my_atm2 = array(i) (51:59)
3680 my_atm3 = array(i) (61:69)
3681 my_atm4 = array(i) (71:79)
3686 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm4)) .OR. &
3687 ((atm1 == my_atm4) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm1))) &
3690 IF (index(array(i) (21:39),
"Improper") == 0) cycle
3691 my_atm1 = array(i) (41:49)
3692 my_atm2 = array(i) (51:59)
3693 my_atm3 = array(i) (61:69)
3694 my_atm4 = array(i) (71:79)
3699 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm4)) .OR. &
3700 ((atm1 == my_atm1) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm4)) .OR. &
3701 ((atm1 == my_atm1) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm4) .AND. (atm4 == my_atm3)) .OR. &
3702 ((atm1 == my_atm1) .AND. (atm2 == my_atm4) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm2)) .OR. &
3703 ((atm1 == my_atm1) .AND. (atm2 == my_atm4) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm3)) .OR. &
3704 ((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm4) .AND. (atm4 == my_atm3))) &
3707 CASE (
"Out of plane bend")
3708 IF (index(array(i) (21:39),
"Out of plane bend") == 0) cycle
3709 my_atm1 = array(i) (41:49)
3710 my_atm2 = array(i) (51:59)
3711 my_atm3 = array(i) (61:69)
3712 my_atm4 = array(i) (71:79)
3717 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm4)) .OR. &
3718 ((atm1 == my_atm1) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm4))) &
3722 IF (index(array(i) (21:39),
"Charge") == 0) cycle
3723 my_atm1 = array(i) (41:49)
3725 IF (atm1 == my_atm1) found = .true.
3726 CASE (
"Spline_Bond_Env",
"Spline_Non_Bond_Env")
3727 IF (index(array(i) (21:39),
"Spline_") == 0) cycle
3729 my_atm1 = array(i) (41:49)
3730 my_atm2 = array(i) (51:59)
3733 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2)) .OR. &
3734 ((atm1 == my_atm2) .AND. (atm2 == my_atm1))) found = .true.
3742 IF (.NOT. found)
THEN
3747 WRITE (array(nsize), fmt=trim(my_format)) atm1
3749 WRITE (array(nsize), fmt=trim(my_format)) atm1, atm2
3751 WRITE (array(nsize), fmt=trim(my_format)) atm1, atm2, atm3
3753 WRITE (array(nsize), fmt=trim(my_format)) atm1, atm2, atm3, atm4
3757 END SUBROUTINE store_ff_missing_par
3766 FUNCTION bsearch_leftmost_2d(array, val, row)
RESULT(res)
3767 INTEGER,
INTENT(IN) :: array(:, :), val
3768 INTEGER,
INTENT(IN),
OPTIONAL :: row
3771 INTEGER :: left, locrow, mid, right
3774 IF (
PRESENT(row)) locrow = row
3777 right = ubound(array, dim=2)
3779 DO WHILE (left < right)
3780 mid = (left + right)/2
3781 IF (array(locrow, mid) < val)
THEN
3791 IF (array(locrow, res) /= val) res = 0
3793 END FUNCTION bsearch_leftmost_2d
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
subroutine, public set_atomic_kind(atomic_kind, element_symbol, name, mass, kind_number, natom, atom_list, fist_potential, shell, shell_active, damping)
Set the components of an atomic kind data set.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Handles all functions related to the CELL.
various routines to log and control the output. The idea is that decisions about where to log should ...
integer, parameter, public tang_toennies
subroutine, public damping_p_create(damping, nkinds)
Creates Data-structure that contains damping information.
subroutine, public ewald_env_set(ewald_env, ewald_type, alpha, epsilon, eps_pol, gmax, ns_max, precs, o_spline, para_env, poisson_section, interaction_cutoffs, cell_hmat)
Purpose: Set the EWALD environment.
subroutine, public ewald_env_get(ewald_env, ewald_type, alpha, eps_pol, epsilon, gmax, ns_max, o_spline, group, para_env, poisson_section, precs, rcut, do_multipoles, max_multipole, do_ipol, max_ipol_iter, interaction_cutoffs, cell_hmat)
Purpose: Get the EWALD environment.
Definition of the atomic potential types.
Define all structure types related to force field kinds.
integer, parameter, public do_ff_undef
pure subroutine, public allocate_impr_kind_set(impr_kind_set, nkind)
Allocate and initialize a impr kind set.
pure subroutine, public allocate_torsion_kind_set(torsion_kind_set, nkind)
Allocate and initialize a torsion kind set.
pure subroutine, public allocate_bond_kind_set(bond_kind_set, nkind)
Allocate and initialize a bond kind set.
integer, parameter, public do_ff_charmm
pure subroutine, public allocate_opbend_kind_set(opbend_kind_set, nkind)
Allocate and initialize a opbend kind set.
integer, parameter, public do_ff_g87
integer, parameter, public do_ff_g96
pure subroutine, public allocate_bend_kind_set(bend_kind_set, nkind)
Allocate and initialize a bend kind set.
integer, parameter, public do_ff_amber
pure subroutine, public allocate_ub_kind_set(ub_kind_set, nkind)
Allocate and initialize a ub kind set.
Define all structures types related to force_fields.
subroutine, public force_field_unique_ub(particle_set, molecule_kind_set, molecule_set, iw)
Determine the number of unique Urey-Bradley kind and allocate ub_kind_set.
subroutine, public force_field_pack_tors(particle_set, molecule_kind_set, molecule_set, ainfo, chm_info, inp_info, gro_info, amb_info, iw)
Pack in torsion information needed for the force_field.
subroutine, public force_field_unique_bond(particle_set, molecule_kind_set, molecule_set, ff_type, iw)
Determine the number of unique bond kind and allocate bond_kind_set.
subroutine, public force_field_unique_opbend(particle_set, molecule_kind_set, molecule_set, ff_type, iw)
Determine the number of unique opbend kind and allocate opbend_kind_set based on the present improper...
subroutine, public force_field_pack_impr(particle_set, molecule_kind_set, molecule_set, ainfo, chm_info, inp_info, gro_info, iw)
Pack in impropers information needed for the force_field.
subroutine, public force_field_pack_radius(atomic_kind_set, iw, subsys_section)
Set up the radius of the electrostatic multipole in Fist.
subroutine, public force_field_pack_shell(particle_set, atomic_kind_set, molecule_kind_set, molecule_set, root_section, subsys_section, shell_particle_set, core_particle_set, cell, iw, inp_info)
Set up shell potential parameters.
subroutine, public force_field_pack_opbend(particle_set, molecule_kind_set, molecule_set, ainfo, inp_info, iw)
Pack in opbend information needed for the force_field. No loop over params for charmm,...
subroutine, public force_field_pack_charges(charges, charges_section, particle_set, my_qmmm, qmmm_env, inp_info, iw4)
Set up array of full charges.
subroutine, public force_field_pack_pol(atomic_kind_set, iw, inp_info)
Set up the polarizable FF parameters.
subroutine, public force_field_unique_bend(particle_set, molecule_kind_set, molecule_set, ff_type, iw)
Determine the number of unique bend kind and allocate bend_kind_set.
subroutine, public force_field_unique_impr(particle_set, molecule_kind_set, molecule_set, ff_type, iw)
Determine the number of unique impr kind and allocate impr_kind_set.
subroutine, public force_field_pack_splines(atomic_kind_set, ff_type, iw2, iw3, iw4, potparm, do_zbl, nonbonded_type)
create the pair potential spline environment
subroutine, public force_field_unique_tors(particle_set, molecule_kind_set, molecule_set, ff_type, iw)
Determine the number of unique torsion kind and allocate torsion_kind_set.
subroutine, public force_field_pack_nonbond(atomic_kind_set, ff_type, qmmm_env, fatal, iw, ainfo, chm_info, inp_info, gro_info, amb_info, potparm_nonbond, ewald_env)
Assign input and potential info to potparm_nonbond.
subroutine, public force_field_pack_charge(atomic_kind_set, qmmm_env, fatal, iw, iw4, ainfo, my_qmmm, inp_info)
Set up atomic_kind_set()fist_potential%[qeff] and shell potential parameters.
subroutine, public force_field_pack_bend(particle_set, molecule_kind_set, molecule_set, fatal, ainfo, chm_info, inp_info, gro_info, amb_info, iw)
Pack in bends information needed for the force_field.
subroutine, public force_field_pack_eicut(atomic_kind_set, ff_type, potparm_nonbond, ewald_env, iw)
Compute the electrostatic interaction cutoffs.
subroutine, public force_field_pack_bond(particle_set, molecule_kind_set, molecule_set, fatal, ainfo, chm_info, inp_info, gro_info, amb_info, iw)
Pack in bonds information needed for the force_field.
subroutine, public force_field_pack_damp(atomic_kind_set, iw, inp_info)
Set up damping parameters.
subroutine, public force_field_pack_nonbond14(atomic_kind_set, ff_type, qmmm_env, iw, ainfo, chm_info, inp_info, gro_info, amb_info, potparm_nonbond14, ewald_env)
Assign input and potential info to potparm_nonbond14.
subroutine, public force_field_pack_ub(particle_set, molecule_kind_set, molecule_set, ainfo, chm_info, inp_info, iw)
Pack in Urey-Bradley information needed for the force_field.
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition of mathematical constants and functions.
real(kind=dp), parameter, public sqrthalf
Utility routines for the memory handling.
Define the molecule kind structure types and the corresponding functionality.
subroutine, public get_molecule_kind(molecule_kind, atom_list, bond_list, bend_list, ub_list, impr_list, opbend_list, colv_list, fixd_list, g3x3_list, g4x6_list, vsite_list, torsion_list, shell_list, name, mass, charge, kind_number, natom, nbend, nbond, nub, nimpr, nopbend, nconstraint, nconstraint_fixd, nfixd, ncolv, ng3x3, ng4x6, nvsite, nfixd_restraint, ng3x3_restraint, ng4x6_restraint, nvsite_restraint, nrestraints, nmolecule, nsgf, nshell, ntorsion, molecule_list, nelectron, nelectron_alpha, nelectron_beta, bond_kind_set, bend_kind_set, ub_kind_set, impr_kind_set, opbend_kind_set, torsion_kind_set, molname_generated)
Get informations about a molecule kind.
subroutine, public set_molecule_kind(molecule_kind, name, mass, charge, kind_number, molecule_list, atom_list, nbond, bond_list, nbend, bend_list, nub, ub_list, nimpr, impr_list, nopbend, opbend_list, ntorsion, torsion_list, fixd_list, ncolv, colv_list, ng3x3, g3x3_list, ng4x6, nfixd, g4x6_list, nvsite, vsite_list, ng3x3_restraint, ng4x6_restraint, nfixd_restraint, nshell, shell_list, nvsite_restraint, bond_kind_set, bend_kind_set, ub_kind_set, torsion_kind_set, impr_kind_set, opbend_kind_set, nelectron, nsgf, molname_generated)
Set the components of a molecule kind.
Define the data structure for the molecule information.
subroutine, public get_molecule(molecule, molecule_kind, lmi, lci, lg3x3, lg4x6, lcolv, first_atom, last_atom, first_shell, last_shell)
Get components from a molecule data set.
real(kind=dp) function, public potential_coulomb(r2, fscalar, qfac, ewald_type, alpha, beta, interaction_cutoff)
Evaluates the electrostatic energy and force.
integer, parameter, public sh_sh
integer, parameter, public nosh_nosh
integer, parameter, public lj_charmm_type
integer, parameter, public allegro_type
integer, parameter, public nequip_type
integer, parameter, public lj_type
integer, parameter, public deepmd_type
subroutine, public pair_potential_single_copy(potparm_source, potparm_dest)
Copy two potential parameter type.
integer, parameter, public nn_type
subroutine, public pair_potential_single_add(potparm_source, potparm_dest)
Add potential parameter type to an existing potential parameter type Used in case of multiple_potenti...
integer, parameter, public siepmann_type
integer, parameter, public nosh_sh
subroutine, public pair_potential_single_clean(potparm)
Cleans the potential parameter type.
subroutine, public pair_potential_lj_create(lj)
Cleans the LJ potential type.
integer, parameter, public ace_type
subroutine, public pair_potential_pp_create(potparm, nkinds)
Data-structure that constains potential parameters.
integer, parameter, public ea_type
integer, parameter, public tersoff_type
subroutine, public spline_nonbond_control(spline_env, potparm, atomic_kind_set, eps_spline, max_energy, rlow_nb, emax_spline, npoints, iw, iw2, iw3, do_zbl, shift_cutoff, nonbonded_type)
creates the splines for the potentials
subroutine, public get_nonbond_storage(spline_env, potparm, atomic_kind_set, do_zbl, shift_cutoff)
Prescreening of the effective bonds evaluations. linear scaling algorithm.
Define the data structure for the particle information.
subroutine, public allocate_particle_set(particle_set, nparticle)
Allocate a particle set.
Definition of physical constants:
real(kind=dp), parameter, public bohr
logical function, public qmmm_ff_precond_only_qm(id1, id2, id3, id4, is_link)
This function handles the atom names and modifies the "_QM_" prefix, in order to find the parameters ...
routines for handling splines_types
subroutine, public spline_data_p_release(spl_p)
releases spline_data_p
subroutine, public spline_env_release(spline_env)
releases spline_env
subroutine, public spline_data_p_retain(spl_p)
retains spline_data_p_type
Utilities for string manipulations.
subroutine, public integer_to_string(inumber, string)
Converts an integer number to a string. The WRITE statement will return an error message,...
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
to build arrays of pointers