1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.potential.openmm;
39
40 import ffx.openmm.DoubleArray;
41 import ffx.openmm.Force;
42 import ffx.openmm.IntArray;
43 import ffx.openmm.CustomCompoundBondForce;
44 import ffx.potential.bonded.AngleTorsion;
45 import ffx.potential.bonded.Atom;
46
47 import java.util.logging.Level;
48 import java.util.logging.Logger;
49
50 import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_KJPerKcal;
51 import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_RadiansPerDegree;
52 import static java.lang.String.format;
53
54
55
56
57 public class AngleTorsionForce extends CustomCompoundBondForce {
58
59 private static final Logger logger = Logger.getLogger(AngleTorsionForce.class.getName());
60
61
62
63
64
65
66 public AngleTorsionForce(OpenMMEnergy openMMEnergy) {
67 super(4, AngleTorsion.angleTorsionForm());
68 AngleTorsion[] angleTorsions = openMMEnergy.getAngleTorsions();
69 if (angleTorsions == null || angleTorsions.length < 1) {
70
71 destroy();
72 return;
73 }
74 addGlobalParameter("phi1", 0);
75 addGlobalParameter("phi2", Math.PI);
76 addGlobalParameter("phi3", 0);
77 for (int m = 1; m < 3; m++) {
78 for (int n = 1; n < 4; n++) {
79 addPerBondParameter(format("k%d%d", m, n));
80 }
81 }
82 for (int m = 1; m < 3; m++) {
83 addPerBondParameter(format("a%d", m));
84 }
85 for (AngleTorsion angleTorsion : angleTorsions) {
86 double[] constants = angleTorsion.getConstants();
87 DoubleArray parameters = new DoubleArray(0);
88 for (int m = 0; m < 2; m++) {
89 for (int n = 0; n < 3; n++) {
90 int index = (3 * m) + n;
91 parameters.append(constants[index] * OpenMM_KJPerKcal);
92 }
93 }
94 Atom[] atoms = angleTorsion.getAtomArray(true);
95 parameters.append(angleTorsion.angleType1.angle[0] * OpenMM_RadiansPerDegree);
96 parameters.append(angleTorsion.angleType2.angle[0] * OpenMM_RadiansPerDegree);
97
98 IntArray particles = new IntArray(0);
99 for (int i = 0; i < 4; i++) {
100 particles.append(atoms[i].getXyzIndex() - 1);
101 }
102
103 addBond(particles, parameters);
104 parameters.destroy();
105 particles.destroy();
106 }
107
108 int forceGroup = openMMEnergy.getMolecularAssembly().getForceField().getInteger("ANGLE_TORSION_FORCE_GROUP", 0);
109
110 setForceGroup(forceGroup);
111 logger.info(format(" Angle-Torsions: %10d", angleTorsions.length));
112 logger.fine(format(" Force Group: %10d", forceGroup));
113 }
114
115
116
117
118
119
120
121 public static Force constructForce(OpenMMEnergy openMMEnergy) {
122 AngleTorsion[] angleTorsions = openMMEnergy.getAngleTorsions();
123 if (angleTorsions == null || angleTorsions.length < 1) {
124 return null;
125 }
126 return new AngleTorsionForce(openMMEnergy);
127 }
128 }