86#include "./base/base_uses.f90"
90 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'force_fields_all'
93 LOGICAL,
PARAMETER :: debug_this_module = .false.
134 INTEGER,
INTENT(IN) :: iw
136 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_bond'
138 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
140 INTEGER :: atm_a, atm_b, counter, first, handle2, &
141 i, j, k, last, natom, nbond
142 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
143 INTEGER,
POINTER :: map_bond_kind(:)
147 TYPE(
bond_type),
DIMENSION(:),
POINTER :: bond_list
151 CALL timeset(routinen, handle2)
154 WRITE (unit=iw, fmt=
"(/,T2,A)") &
155 "FORCEFIELD| Checking for unique bond terms"
158 DO i = 1,
SIZE(molecule_kind_set)
159 molecule_kind => molecule_kind_set(i)
161 molecule_list=molecule_list, &
163 nbond=nbond, bond_list=bond_list)
164 molecule => molecule_set(molecule_list(1))
165 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
167 ALLOCATE (map_bond_kind(nbond))
176 atm_a = bond_list(j)%a
177 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
180 atm_b = bond_list(j)%b
181 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
186 atm_a = bond_list(k)%a
187 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
190 atm_b = bond_list(k)%b
191 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
194 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
195 ((name_atm_b) == (name_atm_b2))) .OR. &
196 (((name_atm_a) == (name_atm_b2)) .AND. &
197 ((name_atm_b) == (name_atm_a2))))
THEN
199 map_bond_kind(j) = map_bond_kind(k)
203 IF (.NOT. found)
THEN
204 counter = counter + 1
205 map_bond_kind(j) = counter
209 NULLIFY (bond_kind_set)
212 bond_list(j)%bond_kind => bond_kind_set(map_bond_kind(j))
215 bond_kind_set=bond_kind_set, bond_list=bond_list)
216 DEALLOCATE (map_bond_kind)
219 CALL timestop(handle2)
237 INTEGER,
INTENT(IN) :: iw
239 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_bend'
241 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
242 name_atm_b2, name_atm_c, name_atm_c2
243 INTEGER :: atm_a, atm_b, atm_c, counter, first, &
244 handle2, i, j, k, last, natom, nbend
245 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
246 INTEGER,
POINTER :: map_bend_kind(:)
250 TYPE(
bend_type),
DIMENSION(:),
POINTER :: bend_list
254 CALL timeset(routinen, handle2)
257 WRITE (unit=iw, fmt=
"(/,T2,A)") &
258 "FORCEFIELD| Checking for unique bend terms"
261 DO i = 1,
SIZE(molecule_kind_set)
262 molecule_kind => molecule_kind_set(i)
264 molecule_list=molecule_list, &
266 nbend=nbend, bend_list=bend_list)
267 molecule => molecule_set(molecule_list(1))
268 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
270 ALLOCATE (map_bend_kind(nbend))
279 atm_a = bend_list(j)%a
280 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
283 atm_b = bend_list(j)%b
284 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
287 atm_c = bend_list(j)%c
288 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
293 atm_a = bend_list(k)%a
294 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
297 atm_b = bend_list(k)%b
298 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
301 atm_c = bend_list(k)%c
302 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
305 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
306 ((name_atm_b) == (name_atm_b2)) .AND. &
307 ((name_atm_c) == (name_atm_c2))) .OR. &
308 (((name_atm_a) == (name_atm_c2)) .AND. &
309 ((name_atm_b) == (name_atm_b2)) .AND. &
310 ((name_atm_c) == (name_atm_a2))))
THEN
312 map_bend_kind(j) = map_bend_kind(k)
316 IF (.NOT. found)
THEN
317 counter = counter + 1
318 map_bend_kind(j) = counter
322 NULLIFY (bend_kind_set)
325 bend_list(j)%bend_kind => bend_kind_set(map_bend_kind(j))
328 bend_kind_set=bend_kind_set, bend_list=bend_list)
329 DEALLOCATE (map_bend_kind)
333 CALL timestop(handle2)
349 INTEGER,
INTENT(IN) :: iw
351 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_ub'
353 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
354 name_atm_b2, name_atm_c, name_atm_c2
355 INTEGER :: atm_a, atm_b, atm_c, counter, first, &
356 handle2, i, j, k, last, natom, nub
357 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
358 INTEGER,
POINTER :: map_ub_kind(:)
363 TYPE(
ub_kind_type),
DIMENSION(:),
POINTER :: ub_kind_set
364 TYPE(
ub_type),
DIMENSION(:),
POINTER :: ub_list
366 CALL timeset(routinen, handle2)
369 WRITE (unit=iw, fmt=
"(/,T2,A)") &
370 "FORCEFIELD| Checking for unique Urey-Bradley terms"
373 DO i = 1,
SIZE(molecule_kind_set)
374 molecule_kind => molecule_kind_set(i)
376 molecule_list=molecule_list, &
378 nub=nub, ub_list=ub_list)
379 molecule => molecule_set(molecule_list(1))
380 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
382 ALLOCATE (map_ub_kind(nub))
386 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
390 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
394 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
400 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
404 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
408 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
411 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
412 ((name_atm_b) == (name_atm_b2)) .AND. &
413 ((name_atm_c) == (name_atm_c2))) .OR. &
414 (((name_atm_a) == (name_atm_c2)) .AND. &
415 ((name_atm_b) == (name_atm_b2)) .AND. &
416 ((name_atm_c) == (name_atm_a2))))
THEN
418 map_ub_kind(j) = map_ub_kind(k)
422 IF (.NOT. found)
THEN
423 counter = counter + 1
424 map_ub_kind(j) = counter
429 ub_list(j)%ub_kind => ub_kind_set(map_ub_kind(j))
432 ub_kind_set=ub_kind_set, ub_list=ub_list)
433 DEALLOCATE (map_ub_kind)
436 CALL timestop(handle2)
454 INTEGER,
INTENT(IN) :: iw
456 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_tors'
458 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
459 name_atm_b2, name_atm_c, name_atm_c2, &
460 name_atm_d, name_atm_d2
461 INTEGER :: atm_a, atm_b, atm_c, atm_d, counter, &
462 first, handle2, i, j, k, last, natom, &
464 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
465 INTEGER,
POINTER :: map_torsion_kind(:)
466 LOGICAL :: chk_reverse, found
471 TYPE(
torsion_type),
DIMENSION(:),
POINTER :: torsion_list
473 CALL timeset(routinen, handle2)
476 WRITE (unit=iw, fmt=
"(/,T2,A)") &
477 "FORCEFIELD| Checking for unique torsion terms"
484 DO i = 1,
SIZE(molecule_kind_set)
485 molecule_kind => molecule_kind_set(i)
487 molecule_list=molecule_list, &
489 ntorsion=ntorsion, torsion_list=torsion_list)
490 molecule => molecule_set(molecule_list(1))
491 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
492 IF (ntorsion > 0)
THEN
493 ALLOCATE (map_torsion_kind(ntorsion))
497 map_torsion_kind(j) = j
502 atm_a = torsion_list(j)%a
503 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
506 atm_b = torsion_list(j)%b
507 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
510 atm_c = torsion_list(j)%c
511 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
514 atm_d = torsion_list(j)%d
515 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
520 atm_a = torsion_list(k)%a
521 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
524 atm_b = torsion_list(k)%b
525 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
528 atm_c = torsion_list(k)%c
529 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
532 atm_d = torsion_list(k)%d
533 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
536 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
537 ((name_atm_b) == (name_atm_b2)) .AND. &
538 ((name_atm_c) == (name_atm_c2)) .AND. &
539 ((name_atm_d) == (name_atm_d2))) .OR. &
541 ((name_atm_a) == (name_atm_d2)) .AND. &
542 ((name_atm_b) == (name_atm_c2)) .AND. &
543 ((name_atm_c) == (name_atm_b2)) .AND. &
544 ((name_atm_d) == (name_atm_a2))))
THEN
546 map_torsion_kind(j) = map_torsion_kind(k)
550 IF (.NOT. found)
THEN
551 counter = counter + 1
552 map_torsion_kind(j) = counter
556 NULLIFY (torsion_kind_set)
559 torsion_list(j)%torsion_kind => torsion_kind_set(map_torsion_kind(j))
562 torsion_kind_set=torsion_kind_set, torsion_list=torsion_list)
563 DEALLOCATE (map_torsion_kind)
567 CALL timestop(handle2)
585 INTEGER,
INTENT(IN) :: iw
587 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_impr'
589 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
590 name_atm_b2, name_atm_c, name_atm_c2, &
591 name_atm_d, name_atm_d2
592 INTEGER :: atm_a, atm_b, atm_c, atm_d, counter, &
593 first, handle2, i, j, k, last, natom, &
595 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
596 INTEGER,
POINTER :: map_impr_kind(:)
600 TYPE(
impr_type),
DIMENSION(:),
POINTER :: impr_list
604 CALL timeset(routinen, handle2)
607 WRITE (unit=iw, fmt=
"(/,T2,A)") &
608 "FORCEFIELD| Checking for unique improper terms"
611 DO i = 1,
SIZE(molecule_kind_set)
612 molecule_kind => molecule_kind_set(i)
614 molecule_list=molecule_list, &
616 nimpr=nimpr, impr_list=impr_list)
617 molecule => molecule_set(molecule_list(1))
619 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
622 ALLOCATE (map_impr_kind(nimpr))
631 atm_a = impr_list(j)%a
632 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
635 atm_b = impr_list(j)%b
636 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
639 atm_c = impr_list(j)%c
640 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
643 atm_d = impr_list(j)%d
644 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
649 atm_a = impr_list(k)%a
650 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
653 atm_b = impr_list(k)%b
654 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
657 atm_c = impr_list(k)%c
658 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
661 atm_d = impr_list(k)%d
662 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
665 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
666 ((name_atm_b) == (name_atm_b2)) .AND. &
667 ((name_atm_c) == (name_atm_c2)) .AND. &
668 ((name_atm_d) == (name_atm_d2))) .OR. &
669 (((name_atm_a) == (name_atm_a2)) .AND. &
670 ((name_atm_b) == (name_atm_b2)) .AND. &
671 ((name_atm_c) == (name_atm_d2)) .AND. &
672 ((name_atm_d) == (name_atm_c2))))
THEN
674 map_impr_kind(j) = map_impr_kind(k)
678 IF (.NOT. found)
THEN
679 counter = counter + 1
680 map_impr_kind(j) = counter
684 NULLIFY (impr_kind_set)
687 impr_list(j)%impr_kind => impr_kind_set(map_impr_kind(j))
690 impr_kind_set=impr_kind_set, impr_list=impr_list)
691 DEALLOCATE (map_impr_kind)
694 CALL timestop(handle2)
714 INTEGER,
INTENT(IN) :: iw
716 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_unique_opbend'
718 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a2, name_atm_b, &
719 name_atm_b2, name_atm_c, name_atm_c2, &
720 name_atm_d, name_atm_d2
721 INTEGER :: atm_a, atm_b, atm_c, atm_d, counter, &
722 first, handle2, i, j, k, last, natom, &
724 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
725 INTEGER,
POINTER :: map_opbend_kind(:)
731 TYPE(
opbend_type),
DIMENSION(:),
POINTER :: opbend_list
733 CALL timeset(routinen, handle2)
736 WRITE (unit=iw, fmt=
"(/,T2,A)") &
737 "FORCEFIELD| Checking for unique out-of-plane bend terms"
740 DO i = 1,
SIZE(molecule_kind_set)
741 molecule_kind => molecule_kind_set(i)
743 molecule_list=molecule_list, &
745 nopbend=nopbend, opbend_list=opbend_list)
746 molecule => molecule_set(molecule_list(1))
747 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
748 IF (nopbend > 0)
THEN
749 ALLOCATE (map_opbend_kind(nopbend))
753 map_opbend_kind(j) = j
758 atm_a = opbend_list(j)%a
759 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
762 atm_b = opbend_list(j)%b
763 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
766 atm_c = opbend_list(j)%c
767 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
770 atm_d = opbend_list(j)%d
771 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
776 atm_a = opbend_list(k)%a
777 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
780 atm_b = opbend_list(k)%b
781 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
784 atm_c = opbend_list(k)%c
785 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
788 atm_d = opbend_list(k)%d
789 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
792 IF ((((name_atm_a) == (name_atm_a2)) .AND. &
793 ((name_atm_b) == (name_atm_b2)) .AND. &
794 ((name_atm_c) == (name_atm_c2)) .AND. &
795 ((name_atm_d) == (name_atm_d2))) .OR. &
796 (((name_atm_a) == (name_atm_a2)) .AND. &
797 ((name_atm_b) == (name_atm_c2)) .AND. &
798 ((name_atm_c) == (name_atm_b2)) .AND. &
799 ((name_atm_d) == (name_atm_d2))))
THEN
801 map_opbend_kind(j) = map_opbend_kind(k)
805 IF (.NOT. found)
THEN
806 counter = counter + 1
807 map_opbend_kind(j) = counter
811 NULLIFY (opbend_kind_set)
814 opbend_list(j)%opbend_kind => opbend_kind_set(map_opbend_kind(j))
817 opbend_kind_set=opbend_kind_set, opbend_list=opbend_list)
818 DEALLOCATE (map_opbend_kind)
821 CALL timestop(handle2)
839 chm_info, inp_info, gro_info, amb_info, iw)
845 CHARACTER(LEN=default_string_length), &
846 DIMENSION(:),
POINTER :: ainfo
851 INTEGER,
INTENT(IN) :: iw
853 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_bond'
855 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_b
856 INTEGER :: atm_a, atm_b, first, handle2, i, itype, &
857 j, k, last, natom, nbond
858 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
859 LOGICAL :: found, only_qm
861 TYPE(
bond_type),
DIMENSION(:),
POINTER :: bond_list
865 CALL timeset(routinen, handle2)
868 WRITE (unit=iw, fmt=
"(/,T2,A)") &
869 "FORCEFIELD| Checking for bond terms"
872 DO i = 1,
SIZE(molecule_kind_set)
873 molecule_kind => molecule_kind_set(i)
875 molecule_list=molecule_list, &
877 nbond=nbond, bond_list=bond_list)
878 molecule => molecule_set(molecule_list(1))
879 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
881 atm_a = bond_list(j)%a
882 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
885 atm_b = bond_list(j)%b
886 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
895 IF (
ASSOCIATED(gro_info%bond_k))
THEN
896 k =
SIZE(gro_info%bond_k)
897 itype = bond_list(j)%itype
899 bond_list(j)%bond_kind%k(1) = gro_info%bond_k(itype)
900 bond_list(j)%bond_kind%r0 = gro_info%bond_r0(itype)
903 bond_list(j)%bond_kind%k(1) = gro_info%solvent_k(itype)
904 bond_list(j)%bond_kind%r0 = gro_info%solvent_r0(itype)
906 bond_list(j)%bond_kind%id_type = gro_info%ff_gromos_type
907 bond_list(j)%id_type = gro_info%ff_gromos_type
912 IF (
ASSOCIATED(chm_info%bond_a))
THEN
913 DO k = 1,
SIZE(chm_info%bond_a)
914 IF ((((chm_info%bond_a(k)) == (name_atm_a)) .AND. &
915 ((chm_info%bond_b(k)) == (name_atm_b))) .OR. &
916 (((chm_info%bond_a(k)) == (name_atm_b)) .AND. &
917 ((chm_info%bond_b(k)) == (name_atm_a))))
THEN
919 bond_list(j)%bond_kind%k(1) = chm_info%bond_k(k)
920 bond_list(j)%bond_kind%r0 = chm_info%bond_r0(k)
921 CALL issue_duplications(found,
"Bond", name_atm_a, name_atm_b)
929 IF (
ASSOCIATED(amb_info%bond_a))
THEN
930 DO k = 1,
SIZE(amb_info%bond_a)
931 IF ((((amb_info%bond_a(k)) == (name_atm_a)) .AND. &
932 ((amb_info%bond_b(k)) == (name_atm_b))) .OR. &
933 (((amb_info%bond_a(k)) == (name_atm_b)) .AND. &
934 ((amb_info%bond_b(k)) == (name_atm_a))))
THEN
936 bond_list(j)%bond_kind%k(1) = amb_info%bond_k(k)
937 bond_list(j)%bond_kind%r0 = amb_info%bond_r0(k)
938 CALL issue_duplications(found,
"Bond", name_atm_a, name_atm_b)
946 IF (
ASSOCIATED(inp_info%bond_a))
THEN
947 DO k = 1,
SIZE(inp_info%bond_a)
948 IF ((((inp_info%bond_a(k)) == (name_atm_a)) .AND. &
949 ((inp_info%bond_b(k)) == (name_atm_b))) .OR. &
950 (((inp_info%bond_a(k)) == (name_atm_b)) .AND. &
951 ((inp_info%bond_b(k)) == (name_atm_a))))
THEN
952 bond_list(j)%bond_kind%id_type = inp_info%bond_kind(k)
953 bond_list(j)%bond_kind%k(:) = inp_info%bond_k(:, k)
954 bond_list(j)%bond_kind%r0 = inp_info%bond_r0(k)
955 bond_list(j)%bond_kind%cs = inp_info%bond_cs(k)
956 CALL issue_duplications(found,
"Bond", name_atm_a, name_atm_b)
963 IF (.NOT. found)
CALL store_ff_missing_par(atm1=trim(name_atm_a), &
964 atm2=trim(name_atm_b), &
980 CALL timestop(handle2)
998 chm_info, inp_info, gro_info, amb_info, iw)
1004 CHARACTER(LEN=default_string_length), &
1005 DIMENSION(:),
POINTER :: ainfo
1010 INTEGER,
INTENT(IN) :: iw
1012 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_bend'
1014 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_b, name_atm_c
1015 INTEGER :: atm_a, atm_b, atm_c, first, handle2, i, &
1016 itype, j, k, l, last, natom, nbend
1017 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
1018 LOGICAL :: found, only_qm
1020 TYPE(
bend_type),
DIMENSION(:),
POINTER :: bend_list
1024 CALL timeset(routinen, handle2)
1027 WRITE (unit=iw, fmt=
"(/,T2,A)") &
1028 "FORCEFIELD| Checking for bend terms"
1031 DO i = 1,
SIZE(molecule_kind_set)
1032 molecule_kind => molecule_kind_set(i)
1034 molecule_list=molecule_list, &
1036 nbend=nbend, bend_list=bend_list)
1037 molecule => molecule_set(molecule_list(1))
1038 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
1040 atm_a = bend_list(j)%a
1041 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
1044 atm_b = bend_list(j)%b
1045 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
1048 atm_c = bend_list(j)%c
1049 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
1059 IF (
ASSOCIATED(gro_info%bend_k))
THEN
1060 k =
SIZE(gro_info%bend_k)
1061 itype = bend_list(j)%itype
1063 bend_list(j)%bend_kind%k = gro_info%bend_k(itype)
1064 bend_list(j)%bend_kind%theta0 = gro_info%bend_theta0(itype)
1066 bend_list(j)%bend_kind%k = gro_info%bend_k(itype/k)
1067 bend_list(j)%bend_kind%theta0 = gro_info%bend_theta0(itype/k)
1069 bend_list(j)%bend_kind%id_type = gro_info%ff_gromos_type
1070 bend_list(j)%id_type = gro_info%ff_gromos_type
1075 IF (
ASSOCIATED(chm_info%bend_a))
THEN
1076 DO k = 1,
SIZE(chm_info%bend_a)
1077 IF ((((chm_info%bend_a(k)) == (name_atm_a)) .AND. &
1078 ((chm_info%bend_b(k)) == (name_atm_b)) .AND. &
1079 ((chm_info%bend_c(k)) == (name_atm_c))) .OR. &
1080 (((chm_info%bend_a(k)) == (name_atm_c)) .AND. &
1081 ((chm_info%bend_b(k)) == (name_atm_b)) .AND. &
1082 ((chm_info%bend_c(k)) == (name_atm_a))))
THEN
1084 bend_list(j)%bend_kind%k = chm_info%bend_k(k)
1085 bend_list(j)%bend_kind%theta0 = chm_info%bend_theta0(k)
1086 CALL issue_duplications(found,
"Bend", name_atm_a, name_atm_b, &
1095 IF (
ASSOCIATED(amb_info%bend_a))
THEN
1096 DO k = 1,
SIZE(amb_info%bend_a)
1097 IF ((((amb_info%bend_a(k)) == (name_atm_a)) .AND. &
1098 ((amb_info%bend_b(k)) == (name_atm_b)) .AND. &
1099 ((amb_info%bend_c(k)) == (name_atm_c))) .OR. &
1100 (((amb_info%bend_a(k)) == (name_atm_c)) .AND. &
1101 ((amb_info%bend_b(k)) == (name_atm_b)) .AND. &
1102 ((amb_info%bend_c(k)) == (name_atm_a))))
THEN
1104 bend_list(j)%bend_kind%k = amb_info%bend_k(k)
1105 bend_list(j)%bend_kind%theta0 = amb_info%bend_theta0(k)
1106 CALL issue_duplications(found,
"Bend", name_atm_a, name_atm_b, &
1115 IF (
ASSOCIATED(inp_info%bend_a))
THEN
1116 DO k = 1,
SIZE(inp_info%bend_a)
1117 IF ((((inp_info%bend_a(k)) == (name_atm_a)) .AND. &
1118 ((inp_info%bend_b(k)) == (name_atm_b)) .AND. &
1119 ((inp_info%bend_c(k)) == (name_atm_c))) .OR. &
1120 (((inp_info%bend_a(k)) == (name_atm_c)) .AND. &
1121 ((inp_info%bend_b(k)) == (name_atm_b)) .AND. &
1122 ((inp_info%bend_c(k)) == (name_atm_a))))
THEN
1123 bend_list(j)%bend_kind%id_type = inp_info%bend_kind(k)
1124 bend_list(j)%bend_kind%k = inp_info%bend_k(k)
1125 bend_list(j)%bend_kind%theta0 = inp_info%bend_theta0(k)
1126 bend_list(j)%bend_kind%cb = inp_info%bend_cb(k)
1127 bend_list(j)%bend_kind%r012 = inp_info%bend_r012(k)
1128 bend_list(j)%bend_kind%r032 = inp_info%bend_r032(k)
1129 bend_list(j)%bend_kind%kbs12 = inp_info%bend_kbs12(k)
1130 bend_list(j)%bend_kind%kbs32 = inp_info%bend_kbs32(k)
1131 bend_list(j)%bend_kind%kss = inp_info%bend_kss(k)
1132 bend_list(j)%bend_kind%legendre%order = inp_info%bend_legendre(k)%order
1133 IF (bend_list(j)%bend_kind%legendre%order /= 0)
THEN
1134 IF (
ASSOCIATED(bend_list(j)%bend_kind%legendre%coeffs))
THEN
1135 DEALLOCATE (bend_list(j)%bend_kind%legendre%coeffs)
1137 ALLOCATE (bend_list(j)%bend_kind%legendre%coeffs(bend_list(j)%bend_kind%legendre%order))
1138 DO l = 1, bend_list(j)%bend_kind%legendre%order
1139 bend_list(j)%bend_kind%legendre%coeffs(l) = inp_info%bend_legendre(k)%coeffs(l)
1142 CALL issue_duplications(found,
"Bend", name_atm_a, name_atm_b, &
1150 IF (.NOT. found)
CALL store_ff_missing_par(atm1=trim(name_atm_a), &
1151 atm2=trim(name_atm_b), &
1152 atm3=trim(name_atm_c), &
1154 type_name=
"Angle", &
1163 bend_list=bend_list)
1165 CALL timestop(handle2)
1180 Ainfo, chm_info, inp_info, iw)
1185 CHARACTER(LEN=default_string_length), &
1186 DIMENSION(:),
POINTER :: ainfo
1191 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_ub'
1193 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_b, name_atm_c
1194 INTEGER :: atm_a, atm_b, atm_c, first, handle2, i, &
1195 j, k, last, natom, nub
1196 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
1197 LOGICAL :: found, only_qm
1201 TYPE(
ub_type),
DIMENSION(:),
POINTER :: ub_list
1203 CALL timeset(routinen, handle2)
1206 WRITE (unit=iw, fmt=
"(/,T2,A)") &
1207 "FORCEFIELD| Checking for Urey-Bradley (UB) terms"
1210 DO i = 1,
SIZE(molecule_kind_set)
1211 molecule_kind => molecule_kind_set(i)
1213 molecule_list=molecule_list, &
1215 nub=nub, ub_list=ub_list)
1216 molecule => molecule_set(molecule_list(1))
1217 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
1219 atm_a = ub_list(j)%a
1220 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
1223 atm_b = ub_list(j)%b
1224 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
1227 atm_c = ub_list(j)%c
1228 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
1241 IF (
ASSOCIATED(chm_info%ub_a))
THEN
1242 DO k = 1,
SIZE(chm_info%ub_a)
1243 IF ((((chm_info%ub_a(k)) == (name_atm_a)) .AND. &
1244 ((chm_info%ub_b(k)) == (name_atm_b)) .AND. &
1245 ((chm_info%ub_c(k)) == (name_atm_c))) .OR. &
1246 (((chm_info%ub_a(k)) == (name_atm_c)) .AND. &
1247 ((chm_info%ub_b(k)) == (name_atm_b)) .AND. &
1248 ((chm_info%ub_c(k)) == (name_atm_a))))
THEN
1250 ub_list(j)%ub_kind%k(1) = chm_info%ub_k(k)
1251 ub_list(j)%ub_kind%r0 = chm_info%ub_r0(k)
1253 WRITE (unit=iw, fmt=
"(T2,A)") &
1254 "FORCEFIELD| Found Urey-Bradley term (CHARMM) for the atomic kinds "// &
1255 trim(name_atm_a)//
", "//trim(name_atm_b)//
" and "//trim(name_atm_c)
1257 CALL issue_duplications(found,
"Urey-Bradley", name_atm_a, &
1258 name_atm_b, name_atm_c)
1269 IF (
ASSOCIATED(inp_info%ub_a))
THEN
1270 DO k = 1,
SIZE(inp_info%ub_a)
1271 IF ((((inp_info%ub_a(k)) == (name_atm_a)) .AND. &
1272 ((inp_info%ub_b(k)) == (name_atm_b)) .AND. &
1273 ((inp_info%ub_c(k)) == (name_atm_c))) .OR. &
1274 (((inp_info%ub_a(k)) == (name_atm_c)) .AND. &
1275 ((inp_info%ub_b(k)) == (name_atm_b)) .AND. &
1276 ((inp_info%ub_c(k)) == (name_atm_a))))
THEN
1277 ub_list(j)%ub_kind%id_type = inp_info%ub_kind(k)
1278 ub_list(j)%ub_kind%k(:) = inp_info%ub_k(:, k)
1279 ub_list(j)%ub_kind%r0 = inp_info%ub_r0(k)
1281 WRITE (unit=iw, fmt=
"(T2,A)") &
1282 "FORCEFIELD| Found Urey-Bradley term (input) for the atomic kinds "// &
1283 trim(name_atm_a)//
", "//trim(name_atm_b)//
" and "//trim(name_atm_c)
1285 CALL issue_duplications(found,
"Urey-Bradley", name_atm_a, &
1286 name_atm_b, name_atm_c)
1293 IF (.NOT. found)
THEN
1294 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
1295 atm2=trim(name_atm_b), &
1296 atm3=trim(name_atm_c), &
1297 type_name=
"Urey-Bradley", &
1301 ub_list(j)%ub_kind%k = 0.0_dp
1302 ub_list(j)%ub_kind%r0 = 0.0_dp
1317 CALL timestop(handle2)
1334 Ainfo, chm_info, inp_info, gro_info, amb_info, iw)
1339 CHARACTER(LEN=default_string_length), &
1340 DIMENSION(:),
POINTER :: ainfo
1345 INTEGER,
INTENT(IN) :: iw
1347 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_tors'
1349 CHARACTER(LEN=default_string_length) :: ldum, molecule_name, name_atm_a, &
1350 name_atm_b, name_atm_c, name_atm_d
1351 INTEGER :: atm_a, atm_b, atm_c, atm_d, first, &
1352 handle2, i, imul, itype, j, k, k_end, &
1353 k_start, last, natom, ntorsion, &
1355 INTEGER,
DIMENSION(4) :: glob_atm_id
1356 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
1357 LOGICAL :: found, only_qm
1361 TYPE(
torsion_type),
DIMENSION(:),
POINTER :: torsion_list
1363 CALL timeset(routinen, handle2)
1366 WRITE (unit=iw, fmt=
"(/,T2,A)") &
1367 "FORCEFIELD| Checking for torsion terms"
1370 DO i = 1,
SIZE(molecule_kind_set)
1371 molecule_kind => molecule_kind_set(i)
1373 molecule_list=molecule_list, &
1374 name=molecule_name, &
1376 ntorsion=ntorsion, &
1377 torsion_list=torsion_list)
1378 molecule => molecule_set(molecule_list(1))
1383 IF (torsion_list(j)%torsion_kind%id_type ==
do_ff_undef)
THEN
1384 atm_a = torsion_list(j)%a
1385 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
1388 atm_b = torsion_list(j)%b
1389 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
1392 atm_c = torsion_list(j)%c
1393 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
1396 atm_d = torsion_list(j)%d
1397 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
1408 IF (
ASSOCIATED(gro_info%torsion_k))
THEN
1409 k =
SIZE(gro_info%torsion_k)
1410 itype = torsion_list(j)%itype
1412 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, 1)
1413 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, 1)
1414 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, 1)
1415 torsion_list(j)%torsion_kind%nmul = 1
1416 torsion_list(j)%torsion_kind%m(1) = gro_info%torsion_m(itype)
1417 torsion_list(j)%torsion_kind%k(1) = gro_info%torsion_k(itype)
1418 torsion_list(j)%torsion_kind%phi0(1) = gro_info%torsion_phi0(itype)
1420 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, 1)
1421 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, 1)
1422 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, 1)
1423 torsion_list(j)%torsion_kind%nmul = 1
1424 torsion_list(j)%torsion_kind%m(1) = gro_info%torsion_m(itype/k)
1425 torsion_list(j)%torsion_kind%k(1) = gro_info%torsion_k(itype/k)
1426 torsion_list(j)%torsion_kind%phi0(1) = gro_info%torsion_phi0(itype/k)
1428 torsion_list(j)%torsion_kind%id_type = gro_info%ff_gromos_type
1429 torsion_list(j)%id_type = gro_info%ff_gromos_type
1431 imul = torsion_list(j)%torsion_kind%nmul
1435 IF (
ASSOCIATED(chm_info%torsion_a))
THEN
1436 DO k = 1,
SIZE(chm_info%torsion_a)
1437 IF ((((chm_info%torsion_a(k)) == (name_atm_a)) .AND. &
1438 ((chm_info%torsion_b(k)) == (name_atm_b)) .AND. &
1439 ((chm_info%torsion_c(k)) == (name_atm_c)) .AND. &
1440 ((chm_info%torsion_d(k)) == (name_atm_d))) .OR. &
1441 (((chm_info%torsion_a(k)) == (name_atm_d)) .AND. &
1442 ((chm_info%torsion_b(k)) == (name_atm_c)) .AND. &
1443 ((chm_info%torsion_c(k)) == (name_atm_b)) .AND. &
1444 ((chm_info%torsion_d(k)) == (name_atm_a))))
THEN
1445 imul = torsion_list(j)%torsion_kind%nmul + 1
1446 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
1447 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
1448 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
1450 torsion_list(j)%torsion_kind%k(imul) = chm_info%torsion_k(k)
1451 torsion_list(j)%torsion_kind%m(imul) = chm_info%torsion_m(k)
1452 torsion_list(j)%torsion_kind%phi0(imul) = chm_info%torsion_phi0(k)
1453 torsion_list(j)%torsion_kind%nmul = imul
1458 IF (.NOT. found)
THEN
1459 DO k = 1,
SIZE(chm_info%torsion_a)
1460 IF ((((chm_info%torsion_a(k)) == (
"X")) .AND. &
1461 ((chm_info%torsion_b(k)) == (name_atm_b)) .AND. &
1462 ((chm_info%torsion_c(k)) == (name_atm_c)) .AND. &
1463 ((chm_info%torsion_d(k)) == (
"X"))) .OR. &
1464 (((chm_info%torsion_a(k)) == (
"X")) .AND. &
1465 ((chm_info%torsion_b(k)) == (name_atm_c)) .AND. &
1466 ((chm_info%torsion_c(k)) == (name_atm_b)) .AND. &
1467 ((chm_info%torsion_d(k)) == (
"X"))))
THEN
1468 imul = torsion_list(j)%torsion_kind%nmul + 1
1469 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
1470 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
1471 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
1473 torsion_list(j)%torsion_kind%k(imul) = chm_info%torsion_k(k)
1474 torsion_list(j)%torsion_kind%m(imul) = chm_info%torsion_m(k)
1475 torsion_list(j)%torsion_kind%phi0(imul) = chm_info%torsion_phi0(k)
1476 torsion_list(j)%torsion_kind%nmul = imul
1486 IF (
ASSOCIATED(amb_info%torsion_a))
THEN
1488 glob_atm_id(1) = atm_a + first - 1
1489 glob_atm_id(2) = atm_b + first - 1
1490 glob_atm_id(3) = atm_c + first - 1
1491 glob_atm_id(4) = atm_d + first - 1
1496 k_start = bsearch_leftmost_2d(amb_info%raw_torsion_id, glob_atm_id(1))
1497 k_end = ubound(amb_info%raw_torsion_id, dim=2)
1500 IF (k_start /= 0)
THEN
1502 DO k = k_start, k_end
1503 IF (glob_atm_id(1) < amb_info%raw_torsion_id(1, k))
EXIT
1504 IF (any((glob_atm_id - amb_info%raw_torsion_id(1:4, k)) /= 0)) cycle
1506 raw_parm_id = amb_info%raw_torsion_id(5, k)
1507 imul = torsion_list(j)%torsion_kind%nmul + 1
1508 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
1509 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
1510 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
1511 torsion_list(j)%torsion_kind%id_type =
do_ff_amber
1512 torsion_list(j)%torsion_kind%k(imul) = amb_info%raw_torsion_k(raw_parm_id)
1513 torsion_list(j)%torsion_kind%m(imul) = nint(amb_info%raw_torsion_m(raw_parm_id))
1514 torsion_list(j)%torsion_kind%phi0(imul) = amb_info%raw_torsion_phi0(raw_parm_id)
1515 torsion_list(j)%torsion_kind%nmul = imul
1524 IF (
ASSOCIATED(inp_info%torsion_a))
THEN
1525 DO k = 1,
SIZE(inp_info%torsion_a)
1526 IF ((((inp_info%torsion_a(k)) == (name_atm_a)) .AND. &
1527 ((inp_info%torsion_b(k)) == (name_atm_b)) .AND. &
1528 ((inp_info%torsion_c(k)) == (name_atm_c)) .AND. &
1529 ((inp_info%torsion_d(k)) == (name_atm_d))) .OR. &
1530 (((inp_info%torsion_a(k)) == (name_atm_d)) .AND. &
1531 ((inp_info%torsion_b(k)) == (name_atm_c)) .AND. &
1532 ((inp_info%torsion_c(k)) == (name_atm_b)) .AND. &
1533 ((inp_info%torsion_d(k)) == (name_atm_a))))
THEN
1534 imul = torsion_list(j)%torsion_kind%nmul + 1
1535 CALL reallocate(torsion_list(j)%torsion_kind%k, 1, imul)
1536 CALL reallocate(torsion_list(j)%torsion_kind%m, 1, imul)
1537 CALL reallocate(torsion_list(j)%torsion_kind%phi0, 1, imul)
1538 torsion_list(j)%torsion_kind%id_type = inp_info%torsion_kind(k)
1539 torsion_list(j)%torsion_kind%k(imul) = inp_info%torsion_k(k)
1540 torsion_list(j)%torsion_kind%m(imul) = inp_info%torsion_m(k)
1541 torsion_list(j)%torsion_kind%phi0(imul) = inp_info%torsion_phi0(k)
1542 torsion_list(j)%torsion_kind%nmul = imul
1552 WRITE (unit=iw, fmt=
"(T2,A)") &
1553 "FORCEFIELD| No torsion term found"
1554 ELSE IF (imul == 1)
THEN
1555 WRITE (unit=iw, fmt=
"(T2,A)") &
1556 "FORCEFIELD| Found torsion term for the atomic kinds "// &
1557 trim(name_atm_a)//
", "//trim(name_atm_b)// &
1558 ", "//trim(name_atm_c)// &
1559 " and "//trim(name_atm_d)
1561 WRITE (unit=iw, fmt=
"(T2,A)") &
1562 "FORCEFIELD| Found multiple ("//trim(ldum)// &
1563 ") torsion terms for the atomic kinds "// &
1564 trim(name_atm_a)//
", "//trim(name_atm_b)// &
1565 ", "//trim(name_atm_c)// &
1566 " and "//trim(name_atm_d)
1570 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
1571 atm2=trim(name_atm_b), &
1572 atm3=trim(name_atm_c), &
1573 atm4=trim(name_atm_d), &
1574 type_name=
"Torsion", &
1576 torsion_list(j)%torsion_kind%id_type =
do_ff_undef
1583 WRITE (unit=iw, fmt=
"(T2,A,I0,4(A,I0))") &
1584 "FORCEFIELD| Torsion ", j,
" for molecule kind "//trim(molecule_name)// &
1585 trim(name_atm_a)// &
1586 "-"//trim(name_atm_b)//
"-"//trim(name_atm_c)//
"-"// &
1587 trim(name_atm_d)//
" (", torsion_list(j)%a,
", ", &
1588 torsion_list(j)%b,
", ", torsion_list(j)%c,
", ", &
1591 torsion_list(j)%torsion_kind%id_type =
do_ff_undef
1600 torsion_list=torsion_list)
1604 CALL timestop(handle2)
1620 Ainfo, chm_info, inp_info, gro_info, iw)
1625 CHARACTER(LEN=default_string_length), &
1626 DIMENSION(:),
POINTER :: ainfo
1630 INTEGER,
INTENT(IN) :: iw
1632 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_impr'
1634 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_b, name_atm_c, &
1636 INTEGER :: atm_a, atm_b, atm_c, atm_d, first, &
1637 handle2, i, itype, j, k, last, natom, &
1639 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
1640 LOGICAL :: found, only_qm
1642 TYPE(
impr_type),
DIMENSION(:),
POINTER :: impr_list
1646 CALL timeset(routinen, handle2)
1649 WRITE (unit=iw, fmt=
"(/,T2,A)") &
1650 "FORCEFIELD| Checking for improper terms"
1653 DO i = 1,
SIZE(molecule_kind_set)
1655 molecule_kind => molecule_kind_set(i)
1657 molecule_list=molecule_list, &
1660 impr_list=impr_list)
1662 molecule => molecule_set(molecule_list(1))
1663 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
1666 atm_a = impr_list(j)%a
1667 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
1670 atm_b = impr_list(j)%b
1671 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
1674 atm_c = impr_list(j)%c
1675 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
1678 atm_d = impr_list(j)%d
1679 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
1690 IF (
ASSOCIATED(gro_info%impr_k))
THEN
1691 k =
SIZE(gro_info%impr_k)
1692 itype = impr_list(j)%itype
1694 impr_list(j)%impr_kind%k = gro_info%impr_k(itype)
1695 impr_list(j)%impr_kind%phi0 = gro_info%impr_phi0(itype)
1697 impr_list(j)%impr_kind%k = gro_info%impr_k(itype)
1698 impr_list(j)%impr_kind%phi0 = gro_info%impr_phi0(itype)
1701 impr_list(j)%impr_kind%id_type = gro_info%ff_gromos_type
1702 impr_list(j)%id_type = gro_info%ff_gromos_type
1706 IF (
ASSOCIATED(chm_info%impr_a))
THEN
1707 DO k = 1,
SIZE(chm_info%impr_a)
1708 IF ((((chm_info%impr_a(k)) == (name_atm_a)) .AND. &
1709 ((chm_info%impr_b(k)) == (name_atm_b)) .AND. &
1710 ((chm_info%impr_c(k)) == (name_atm_c)) .AND. &
1711 ((chm_info%impr_d(k)) == (name_atm_d))) .OR. &
1712 (((chm_info%impr_a(k)) == (name_atm_d)) .AND. &
1713 ((chm_info%impr_b(k)) == (name_atm_c)) .AND. &
1714 ((chm_info%impr_c(k)) == (name_atm_b)) .AND. &
1715 ((chm_info%impr_d(k)) == (name_atm_a))))
THEN
1717 impr_list(j)%impr_kind%k = chm_info%impr_k(k)
1718 impr_list(j)%impr_kind%phi0 = chm_info%impr_phi0(k)
1719 CALL issue_duplications(found,
"Impropers", name_atm_a, name_atm_b, &
1720 name_atm_c, name_atm_d)
1725 IF (.NOT. found)
THEN
1726 DO k = 1,
SIZE(chm_info%impr_a)
1727 IF ((((chm_info%impr_a(k)) == (name_atm_a)) .AND. &
1728 ((chm_info%impr_b(k)) == (
"X")) .AND. &
1729 ((chm_info%impr_c(k)) == (
"X")) .AND. &
1730 ((chm_info%impr_d(k)) == (name_atm_d))) .OR. &
1731 (((chm_info%impr_a(k)) == (name_atm_d)) .AND. &
1732 ((chm_info%impr_b(k)) == (
"X")) .AND. &
1733 ((chm_info%impr_c(k)) == (
"X")) .AND. &
1734 ((chm_info%impr_d(k)) == (name_atm_a))))
THEN
1736 impr_list(j)%impr_kind%k = chm_info%impr_k(k)
1737 impr_list(j)%impr_kind%phi0 = chm_info%impr_phi0(k)
1738 CALL issue_duplications(found,
"Impropers", name_atm_a, name_atm_b, &
1739 name_atm_c, name_atm_d)
1751 IF (
ASSOCIATED(inp_info%impr_a))
THEN
1752 DO k = 1,
SIZE(inp_info%impr_a)
1753 IF (((inp_info%impr_a(k)) == (name_atm_a)) .AND. &
1754 ((inp_info%impr_b(k)) == (name_atm_b)) .AND. &
1755 ((((inp_info%impr_c(k)) == (name_atm_c)) .AND. &
1756 ((inp_info%impr_d(k)) == (name_atm_d))) .OR. &
1757 (((inp_info%impr_c(k)) == (name_atm_d)) .AND. &
1758 ((inp_info%impr_d(k)) == (name_atm_c)))))
THEN
1759 impr_list(j)%impr_kind%id_type = inp_info%impr_kind(k)
1760 impr_list(j)%impr_kind%k = inp_info%impr_k(k)
1761 IF (((inp_info%impr_c(k)) == (name_atm_c)) .AND. &
1762 ((inp_info%impr_d(k)) == (name_atm_d)))
THEN
1763 impr_list(j)%impr_kind%phi0 = inp_info%impr_phi0(k)
1765 impr_list(j)%impr_kind%phi0 = -inp_info%impr_phi0(k)
1776 CALL issue_duplications(found,
"Impropers", name_atm_a, name_atm_b, &
1777 name_atm_c, name_atm_d)
1784 IF (.NOT. found)
THEN
1785 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
1786 atm2=trim(name_atm_b), &
1787 atm3=trim(name_atm_c), &
1788 atm4=trim(name_atm_d), &
1789 type_name=
"Improper", &
1791 impr_list(j)%impr_kind%k = 0.0_dp
1792 impr_list(j)%impr_kind%phi0 = 0.0_dp
1801 WRITE (unit=iw, fmt=
"(T2,A)") &
1802 "FORCEFIELD| Found improper term for "//trim(name_atm_a)// &
1803 "-"//trim(name_atm_b)//
"-"//trim(name_atm_c)//
"-"// &
1817 CALL timestop(handle2)
1839 CHARACTER(LEN=default_string_length), &
1840 DIMENSION(:),
POINTER :: ainfo
1842 INTEGER,
INTENT(IN) :: iw
1844 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_opbend'
1846 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_b, name_atm_c, &
1848 INTEGER :: atm_a, atm_b, atm_c, atm_d, first, &
1849 handle2, i, j, k, last, natom, nopbend
1850 INTEGER,
DIMENSION(:),
POINTER :: molecule_list
1851 LOGICAL :: found, only_qm
1855 TYPE(
opbend_type),
DIMENSION(:),
POINTER :: opbend_list
1857 CALL timeset(routinen, handle2)
1860 WRITE (unit=iw, fmt=
"(/,T2,A)") &
1861 "FORCEFIELD| Checking for out-of-plane bend terms"
1864 DO i = 1,
SIZE(molecule_kind_set)
1865 molecule_kind => molecule_kind_set(i)
1867 molecule_list=molecule_list, &
1869 nopbend=nopbend, opbend_list=opbend_list)
1870 molecule => molecule_set(molecule_list(1))
1872 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
1874 atm_a = opbend_list(j)%a
1875 atomic_kind => particle_set(atm_a + first - 1)%atomic_kind
1878 atm_b = opbend_list(j)%b
1879 atomic_kind => particle_set(atm_b + first - 1)%atomic_kind
1882 atm_c = opbend_list(j)%c
1883 atomic_kind => particle_set(atm_c + first - 1)%atomic_kind
1886 atm_d = opbend_list(j)%d
1887 atomic_kind => particle_set(atm_d + first - 1)%atomic_kind
1898 IF (
ASSOCIATED(inp_info%opbend_a))
THEN
1899 DO k = 1,
SIZE(inp_info%opbend_a)
1900 IF (((inp_info%opbend_a(k)) == (name_atm_a)) .AND. &
1901 ((inp_info%opbend_d(k)) == (name_atm_d)) .AND. &
1902 ((((inp_info%opbend_c(k)) == (name_atm_c)) .AND. &
1903 ((inp_info%opbend_b(k)) == (name_atm_b))) .OR. &
1904 (((inp_info%opbend_c(k)) == (name_atm_b)) .AND. &
1905 ((inp_info%opbend_b(k)) == (name_atm_c)))))
THEN
1906 opbend_list(j)%opbend_kind%id_type = inp_info%opbend_kind(k)
1907 opbend_list(j)%opbend_kind%k = inp_info%opbend_k(k)
1908 IF (((inp_info%opbend_c(k)) == (name_atm_c)) .AND. &
1909 ((inp_info%opbend_b(k)) == (name_atm_b)))
THEN
1910 opbend_list(j)%opbend_kind%phi0 = inp_info%opbend_phi0(k)
1912 opbend_list(j)%opbend_kind%phi0 = -inp_info%opbend_phi0(k)
1922 CALL issue_duplications(found,
"Out of plane bend", name_atm_a, name_atm_b, &
1923 name_atm_c, name_atm_d)
1930 IF (.NOT. found)
THEN
1931 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
1932 atm2=trim(name_atm_b), &
1933 atm3=trim(name_atm_c), &
1934 atm4=trim(name_atm_d), &
1935 type_name=
"Out of plane bend", &
1937 opbend_list(j)%opbend_kind%k = 0.0_dp
1938 opbend_list(j)%opbend_kind%phi0 = 0.0_dp
1956 CALL timestop(handle2)
1973 my_qmmm, qmmm_env, inp_info, iw4)
1975 REAL(kind=
dp),
DIMENSION(:),
POINTER :: charges
1981 INTEGER,
INTENT(IN) :: iw4
1983 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_charges'
1985 CHARACTER(LEN=default_string_length) :: atmname
1986 INTEGER :: handle, iatom, ilink, j, nval
1987 LOGICAL :: found_p, is_link_atom, is_ok, &
1988 only_manybody, only_qm
1989 REAL(kind=
dp) :: charge, charge_tot, rval, scale_factor
1995 CALL timeset(routinen, handle)
2001 IF (
ASSOCIATED(inp_info%shell_list))
THEN
2002 cpabort(
"Array of charges is not implemented for the core-shell model")
2006 cpassert(.NOT. (
ASSOCIATED(charges)))
2007 ALLOCATE (charges(
SIZE(particle_set)))
2011 cpassert(nval ==
SIZE(charges))
2018 charges(iatom) = rval
2021 atomic_kind => particle_set(iatom)%atomic_kind
2023 fist_potential=fist_potential, &
2029 IF (charge /= -huge(0.0_dp)) &
2030 CALL cp_warn(__location__, &
2031 "The charge for atom index ("//
cp_to_string(iatom)//
") and atom name ("// &
2032 trim(atmname)//
") was already defined. The charge associated to this kind"// &
2033 " will be set to an uninitialized value and only the atom specific charge will be used! ")
2034 charge = -huge(0.0_dp)
2037 IF (
ASSOCIATED(inp_info%nonbonded))
THEN
2038 IF (
ASSOCIATED(inp_info%nonbonded%pot))
THEN
2040 only_manybody = .true.
2042 DO j = 1,
SIZE(inp_info%nonbonded%pot)
2043 IF (atmname == inp_info%nonbonded%pot(j)%pot%at1 .OR. &
2044 atmname == inp_info%nonbonded%pot(j)%pot%at2)
THEN
2045 SELECT CASE (inp_info%nonbonded%pot(j)%pot%type(1))
2050 only_manybody = .false.
2056 IF (only_manybody .AND. found_p)
THEN
2057 charges(iatom) = 0.0_dp
2063 IF (only_qm .AND. my_qmmm)
THEN
2065 scale_factor = 0.0_dp
2066 IF (is_link_atom)
THEN
2068 DO ilink = 1,
SIZE(qmmm_env%mm_link_atoms)
2069 IF (iatom == qmmm_env%mm_link_atoms(ilink))
EXIT
2071 cpassert(ilink <=
SIZE(qmmm_env%mm_link_atoms))
2072 scale_factor = qmmm_env%fist_scale_charge_link(ilink)
2074 charges(iatom) = charges(iatom)*scale_factor
2080 charge_tot = sum(charges)
2084 WRITE (unit=iw4, fmt=
"(/,T2,A,T61,F20.10)") &
2085 "FORCEFIELD| Total charge of the classical system: ", charge_tot
2088 CALL timestop(handle)
2105 Ainfo, my_qmmm, inp_info)
2109 LOGICAL,
INTENT(INOUT) :: fatal
2110 INTEGER,
INTENT(IN) :: iw, iw4
2111 CHARACTER(LEN=default_string_length), &
2112 DIMENSION(:),
POINTER :: ainfo
2113 LOGICAL,
INTENT(IN) :: my_qmmm
2116 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_charge'
2118 CHARACTER(LEN=default_string_length) :: atmname
2119 INTEGER :: handle, i, ilink, j
2120 INTEGER,
DIMENSION(:),
POINTER :: my_atom_list
2121 LOGICAL :: found, found_p, is_link_atom, is_shell, &
2122 only_manybody, only_qm
2123 REAL(kind=
dp) :: charge, charge_tot, cs_charge, &
2128 CALL timeset(routinen, handle)
2132 DO i = 1,
SIZE(atomic_kind_set)
2133 atomic_kind => atomic_kind_set(i)
2135 fist_potential=fist_potential, &
2136 atom_list=my_atom_list, &
2144 IF (charge /= -huge(0.0_dp)) found = .true.
2147 IF (
ASSOCIATED(inp_info%charge_atm))
THEN
2148 IF (iw > 0)
WRITE (unit=iw, fmt=
"(A)")
""
2149 DO j = 1,
SIZE(inp_info%charge_atm)
2150 IF (debug_this_module)
THEN
2152 WRITE (unit=iw, fmt=
"(T2,A)") &
2153 "Checking charges for the atomic kinds "// &
2154 trim(inp_info%charge_atm(j))//
" and "//trim(atmname)
2157 IF ((inp_info%charge_atm(j)) == atmname)
THEN
2158 charge = inp_info%charge(j)
2159 CALL issue_duplications(found,
"Charge", atmname)
2167 IF (
ASSOCIATED(inp_info%shell_list))
THEN
2168 DO j = 1,
SIZE(inp_info%shell_list)
2169 IF ((inp_info%shell_list(j)%atm_name) == atmname)
THEN
2171 cs_charge = inp_info%shell_list(j)%shell%charge_core + &
2172 inp_info%shell_list(j)%shell%charge_shell
2176 CALL cp_warn(__location__, &
2177 "CORE-SHELL model defined for KIND ("//trim(atmname)//
")"// &
2178 " ignoring charge definition! ")
2186 IF (
ASSOCIATED(inp_info%nonbonded))
THEN
2187 IF (
ASSOCIATED(inp_info%nonbonded%pot))
THEN
2189 only_manybody = .true.
2191 DO j = 1,
SIZE(inp_info%nonbonded%pot)
2192 IF (atmname == inp_info%nonbonded%pot(j)%pot%at1 .OR. &
2193 atmname == inp_info%nonbonded%pot(j)%pot%at2)
THEN
2194 SELECT CASE (inp_info%nonbonded%pot(j)%pot%type(1))
2200 only_manybody = .false.
2206 IF (only_manybody .AND. found_p)
THEN
2212 IF (.NOT. found)
THEN
2216 CALL store_ff_missing_par(atm1=trim(atmname), &
2218 type_name=
"Charge", &
2224 IF (only_qm .AND. my_qmmm)
THEN
2226 scale_factor = 0.0_dp
2227 IF (is_link_atom)
THEN
2231 DO ilink = 1,
SIZE(qmmm_env%mm_link_atoms)
2232 IF (any(my_atom_list == qmmm_env%mm_link_atoms(ilink)))
EXIT
2234 cpassert(ilink <=
SIZE(qmmm_env%mm_link_atoms))
2235 scale_factor = qmmm_env%fist_scale_charge_link(ilink)
2237 charge = charge*scale_factor
2245 charge_tot = charge_tot + atomic_kind%natom*cs_charge
2247 charge_tot = charge_tot + atomic_kind%natom*charge
2254 WRITE (unit=iw4, fmt=
"(/,T2,A,T61,F20.10)") &
2255 "FORCEFIELD| Total charge of the classical system: ", charge_tot
2258 CALL timestop(handle)
2272 INTEGER,
INTENT(IN) :: iw
2275 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_radius'
2277 CHARACTER(LEN=default_string_length) :: inp_kind_name, kind_name
2278 INTEGER :: handle, i, i_rep, n_rep
2280 REAL(kind=
dp) :: mm_radius
2285 CALL timeset(routinen, handle)
2290 DO i = 1,
SIZE(atomic_kind_set)
2291 atomic_kind => atomic_kind_set(i)
2293 fist_potential=fist_potential, name=kind_name)
2300 IF (iw > 0)
WRITE (unit=iw, fmt=
"(A)")
""
2304 c_val=inp_kind_name, i_rep_section=i_rep)
2307 WRITE (unit=iw, fmt=
"(T2,A)") &
2308 "FORCEFIELD| Matching atomic kinds "//trim(kind_name)// &
2309 " and "//trim(inp_kind_name)//
" for MM_RADIUS"
2311 IF (trim(kind_name) == trim(inp_kind_name))
THEN
2313 keyword_name=
"MM_RADIUS", r_val=mm_radius)
2314 CALL issue_duplications(found,
"MM_RADIUS", kind_name)
2318 CALL set_potential(potential=fist_potential, mm_radius=mm_radius)
2321 CALL timestop(handle)
2335 INTEGER,
INTENT(IN) :: iw
2338 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_pol'
2340 CHARACTER(LEN=default_string_length) :: kind_name
2341 INTEGER :: handle, i, j
2343 REAL(kind=
dp) :: apol, cpol
2347 CALL timeset(routinen, handle)
2350 WRITE (unit=iw, fmt=
"(/,T2,A)") &
2351 "FORCEFIELD| Checking for polarisable forcefield terms"
2354 DO i = 1,
SIZE(atomic_kind_set)
2355 atomic_kind => atomic_kind_set(i)
2357 fist_potential=fist_potential, &
2359 CALL get_potential(potential=fist_potential, apol=apol, cpol=cpol)
2363 IF (iw > 0)
WRITE (unit=iw, fmt=
"(A)")
""
2365 IF (
ASSOCIATED(inp_info%apol_atm))
THEN
2366 DO j = 1,
SIZE(inp_info%apol_atm)
2368 WRITE (unit=iw, fmt=
"(T2,A)") &
2369 "FORCEFIELD| Matching atomic kinds "//trim(kind_name)// &
2370 " and "//trim(inp_info%apol_atm(j))//
" for APOL"
2372 IF ((inp_info%apol_atm(j)) == kind_name)
THEN
2373 apol = inp_info%apol(j)
2374 CALL issue_duplications(found,
"APOL", kind_name)
2380 IF (
ASSOCIATED(inp_info%cpol_atm))
THEN
2381 DO j = 1,
SIZE(inp_info%cpol_atm)
2383 WRITE (unit=iw, fmt=
"(T2,A)") &
2384 "FORCEFIELD| Matching atomic kinds "//trim(kind_name)// &
2385 " and "//trim(inp_info%cpol_atm(j))//
" for CPOL"
2387 IF ((inp_info%cpol_atm(j)) == kind_name)
THEN
2388 cpol = inp_info%cpol(j)
2389 CALL issue_duplications(found,
"CPOL", kind_name)
2395 CALL set_potential(potential=fist_potential, apol=apol, cpol=cpol)
2399 CALL timestop(handle)
2415 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_damp'
2417 CHARACTER(len=default_string_length) :: atm_name1, atm_name2, my_atm_name1, &
2419 INTEGER :: handle2, i, j, k, nkinds
2424 CALL timeset(routinen, handle2)
2427 WRITE (unit=iw, fmt=
"(/,T2,A)") &
2428 "FORCEFIELD| Checking for damping terms"
2432 nkinds =
SIZE(atomic_kind_set)
2434 DO j = 1,
SIZE(atomic_kind_set)
2436 atomic_kind => atomic_kind_set(j)
2442 IF (
ASSOCIATED(inp_info%damping_list))
THEN
2443 DO i = 1,
SIZE(inp_info%damping_list)
2444 my_atm_name1 = inp_info%damping_list(i)%atm_name1
2445 my_atm_name2 = inp_info%damping_list(i)%atm_name2
2446 IF (debug_this_module)
THEN
2448 WRITE (unit=iw, fmt=
"(T2,A)") &
2449 "FORCEFIELD| Check damping for the atomic kinds "// &
2450 trim(my_atm_name1)//
" and "//trim(atm_name1)
2453 IF (my_atm_name1 == atm_name1)
THEN
2454 IF (.NOT.
ASSOCIATED(damping))
THEN
2458 DO k = 1,
SIZE(atomic_kind_set)
2459 atomic_kind2 => atomic_kind_set(k)
2463 IF (my_atm_name2 == atm_name2)
THEN
2464 IF (damping%damp(k)%bij /= huge(0.0_dp)) found = .true.
2465 CALL issue_duplications(found,
"Damping", atm_name1)
2467 SELECT CASE (trim(inp_info%damping_list(i)%dtype))
2468 CASE (
'TANG-TOENNIES')
2471 cpabort(
"Unknown damping type.")
2473 damping%damp(k)%order = inp_info%damping_list(i)%order
2474 damping%damp(k)%bij = inp_info%damping_list(i)%bij
2475 damping%damp(k)%cij = inp_info%damping_list(i)%cij
2478 IF (.NOT. found)
THEN
2479 CALL cp_warn(__location__, &
2480 "Atom "//trim(my_atm_name2)// &
2481 " in damping parameters for atom "//trim(my_atm_name1)// &
2494 CALL timestop(handle2)
2513 molecule_kind_set, molecule_set, root_section, subsys_section, &
2514 shell_particle_set, core_particle_set, cell, iw, inp_info)
2521 TYPE(
particle_type),
DIMENSION(:),
POINTER :: shell_particle_set, core_particle_set
2526 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_shell'
2528 CHARACTER(LEN=default_string_length) :: atmname
2529 INTEGER :: counter, first, first_shell, handle2, i, &
2530 j, last, last_shell, n, natom, nmol, &
2532 INTEGER,
DIMENSION(:),
POINTER :: molecule_list, shell_list_tmp
2533 LOGICAL :: core_coord_read, found_shell, is_a_shell, is_link_atom, null_massfrac, only_qm, &
2534 save_mem, shell_adiabatic, shell_coord_read
2535 REAL(kind=
dp) :: atmmass
2541 TYPE(
shell_type),
DIMENSION(:),
POINTER :: shell_list
2543 CALL timeset(routinen, handle2)
2548 null_massfrac = .false.
2549 core_coord_read = .false.
2550 shell_coord_read = .false.
2552 NULLIFY (global_section)
2557 WRITE (unit=iw, fmt=
"(/,T2,A)") &
2558 "FORCEFIELD| Checking for core-shell terms"
2561 DO i = 1,
SIZE(atomic_kind_set)
2562 atomic_kind => atomic_kind_set(i)
2566 found_shell = .false.
2571 IF (
ASSOCIATED(inp_info%shell_list))
THEN
2572 DO j = 1,
SIZE(inp_info%shell_list)
2573 IF (debug_this_module)
THEN
2575 WRITE (unit=iw, fmt=
"(T2,A)") &
2576 "Checking shells for the atomic kinds "// &
2577 trim(inp_info%shell_list(j)%atm_name)//
" and "//trim(atmname)
2580 IF ((inp_info%shell_list(j)%atm_name) == atmname)
THEN
2582 shell=shell, mass=atmmass, natom=natom)
2583 IF (.NOT.
ASSOCIATED(shell))
ALLOCATE (shell)
2584 nshell_tot = nshell_tot + natom
2585 shell%charge_core = inp_info%shell_list(j)%shell%charge_core
2586 shell%charge_shell = inp_info%shell_list(j)%shell%charge_shell
2587 shell%massfrac = inp_info%shell_list(j)%shell%massfrac
2588 IF (shell%massfrac < epsilon(1.0_dp)) null_massfrac = .true.
2589 shell%k2_spring = inp_info%shell_list(j)%shell%k2_spring
2590 shell%k4_spring = inp_info%shell_list(j)%shell%k4_spring
2591 shell%max_dist = inp_info%shell_list(j)%shell%max_dist
2592 shell%shell_cutoff = inp_info%shell_list(j)%shell%shell_cutoff
2593 shell%mass_shell = shell%massfrac*atmmass
2594 shell%mass_core = atmmass - shell%mass_shell
2595 CALL issue_duplications(found_shell,
"Shell", atmname)
2596 found_shell = .true.
2598 shell=shell, shell_active=.true.)
2605 WRITE (unit=iw, fmt=
"(/,T2,A,T61,I20)") &
2606 "FORCEFIELD| Total number of particles with a shell:", nshell_tot
2609 NULLIFY (shell_particle_set)
2610 NULLIFY (core_particle_set)
2611 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, shell_adiabatic=shell_adiabatic)
2612 IF (nshell_tot > 0)
THEN
2613 IF (shell_adiabatic .AND. null_massfrac)
THEN
2614 cpabort(
"Shell-model adiabatic: at least one shell_kind has mass zero")
2621 DO i = 1,
SIZE(particle_set)
2622 NULLIFY (atomic_kind)
2624 atomic_kind => particle_set(i)%atomic_kind
2625 CALL get_atomic_kind(atomic_kind=atomic_kind, shell_active=is_a_shell)
2626 IF (is_a_shell)
THEN
2627 counter = counter + 1
2628 particle_set(i)%shell_index = counter
2629 shell_particle_set(counter)%shell_index = counter
2630 shell_particle_set(counter)%atomic_kind => particle_set(i)%atomic_kind
2631 shell_particle_set(counter)%r(1:3) = particle_set(i)%r(1:3)
2632 shell_particle_set(counter)%atom_index = i
2633 core_particle_set(counter)%shell_index = counter
2634 core_particle_set(counter)%atomic_kind => particle_set(i)%atomic_kind
2635 core_particle_set(counter)%r(1:3) = particle_set(i)%r(1:3)
2636 core_particle_set(counter)%atom_index = i
2638 particle_set(i)%shell_index = 0
2641 cpassert(counter == nshell_tot)
2646 subsys_section, shell_coord_read)
2648 subsys_section, core_coord_read)
2650 IF (nshell_tot > 0)
THEN
2653 IF (shell_adiabatic)
THEN
2654 IF (.NOT. (core_coord_read .AND. shell_coord_read))
THEN
2656 subsys_section, core_particle_set, &
2660 IF (.NOT. shell_coord_read)
THEN
2662 subsys_section, save_mem=save_mem)
2667 DO i = 1,
SIZE(molecule_kind_set)
2668 molecule_kind => molecule_kind_set(i)
2669 CALL get_molecule_kind(molecule_kind=molecule_kind, molecule_list=molecule_list, &
2670 natom=natom, nmolecule=nmol)
2671 molecule => molecule_set(molecule_list(1))
2672 CALL get_molecule(molecule=molecule, first_atom=first, last_atom=last)
2673 ALLOCATE (shell_list_tmp(natom))
2676 atomic_kind => particle_set(j)%atomic_kind
2677 CALL get_atomic_kind(atomic_kind=atomic_kind, shell_active=is_a_shell)
2678 IF (is_a_shell)
THEN
2679 counter = counter + 1
2680 shell_list_tmp(counter) = j - first + 1
2681 first_shell = min(first_shell, max(1, particle_set(j)%shell_index))
2684 IF (counter /= 0)
THEN
2686 DO j = 1,
SIZE(molecule_list)
2687 last_shell = first_shell + counter - 1
2688 molecule => molecule_set(molecule_list(j))
2689 molecule%first_shell = first_shell
2690 molecule%last_shell = last_shell
2691 first_shell = last_shell + 1
2695 IF (
ASSOCIATED(shell_list))
THEN
2696 DEALLOCATE (shell_list)
2698 ALLOCATE (shell_list(counter))
2700 shell_list(j)%a = shell_list_tmp(j)
2701 atomic_kind => particle_set(shell_list_tmp(j) + first - 1)%atomic_kind
2702 CALL get_atomic_kind(atomic_kind=atomic_kind, name=atmname, shell=shell)
2704 shell_list(j)%name = atmname
2705 shell_list(j)%shell_kind => shell
2707 CALL set_molecule_kind(molecule_kind=molecule_kind, nshell=counter, shell_list=shell_list)
2709 DEALLOCATE (shell_list_tmp)
2710 n = n + nmol*counter
2714 cpassert(first_shell - 1 == nshell_tot)
2715 cpassert(n == nshell_tot)
2717 CALL timestop(handle2)
2736 Ainfo, chm_info, inp_info, gro_info, amb_info, potparm_nonbond14, ewald_env)
2742 CHARACTER(LEN=default_string_length), &
2743 DIMENSION(:),
POINTER :: ainfo
2751 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_nonbond14'
2753 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a_local, &
2754 name_atm_b, name_atm_b_local
2755 INTEGER :: handle2, i, ii, j, jj, k, match_names
2756 LOGICAL :: found, found_a, found_b, only_qm, &
2758 REAL(kind=
dp) :: epsilon0, epsilon_a, epsilon_b, &
2759 ewald_rcut, rmin, rmin2_a, rmin2_b
2763 CALL timeset(routinen, handle2)
2765 use_qmmm_ff = qmmm_env%use_qmmm_ff
2769 WRITE (unit=iw, fmt=
"(/,T2,A)") &
2770 "FORCEFIELD| Checking for nonbonded14 terms"
2776 DO i = 1,
SIZE(atomic_kind_set)
2777 atomic_kind => atomic_kind_set(i)
2779 DO j = i,
SIZE(atomic_kind_set)
2780 atomic_kind => atomic_kind_set(j)
2785 name_atm_a = name_atm_a_local
2786 name_atm_b = name_atm_b_local
2790 pot => potparm_nonbond14%pot(i, j)%pot
2793 IF (
ASSOCIATED(gro_info%nonbond_a_14))
THEN
2796 DO k = 1,
SIZE(gro_info%nonbond_a_14)
2797 IF (trim(name_atm_a) == trim(gro_info%nonbond_a_14(k)))
THEN
2803 DO k = 1,
SIZE(gro_info%nonbond_a_14)
2804 IF (trim(name_atm_b) == trim(gro_info%nonbond_a_14(k)))
THEN
2810 IF (ii /= 0 .AND. jj /= 0)
THEN
2813 pot%at1 = name_atm_a
2814 pot%at2 = name_atm_b
2815 pot%set(1)%lj%epsilon = 1.0_dp
2816 pot%set(1)%lj%sigma6 = gro_info%nonbond_c6_14(ii, jj)
2817 pot%set(1)%lj%sigma12 = gro_info%nonbond_c12_14(ii, jj)
2818 pot%rcutsq = (10.0_dp*
bohr)**2
2819 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, name_atm_b)
2827 IF (
ASSOCIATED(chm_info%nonbond_a_14))
THEN
2828 DO k = 1,
SIZE(chm_info%nonbond_a_14)
2829 IF ((name_atm_a) == (chm_info%nonbond_a_14(k)))
THEN
2831 rmin2_a = chm_info%nonbond_rmin2_14(k)
2832 epsilon_a = chm_info%nonbond_eps_14(k)
2836 DO k = 1,
SIZE(chm_info%nonbond_a_14)
2837 IF ((name_atm_b) == (chm_info%nonbond_a_14(k)))
THEN
2839 rmin2_b = chm_info%nonbond_rmin2_14(k)
2840 epsilon_b = chm_info%nonbond_eps_14(k)
2845 IF (
ASSOCIATED(chm_info%nonbond_a))
THEN
2846 IF (.NOT. found_a)
THEN
2847 DO k = 1,
SIZE(chm_info%nonbond_a)
2848 IF ((name_atm_a) == (chm_info%nonbond_a(k)))
THEN
2850 rmin2_a = chm_info%nonbond_rmin2(k)
2851 epsilon_a = chm_info%nonbond_eps(k)
2855 IF (.NOT. found_b)
THEN
2856 DO k = 1,
SIZE(chm_info%nonbond_a)
2857 IF ((name_atm_b) == (chm_info%nonbond_a(k)))
THEN
2859 rmin2_b = chm_info%nonbond_rmin2(k)
2860 epsilon_b = chm_info%nonbond_eps(k)
2865 IF (ii /= 0 .AND. jj /= 0)
THEN
2866 rmin = rmin2_a + rmin2_b
2868 epsilon0 = sqrt(abs(epsilon_a*epsilon_b))
2871 pot%at1 = name_atm_a
2872 pot%at2 = name_atm_b
2873 pot%set(1)%lj%epsilon = epsilon0
2874 pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
2875 pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
2876 pot%rcutsq = (10.0_dp*
bohr)**2
2877 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, name_atm_b)
2882 IF (
ASSOCIATED(amb_info%nonbond_a))
THEN
2885 IF (.NOT. found_a)
THEN
2886 DO k = 1,
SIZE(amb_info%nonbond_a)
2887 IF ((name_atm_a) == (amb_info%nonbond_a(k)))
THEN
2889 rmin2_a = amb_info%nonbond_rmin2(k)
2890 epsilon_a = amb_info%nonbond_eps(k)
2894 IF (.NOT. found_b)
THEN
2895 DO k = 1,
SIZE(amb_info%nonbond_a)
2896 IF ((name_atm_b) == (amb_info%nonbond_a(k)))
THEN
2898 rmin2_b = amb_info%nonbond_rmin2(k)
2899 epsilon_b = amb_info%nonbond_eps(k)
2903 IF (ii /= 0 .AND. jj /= 0)
THEN
2904 rmin = rmin2_a + rmin2_b
2906 epsilon0 = sqrt(abs(epsilon_a*epsilon_b))
2909 pot%at1 = name_atm_a
2910 pot%at2 = name_atm_b
2911 pot%set(1)%lj%epsilon = epsilon0
2912 pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
2913 pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
2914 pot%rcutsq = (10.0_dp*
bohr)**2
2915 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, &
2922 IF (
ASSOCIATED(inp_info%nonbonded14))
THEN
2923 DO k = 1,
SIZE(inp_info%nonbonded14%pot)
2924 IF (iw > 0)
WRITE (iw, *)
" TESTING ", trim(name_atm_a), trim(name_atm_b), &
2925 " with ", trim(inp_info%nonbonded14%pot(k)%pot%at1), &
2926 trim(inp_info%nonbonded14%pot(k)%pot%at2)
2927 IF ((((name_atm_a) == (inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
2928 ((name_atm_b) == (inp_info%nonbonded14%pot(k)%pot%at2))) .OR. &
2929 (((name_atm_b) == (inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
2930 ((name_atm_a) == (inp_info%nonbonded14%pot(k)%pot%at2))))
THEN
2931 IF (ff_type%multiple_potential)
THEN
2934 CALL cp_warn(__location__, &
2935 "Multiple ONFO declaration: "//trim(name_atm_a)// &
2936 " and "//trim(name_atm_b)//
" ADDING! ")
2937 potparm_nonbond14%pot(i, j)%pot => pot
2938 potparm_nonbond14%pot(j, i)%pot => pot
2942 CALL cp_warn(__location__, &
2943 "Multiple ONFO declarations: "//trim(name_atm_a)// &
2944 " and "//trim(name_atm_b)//
" OVERWRITING! ")
2946 IF (iw > 0)
WRITE (iw, *)
" FOUND ", trim(name_atm_a),
" ", trim(name_atm_b)
2954 IF (use_qmmm_ff)
THEN
2956 IF ((name_atm_a) == (name_atm_a_local)) match_names = match_names + 1
2957 IF ((name_atm_b) == (name_atm_b_local)) match_names = match_names + 1
2958 IF (match_names == 1)
THEN
2959 IF (
ASSOCIATED(qmmm_env%inp_info%nonbonded14))
THEN
2960 DO k = 1,
SIZE(qmmm_env%inp_info%nonbonded14%pot)
2961 IF (debug_this_module)
THEN
2963 WRITE (unit=iw, fmt=
"(T2,A)") &
2964 "FORCEFIELD| Testing "//trim(name_atm_a)//
"-"//trim(name_atm_b)// &
2965 " with "//trim(qmmm_env%inp_info%nonbonded14%pot(k)%pot%at1)//
"-"// &
2966 trim(qmmm_env%inp_info%nonbonded14%pot(k)%pot%at2)
2969 IF ((((name_atm_a) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
2970 ((name_atm_b) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at2))) .OR. &
2971 (((name_atm_b) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at1)) .AND. &
2972 ((name_atm_a) == (qmmm_env%inp_info%nonbonded14%pot(k)%pot%at2))))
THEN
2973 IF (qmmm_env%multiple_potential)
THEN
2976 CALL cp_warn(__location__, &
2977 "Multiple ONFO declaration: "//trim(name_atm_a)// &
2978 " and "//trim(name_atm_b)//
" Adding QM/MM forcefield specifications")
2979 potparm_nonbond14%pot(i, j)%pot => pot
2980 potparm_nonbond14%pot(j, i)%pot => pot
2984 CALL cp_warn(__location__, &
2985 "Multiple ONFO declaration: "//trim(name_atm_a)// &
2986 " and "//trim(name_atm_b)//
" OVERWRITING QM/MM forcefield specifications! ")
2988 IF (iw > 0)
WRITE (iw, *)
" FOUND ", trim(name_atm_a), &
2989 " ", trim(name_atm_b)
2997 IF (.NOT. found)
THEN
2998 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
2999 atm2=trim(name_atm_b), &
3000 type_name=
"Spline_Bond_Env", &
3004 pot%at1 = name_atm_a
3005 pot%at2 = name_atm_b
3009 IF (ff_type%rcut_nb > 0.0_dp)
THEN
3010 pot%rcutsq = ff_type%rcut_nb*ff_type%rcut_nb
3014 pot%rcutsq = max(pot%rcutsq, ewald_rcut*ewald_rcut)
3023 CALL timestop(handle2)
3043 iw, Ainfo, chm_info, inp_info, gro_info, amb_info, potparm_nonbond, &
3051 CHARACTER(LEN=default_string_length), &
3052 DIMENSION(:),
POINTER :: ainfo
3060 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_nonbond'
3062 CHARACTER(LEN=default_string_length) :: name_atm_a, name_atm_a_local, &
3063 name_atm_b, name_atm_b_local
3064 INTEGER :: handle2, i, ii, j, jj, k, match_names
3065 LOGICAL :: found, is_a_shell, is_b_shell, only_qm, &
3067 REAL(kind=
dp) :: epsilon0, ewald_rcut, rmin
3071 CALL timeset(routinen, handle2)
3073 use_qmmm_ff = qmmm_env%use_qmmm_ff
3077 WRITE (unit=iw, fmt=
"(/,T2,A)") &
3078 "FORCEFIELD| Checking for nonbonded terms"
3084 DO i = 1,
SIZE(atomic_kind_set)
3086 atomic_kind => atomic_kind_set(i)
3088 CALL get_atomic_kind(atomic_kind=atomic_kind, name=name_atm_a_local, &
3089 shell_active=is_a_shell)
3091 DO j = i,
SIZE(atomic_kind_set)
3093 atomic_kind => atomic_kind_set(j)
3095 CALL get_atomic_kind(atomic_kind=atomic_kind, name=name_atm_b_local, &
3096 shell_active=is_b_shell)
3100 name_atm_a = name_atm_a_local
3101 name_atm_b = name_atm_b_local
3105 pot => potparm_nonbond%pot(i, j)%pot
3108 WRITE (unit=iw, fmt=
"(/,T2,A)") &
3109 "FORCEFIELD| Checking for nonbonded terms between the atomic kinds "// &
3110 trim(name_atm_a)//
" and "//trim(name_atm_b)
3114 IF (
ASSOCIATED(gro_info%nonbond_a))
THEN
3117 DO k = 1,
SIZE(gro_info%nonbond_a)
3118 IF (trim(name_atm_a) == trim(gro_info%nonbond_a(k)))
THEN
3123 DO k = 1,
SIZE(gro_info%nonbond_a)
3124 IF (trim(name_atm_b) == trim(gro_info%nonbond_a(k)))
THEN
3130 IF (ii /= 0 .AND. jj /= 0)
THEN
3133 pot%at1 = name_atm_a
3134 pot%at2 = name_atm_b
3135 pot%set(1)%lj%epsilon = 1.0_dp
3136 pot%set(1)%lj%sigma6 = gro_info%nonbond_c6(ii, jj)
3137 pot%set(1)%lj%sigma12 = gro_info%nonbond_c12(ii, jj)
3138 pot%rcutsq = (10.0_dp*
bohr)**2
3139 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, name_atm_b)
3145 IF (
ASSOCIATED(chm_info%nonbond_a))
THEN
3148 DO k = 1,
SIZE(chm_info%nonbond_a)
3149 IF ((name_atm_a) == (chm_info%nonbond_a(k)))
THEN
3153 DO k = 1,
SIZE(chm_info%nonbond_a)
3154 IF ((name_atm_b) == (chm_info%nonbond_a(k)))
THEN
3159 IF (ii /= 0 .AND. jj /= 0)
THEN
3160 rmin = chm_info%nonbond_rmin2(ii) + chm_info%nonbond_rmin2(jj)
3161 epsilon0 = sqrt(chm_info%nonbond_eps(ii)* &
3162 chm_info%nonbond_eps(jj))
3165 pot%at1 = name_atm_a
3166 pot%at2 = name_atm_b
3167 pot%set(1)%lj%epsilon = epsilon0
3168 pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
3169 pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
3170 pot%rcutsq = (10.0_dp*
bohr)**2
3171 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, name_atm_b)
3177 IF (
ASSOCIATED(amb_info%nonbond_a))
THEN
3180 DO k = 1,
SIZE(amb_info%nonbond_a)
3181 IF ((name_atm_a) == (amb_info%nonbond_a(k)))
THEN
3185 DO k = 1,
SIZE(amb_info%nonbond_a)
3186 IF ((name_atm_b) == (amb_info%nonbond_a(k)))
THEN
3191 IF (ii /= 0 .AND. jj /= 0)
THEN
3192 rmin = amb_info%nonbond_rmin2(ii) + amb_info%nonbond_rmin2(jj)
3193 epsilon0 = sqrt(amb_info%nonbond_eps(ii)*amb_info%nonbond_eps(jj))
3196 pot%at1 = name_atm_a
3197 pot%at2 = name_atm_b
3198 pot%set(1)%lj%epsilon = epsilon0
3199 pot%set(1)%lj%sigma6 = 0.5_dp*rmin**6
3200 pot%set(1)%lj%sigma12 = 0.25_dp*rmin**12
3201 pot%rcutsq = (10.0_dp*
bohr)**2
3202 CALL issue_duplications(found,
"Lennard-Jones", name_atm_a, name_atm_b)
3208 IF (
ASSOCIATED(inp_info%nonbonded))
THEN
3209 DO k = 1,
SIZE(inp_info%nonbonded%pot)
3210 IF ((trim(inp_info%nonbonded%pot(k)%pot%at1) ==
"*") .OR. &
3211 (trim(inp_info%nonbonded%pot(k)%pot%at2) ==
"*")) cycle
3212 IF (debug_this_module)
THEN
3214 WRITE (unit=iw, fmt=
"(T2,A)") &
3215 "FORCEFIELD| Testing "//trim(name_atm_a)//
"-"//trim(name_atm_b)// &
3216 " with "//trim(inp_info%nonbonded%pot(k)%pot%at1)//
"-"// &
3217 trim(inp_info%nonbonded%pot(k)%pot%at2)
3220 IF ((((name_atm_a) == (inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
3221 ((name_atm_b) == (inp_info%nonbonded%pot(k)%pot%at2))) .OR. &
3222 (((name_atm_b) == (inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
3223 ((name_atm_a) == (inp_info%nonbonded%pot(k)%pot%at2))))
THEN
3225 WRITE (unit=iw, fmt=
"(T2,A)") &
3226 "FORCEFIELD| Found nonbonded term "// &
3227 trim(name_atm_a)//
"-"//trim(name_atm_b)
3229 IF (ff_type%multiple_potential)
THEN
3232 CALL cp_warn(__location__, &
3233 "Multiple NONBONDED declarations for "//trim(name_atm_a)// &
3234 "-"//trim(name_atm_b)//
" -> ADDING")
3235 potparm_nonbond%pot(i, j)%pot => pot
3236 potparm_nonbond%pot(j, i)%pot => pot
3240 CALL cp_warn(__location__, &
3241 "Multiple NONBONDED declarations for "//trim(name_atm_a)// &
3242 "-"//trim(name_atm_b)//
" -> OVERWRITING")
3249 IF (.NOT. found)
THEN
3250 DO k = 1,
SIZE(inp_info%nonbonded%pot)
3251 IF ((trim(inp_info%nonbonded%pot(k)%pot%at1) ==
"*") .EQV. &
3252 (trim(inp_info%nonbonded%pot(k)%pot%at2) ==
"*")) cycle
3253 IF (debug_this_module)
THEN
3255 WRITE (unit=iw, fmt=
"(T2,A)") &
3256 "FORCEFIELD| Testing "//trim(name_atm_a)//
"-"//trim(name_atm_b)// &
3257 " with "//trim(inp_info%nonbonded%pot(k)%pot%at1)//
"-"// &
3258 trim(inp_info%nonbonded%pot(k)%pot%at2)
3261 IF ((name_atm_a == inp_info%nonbonded%pot(k)%pot%at1) .OR. &
3262 (name_atm_b == inp_info%nonbonded%pot(k)%pot%at2) .OR. &
3263 (name_atm_b == inp_info%nonbonded%pot(k)%pot%at1) .OR. &
3264 (name_atm_a == inp_info%nonbonded%pot(k)%pot%at2))
THEN
3266 WRITE (unit=iw, fmt=
"(T2,A)") &
3267 "FORCEFIELD| Found one wildcard for "// &
3268 trim(name_atm_a)//
"-"//trim(name_atm_b)
3270 IF (ff_type%multiple_potential)
THEN
3273 CALL cp_warn(__location__, &
3274 "Multiple NONBONDED declarations "//trim(name_atm_a)// &
3275 "-"//trim(name_atm_b)//
" -> ADDING")
3276 potparm_nonbond%pot(i, j)%pot => pot
3277 potparm_nonbond%pot(j, i)%pot => pot
3281 CALL cp_warn(__location__, &
3282 "Multiple NONBONDED declarations "//trim(name_atm_a)// &
3283 "-"//trim(name_atm_b)//
" -> OVERWRITING")
3291 IF (.NOT. found)
THEN
3292 DO k = 1,
SIZE(inp_info%nonbonded%pot)
3293 IF ((trim(inp_info%nonbonded%pot(k)%pot%at1) /=
"*") .OR. &
3294 (trim(inp_info%nonbonded%pot(k)%pot%at2) /=
"*")) cycle
3295 IF (debug_this_module)
THEN
3297 WRITE (unit=iw, fmt=
"(T2,A)") &
3298 "FORCEFIELD| Testing "//trim(name_atm_a)//
"-"//trim(name_atm_b)// &
3299 " with "//trim(inp_info%nonbonded%pot(k)%pot%at1)//
"-"// &
3300 trim(inp_info%nonbonded%pot(k)%pot%at2)
3304 WRITE (unit=iw, fmt=
"(T2,A)") &
3305 "FORCEFIELD| Found wildcards for both "// &
3306 trim(name_atm_a)//
" and "//trim(name_atm_b)
3308 IF (ff_type%multiple_potential)
THEN
3311 CALL cp_warn(__location__, &
3312 "Multiple NONBONDED declarations "//trim(name_atm_a)// &
3313 " - "//trim(name_atm_b)//
" -> ADDING")
3314 potparm_nonbond%pot(i, j)%pot => pot
3315 potparm_nonbond%pot(j, i)%pot => pot
3319 CALL cp_warn(__location__, &
3320 "Multiple NONBONDED declarations "//trim(name_atm_a)// &
3321 " - "//trim(name_atm_b)//
" -> OVERWRITING")
3330 IF (use_qmmm_ff)
THEN
3332 IF ((name_atm_a) == (name_atm_a_local)) match_names = match_names + 1
3333 IF ((name_atm_b) == (name_atm_b_local)) match_names = match_names + 1
3334 IF (match_names == 1)
THEN
3335 IF (
ASSOCIATED(qmmm_env%inp_info%nonbonded))
THEN
3336 DO k = 1,
SIZE(qmmm_env%inp_info%nonbonded%pot)
3337 IF (debug_this_module)
THEN
3339 WRITE (unit=iw, fmt=
"(T2,A)") &
3340 "FORCEFIELD| Testing "//trim(name_atm_a)//
"-"//trim(name_atm_b)// &
3341 " with "//trim(qmmm_env%inp_info%nonbonded%pot(k)%pot%at1), &
3342 trim(qmmm_env%inp_info%nonbonded%pot(k)%pot%at2)
3345 IF ((((name_atm_a) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
3346 ((name_atm_b) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at2))) .OR. &
3347 (((name_atm_b) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at1)) .AND. &
3348 ((name_atm_a) == (qmmm_env%inp_info%nonbonded%pot(k)%pot%at2))))
THEN
3350 WRITE (unit=iw, fmt=
"(T2,A)") &
3351 "FORCEFIELD| Found "//trim(name_atm_a)//
"-"//trim(name_atm_b)//
" (QM/MM)"
3353 IF (qmmm_env%multiple_potential)
THEN
3356 CALL cp_warn(__location__, &
3357 "Multiple NONBONDED declarations for "//trim(name_atm_a)// &
3358 " and "//trim(name_atm_b)//
" -> ADDING QM/MM forcefield specifications")
3359 potparm_nonbond%pot(i, j)%pot => pot
3360 potparm_nonbond%pot(j, i)%pot => pot
3364 CALL cp_warn(__location__, &
3365 "Multiple NONBONDED declarations for "//trim(name_atm_a)// &
3366 " and "//trim(name_atm_b)//
" -> OVERWRITING QM/MM forcefield specifications")
3375 IF (.NOT. found)
THEN
3376 CALL store_ff_missing_par(atm1=trim(name_atm_a), &
3377 atm2=trim(name_atm_b), &
3378 type_name=
"Spline_Non_Bond_Env", &
3384 IF (ff_type%rcut_nb > 0.0_dp)
THEN
3385 pot%rcutsq = ff_type%rcut_nb*ff_type%rcut_nb
3389 pot%rcutsq = max(pot%rcutsq, ewald_rcut*ewald_rcut)
3391 IF ((is_a_shell .AND. .NOT. is_b_shell) .OR. (is_b_shell .AND. .NOT. is_a_shell))
THEN
3393 ELSE IF (is_a_shell .AND. is_b_shell)
THEN
3394 pot%shell_type =
sh_sh
3407 CALL timestop(handle2)
3423 potparm, do_zbl, nonbonded_type)
3427 INTEGER :: iw2, iw3, iw4
3429 LOGICAL,
INTENT(IN) :: do_zbl
3430 CHARACTER(LEN=*),
INTENT(IN) :: nonbonded_type
3432 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_splines'
3434 INTEGER :: handle2, ikind, jkind, n
3438 CALL timeset(routinen, handle2)
3441 WRITE (unit=iw2, fmt=
"(/,T2,A)") &
3442 "FORCEFIELD| Splining nonbonded terms"
3447 NULLIFY (spline_env)
3449 do_zbl, shift_cutoff=ff_type%shift_cutoff)
3452 atomic_kind_set, eps_spline=ff_type%eps_spline, &
3453 max_energy=ff_type%max_energy, rlow_nb=ff_type%rlow_nb, &
3454 emax_spline=ff_type%emax_spline, npoints=ff_type%npoints, &
3455 iw=iw2, iw2=iw3, iw3=iw4, &
3456 do_zbl=do_zbl, shift_cutoff=ff_type%shift_cutoff, &
3457 nonbonded_type=nonbonded_type)
3460 DO ikind = 1,
SIZE(potparm%pot, 1)
3461 DO jkind = ikind,
SIZE(potparm%pot, 2)
3462 n = spline_env%spltab(ikind, jkind)
3463 spl_p => spline_env%spl_pp(n)%spl_p
3466 potparm%pot(ikind, jkind)%pot%pair_spline_data => spl_p
3470 DEALLOCATE (spline_env)
3471 NULLIFY (spline_env)
3474 WRITE (unit=iw2, fmt=
"(/,T2,A)") &
3475 "FORCEFIELD| Splining done"
3478 CALL timestop(handle2)
3497 INTEGER,
INTENT(IN) :: iw
3499 CHARACTER(len=*),
PARAMETER :: routinen =
'force_field_pack_eicut'
3501 INTEGER :: ewald_type, handle, i1, i2, nkinds
3502 REAL(kind=
dp) :: alpha, beta, mm_radius1, mm_radius2, &
3503 rcut2, rcut2_ewald, tmp
3504 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: interaction_cutoffs
3507 CALL timeset(routinen, handle)
3510 WRITE (unit=iw, fmt=
"(/,T2,A)") &
3511 "FORCEFIELD| Computing the electrostatic interactions cutoffs"
3515 nkinds =
SIZE(atomic_kind_set)
3519 ALLOCATE (interaction_cutoffs(3, nkinds, nkinds))
3520 interaction_cutoffs = 0.0_dp
3523 IF (ff_type%shift_cutoff)
THEN
3524 CALL ewald_env_get(ewald_env, alpha=alpha, ewald_type=ewald_type, &
3526 rcut2_ewald = rcut2_ewald*rcut2_ewald
3528 atomic_kind => atomic_kind_set(i1)
3532 IF (
ASSOCIATED(potparm_nonbond))
THEN
3533 rcut2 = max(potparm_nonbond%pot(i1, i2)%pot%rcutsq, rcut2_ewald)
3536 atomic_kind => atomic_kind_set(i2)
3540 1.0_dp, ewald_type, alpha, 0.0_dp, 0.0_dp)
3542 IF (mm_radius1 > 0.0_dp)
THEN
3548 1.0_dp, ewald_type, alpha, beta, 0.0_dp)
3550 IF (mm_radius1 + mm_radius2 > 0.0_dp)
THEN
3551 beta =
sqrthalf/sqrt(mm_radius1*mm_radius1 + mm_radius2*mm_radius2)
3556 1.0_dp, ewald_type, alpha, beta, 0.0_dp)
3562 CALL ewald_env_set(ewald_env, interaction_cutoffs=interaction_cutoffs)
3564 CALL timestop(handle)
3579 SUBROUTINE issue_duplications(found, tag_label, name_atm_a, name_atm_b, &
3580 name_atm_c, name_atm_d)
3582 LOGICAL,
INTENT(IN) :: found
3583 CHARACTER(LEN=*),
INTENT(IN) :: tag_label, name_atm_a
3584 CHARACTER(LEN=*),
INTENT(IN),
OPTIONAL :: name_atm_b, name_atm_c, name_atm_d
3586 CHARACTER(LEN=default_string_length) :: item
3588 item =
"("//trim(name_atm_a)
3589 IF (
PRESENT(name_atm_b))
THEN
3590 item = trim(item)//
", "//trim(name_atm_b)
3592 IF (
PRESENT(name_atm_c))
THEN
3593 item = trim(item)//
", "//trim(name_atm_c)
3595 IF (
PRESENT(name_atm_d))
THEN
3596 item = trim(item)//
", "//trim(name_atm_d)
3598 item = trim(item)//
")"
3600 cpwarn(
"Found multiple "//trim(tag_label)//
" terms for "//trim(item)//
" -> OVERWRITING")
3603 END SUBROUTINE issue_duplications
3615 SUBROUTINE store_ff_missing_par(atm1, atm2, atm3, atm4, type_name, fatal, array)
3616 CHARACTER(LEN=*),
INTENT(IN) :: atm1
3617 CHARACTER(LEN=*),
INTENT(IN),
OPTIONAL :: atm2, atm3, atm4
3618 CHARACTER(LEN=*),
INTENT(IN) :: type_name
3619 LOGICAL,
INTENT(INOUT),
OPTIONAL :: fatal
3620 CHARACTER(LEN=default_string_length), &
3621 DIMENSION(:),
POINTER :: array
3623 CHARACTER(LEN=10) :: sfmt
3624 CHARACTER(LEN=9) :: my_atm1, my_atm2, my_atm3, my_atm4
3625 CHARACTER(LEN=default_path_length) :: my_format
3626 INTEGER :: fmt, i, nsize
3631 my_format =
'(T2,"FORCEFIELD| Missing ","'//trim(type_name)// &
3633 IF (
PRESENT(atm2)) fmt = fmt + 1
3634 IF (
PRESENT(atm3)) fmt = fmt + 1
3635 IF (
PRESENT(atm4)) fmt = fmt + 1
3638 my_format =
'(T2,"FORCEFIELD| Missing ","'//trim(type_name)// &
3639 '",T40,"(",A9,'//trim(sfmt)//
'(",",A9),")")'
3640 IF (
PRESENT(fatal)) fatal = .true.
3642 IF (
ASSOCIATED(array)) nsize =
SIZE(array)
3644 IF (nsize >= 1)
THEN
3646 SELECT CASE (type_name)
3648 IF (index(array(i) (21:39),
"Bond") == 0) cycle
3649 my_atm1 = array(i) (41:49)
3650 my_atm2 = array(i) (51:59)
3653 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2)) .OR. &
3654 ((atm1 == my_atm2) .AND. (atm2 == my_atm1))) found = .true.
3656 IF (index(array(i) (21:39),
"Angle") == 0) cycle
3657 my_atm1 = array(i) (41:49)
3658 my_atm2 = array(i) (51:59)
3659 my_atm3 = array(i) (61:69)
3663 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3)) .OR. &
3664 ((atm1 == my_atm3) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm1))) &
3666 CASE (
"Urey-Bradley")
3667 IF (index(array(i) (21:39),
"Urey-Bradley") == 0) cycle
3668 my_atm1 = array(i) (41:49)
3669 my_atm2 = array(i) (51:59)
3670 my_atm3 = array(i) (61:69)
3674 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3)) .OR. &
3675 ((atm1 == my_atm3) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm1))) &
3678 IF (index(array(i) (21:39),
"Torsion") == 0) cycle
3679 my_atm1 = array(i) (41:49)
3680 my_atm2 = array(i) (51:59)
3681 my_atm3 = array(i) (61:69)
3682 my_atm4 = array(i) (71:79)
3687 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm4)) .OR. &
3688 ((atm1 == my_atm4) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm1))) &
3691 IF (index(array(i) (21:39),
"Improper") == 0) cycle
3692 my_atm1 = array(i) (41:49)
3693 my_atm2 = array(i) (51:59)
3694 my_atm3 = array(i) (61:69)
3695 my_atm4 = array(i) (71:79)
3700 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm4)) .OR. &
3701 ((atm1 == my_atm1) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm4)) .OR. &
3702 ((atm1 == my_atm1) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm4) .AND. (atm4 == my_atm3)) .OR. &
3703 ((atm1 == my_atm1) .AND. (atm2 == my_atm4) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm2)) .OR. &
3704 ((atm1 == my_atm1) .AND. (atm2 == my_atm4) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm3)) .OR. &
3705 ((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm4) .AND. (atm4 == my_atm3))) &
3708 CASE (
"Out of plane bend")
3709 IF (index(array(i) (21:39),
"Out of plane bend") == 0) cycle
3710 my_atm1 = array(i) (41:49)
3711 my_atm2 = array(i) (51:59)
3712 my_atm3 = array(i) (61:69)
3713 my_atm4 = array(i) (71:79)
3718 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2) .AND. (atm3 == my_atm3) .AND. (atm4 == my_atm4)) .OR. &
3719 ((atm1 == my_atm1) .AND. (atm2 == my_atm3) .AND. (atm3 == my_atm2) .AND. (atm4 == my_atm4))) &
3723 IF (index(array(i) (21:39),
"Charge") == 0) cycle
3724 my_atm1 = array(i) (41:49)
3726 IF (atm1 == my_atm1) found = .true.
3727 CASE (
"Spline_Bond_Env",
"Spline_Non_Bond_Env")
3728 IF (index(array(i) (21:39),
"Spline_") == 0) cycle
3730 my_atm1 = array(i) (41:49)
3731 my_atm2 = array(i) (51:59)
3734 IF (((atm1 == my_atm1) .AND. (atm2 == my_atm2)) .OR. &
3735 ((atm1 == my_atm2) .AND. (atm2 == my_atm1))) found = .true.
3743 IF (.NOT. found)
THEN
3748 WRITE (array(nsize), fmt=trim(my_format)) atm1
3750 WRITE (array(nsize), fmt=trim(my_format)) atm1, atm2
3752 WRITE (array(nsize), fmt=trim(my_format)) atm1, atm2, atm3
3754 WRITE (array(nsize), fmt=trim(my_format)) atm1, atm2, atm3, atm4
3758 END SUBROUTINE store_ff_missing_par
3767 FUNCTION bsearch_leftmost_2d(array, val, row)
RESULT(res)
3768 INTEGER,
INTENT(IN) :: array(:, :), val
3769 INTEGER,
INTENT(IN),
OPTIONAL :: row
3772 INTEGER :: left, locrow, mid, right
3775 IF (
PRESENT(row)) locrow = row
3778 right = ubound(array, dim=2)
3780 DO WHILE (left < right)
3781 mid = (left + right)/2
3782 IF (array(locrow, mid) < val)
THEN
3792 IF (array(locrow, res) /= val) res = 0
3794 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
integer, parameter, public quip_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