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.amoeba.DoubleArray3D;
43 import ffx.openmm.amoeba.TorsionTorsionForce;
44 import ffx.potential.ForceFieldEnergy;
45 import ffx.potential.bonded.Atom;
46 import ffx.potential.bonded.TorsionTorsion;
47 import ffx.potential.parameters.TorsionTorsionType;
48 import ffx.potential.terms.TorsionTorsionPotentialEnergy;
49
50 import java.util.LinkedHashMap;
51 import java.util.Map;
52 import java.util.logging.Logger;
53
54 import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_KJPerKcal;
55 import static java.lang.String.format;
56
57
58
59
60 public class AmoebaTorsionTorsionForce extends TorsionTorsionForce {
61
62 private static final Logger logger = Logger.getLogger(AmoebaTorsionTorsionForce.class.getName());
63
64
65
66
67
68
69 public AmoebaTorsionTorsionForce(TorsionTorsionPotentialEnergy torsionTorsionPotentialEnergy) {
70 TorsionTorsion[] torsionTorsions = torsionTorsionPotentialEnergy.getTorsionTorsionArray();
71
72
73 Map<String, TorsionTorsionType> torTorTypes = new LinkedHashMap<>();
74 for (TorsionTorsion torsionTorsion : torsionTorsions) {
75 int ia = torsionTorsion.getAtom(0).getArrayIndex();
76 int ib = torsionTorsion.getAtom(1).getArrayIndex();
77 int ic = torsionTorsion.getAtom(2).getArrayIndex();
78 int id = torsionTorsion.getAtom(3).getArrayIndex();
79 int ie = torsionTorsion.getAtom(4).getArrayIndex();
80
81 TorsionTorsionType torsionTorsionType = torsionTorsion.torsionTorsionType;
82 String key = torsionTorsionType.getKey();
83
84
85 int gridIndex = 0;
86 if (torTorTypes.containsKey(key)) {
87
88
89 int index = 0;
90 for (String entry : torTorTypes.keySet()) {
91 if (entry.equalsIgnoreCase(key)) {
92 gridIndex = index;
93 break;
94 } else {
95 index++;
96 }
97 }
98 } else {
99
100 torTorTypes.put(key, torsionTorsionType);
101 gridIndex = torTorTypes.size() - 1;
102 }
103
104 Atom atom = torsionTorsion.getChiralAtom();
105 int iChiral = -1;
106 if (atom != null) {
107 iChiral = atom.getArrayIndex();
108 }
109 addTorsionTorsion(ia, ib, ic, id, ie, iChiral, gridIndex);
110 }
111
112
113 DoubleArray values = new DoubleArray(6);
114 int gridIndex = 0;
115 for (String key : torTorTypes.keySet()) {
116 TorsionTorsionType torTorType = torTorTypes.get(key);
117 int nx = torTorType.nx;
118 int ny = torTorType.ny;
119 double[] tx = torTorType.tx;
120 double[] ty = torTorType.ty;
121 double[] f = torTorType.energy;
122 double[] dx = torTorType.dx;
123 double[] dy = torTorType.dy;
124 double[] dxy = torTorType.dxy;
125
126
127 DoubleArray3D grid3D = new DoubleArray3D(nx, ny, 6);
128 int xIndex = 0;
129 int yIndex = 0;
130 for (int j = 0; j < nx * ny; j++) {
131 int addIndex = 0;
132 values.set(addIndex++, tx[xIndex]);
133 values.set(addIndex++, ty[yIndex]);
134 values.set(addIndex++, OpenMM_KJPerKcal * f[j]);
135 values.set(addIndex++, OpenMM_KJPerKcal * dx[j]);
136 values.set(addIndex++, OpenMM_KJPerKcal * dy[j]);
137 values.set(addIndex, OpenMM_KJPerKcal * dxy[j]);
138 grid3D.set(yIndex, xIndex, values);
139 xIndex++;
140 if (xIndex == nx) {
141 xIndex = 0;
142 yIndex++;
143 }
144 }
145 setTorsionTorsionGrid(gridIndex++, grid3D.getPointer());
146 grid3D.destroy();
147 }
148 values.destroy();
149
150 int forceGroup = torsionTorsionPotentialEnergy.getForceGroup();
151 setForceGroup(forceGroup);
152 logger.info(format(" Torsion-Torsions: %10d", torsionTorsions.length));
153 logger.fine(format(" Force Group: %10d", forceGroup));
154 }
155
156
157
158
159
160
161
162 public AmoebaTorsionTorsionForce(TorsionTorsionPotentialEnergy torsionTorsionPotentialEnergy,
163 int topology, OpenMMDualTopologyEnergy openMMDualTopologyEnergy) {
164 TorsionTorsion[] torsionTorsions = torsionTorsionPotentialEnergy.getTorsionTorsionArray();
165
166
167
168
169 Map<String, TorsionTorsionType> torTorTypes = new LinkedHashMap<>();
170 for (TorsionTorsion torsionTorsion : torsionTorsions) {
171 int ia = torsionTorsion.getAtom(0).getArrayIndex();
172 int ib = torsionTorsion.getAtom(1).getArrayIndex();
173 int ic = torsionTorsion.getAtom(2).getArrayIndex();
174 int id = torsionTorsion.getAtom(3).getArrayIndex();
175 int ie = torsionTorsion.getAtom(4).getArrayIndex();
176
177 TorsionTorsionType torsionTorsionType = torsionTorsion.torsionTorsionType;
178 String key = torsionTorsionType.getKey();
179
180
181 int gridIndex = 0;
182 if (torTorTypes.containsKey(key)) {
183
184 int index = 0;
185 for (String entry : torTorTypes.keySet()) {
186 if (entry.equalsIgnoreCase(key)) {
187 gridIndex = index;
188 break;
189 } else {
190 index++;
191 }
192 }
193 } else {
194
195 torTorTypes.put(key, torsionTorsionType);
196 gridIndex = torTorTypes.size() - 1;
197 }
198
199 Atom atom = torsionTorsion.getChiralAtom();
200 int iChiral = -1;
201 if (atom != null) {
202 iChiral = atom.getArrayIndex();
203 iChiral = openMMDualTopologyEnergy.mapToDualTopologyIndex(topology, iChiral);
204 }
205 ia = openMMDualTopologyEnergy.mapToDualTopologyIndex(topology, ia);
206 ib = openMMDualTopologyEnergy.mapToDualTopologyIndex(topology, ib);
207 ic = openMMDualTopologyEnergy.mapToDualTopologyIndex(topology, ic);
208 id = openMMDualTopologyEnergy.mapToDualTopologyIndex(topology, id);
209 ie = openMMDualTopologyEnergy.mapToDualTopologyIndex(topology, ie);
210 addTorsionTorsion(ia, ib, ic, id, ie, iChiral, gridIndex);
211 }
212
213
214 DoubleArray values = new DoubleArray(6);
215 int gridIndex = 0;
216 for (String key : torTorTypes.keySet()) {
217 TorsionTorsionType torTorType = torTorTypes.get(key);
218 int nx = torTorType.nx;
219 int ny = torTorType.ny;
220 double[] tx = torTorType.tx;
221 double[] ty = torTorType.ty;
222 double[] f = torTorType.energy;
223 double[] dx = torTorType.dx;
224 double[] dy = torTorType.dy;
225 double[] dxy = torTorType.dxy;
226
227
228 DoubleArray3D grid3D = new DoubleArray3D(nx, ny, 6);
229 int xIndex = 0;
230 int yIndex = 0;
231 for (int j = 0; j < nx * ny; j++) {
232 int addIndex = 0;
233 values.set(addIndex++, tx[xIndex]);
234 values.set(addIndex++, ty[yIndex]);
235 values.set(addIndex++, OpenMM_KJPerKcal * f[j]);
236 values.set(addIndex++, OpenMM_KJPerKcal * dx[j]);
237 values.set(addIndex++, OpenMM_KJPerKcal * dy[j]);
238 values.set(addIndex, OpenMM_KJPerKcal * dxy[j]);
239 grid3D.set(yIndex, xIndex, values);
240 xIndex++;
241 if (xIndex == nx) {
242 xIndex = 0;
243 yIndex++;
244 }
245 }
246 setTorsionTorsionGrid(gridIndex++, grid3D.getPointer());
247 grid3D.destroy();
248 }
249 values.destroy();
250
251 int forceGroup = torsionTorsionPotentialEnergy.getForceGroup();
252 setForceGroup(forceGroup);
253 logger.info(format(" Torsion-Torsions: %10d", torsionTorsions.length));
254 logger.fine(format(" Force Group: %10d", forceGroup));
255 }
256
257
258
259
260
261
262
263 public static Force constructForce(OpenMMEnergy openMMEnergy) {
264 TorsionTorsionPotentialEnergy torsionTorsionPotentialEnergy = openMMEnergy.getTorsionTorsionPotentialEnergy();
265 if (torsionTorsionPotentialEnergy == null) {
266 return null;
267 }
268 return new AmoebaTorsionTorsionForce(torsionTorsionPotentialEnergy);
269 }
270
271
272
273
274
275
276
277
278 public static Force constructForce(int topology, OpenMMDualTopologyEnergy openMMDualTopologyEnergy) {
279 ForceFieldEnergy forceFieldEnergy = openMMDualTopologyEnergy.getForceFieldEnergy(topology);
280 TorsionTorsionPotentialEnergy torsionTorsionPotentialEnergy = forceFieldEnergy.getTorsionTorsionPotentialEnergy();
281 if (torsionTorsionPotentialEnergy == null) {
282 return null;
283 }
284 return new AmoebaTorsionTorsionForce(torsionTorsionPotentialEnergy, topology, openMMDualTopologyEnergy);
285 }
286 }