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.DoubleArray3D;
42 import ffx.openmm.Force;
43 import ffx.openmm.amoeba.TorsionTorsionForce;
44 import ffx.potential.bonded.Atom;
45 import ffx.potential.bonded.TorsionTorsion;
46 import ffx.potential.parameters.TorsionTorsionType;
47
48 import java.util.LinkedHashMap;
49 import java.util.logging.Level;
50 import java.util.logging.Logger;
51
52 import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_KJPerKcal;
53 import static java.lang.String.format;
54
55
56
57
58 public class AmoebaTorsionTorsionForce extends TorsionTorsionForce {
59
60 private static final Logger logger = Logger.getLogger(AmoebaTorsionTorsionForce.class.getName());
61
62
63
64
65
66
67 public AmoebaTorsionTorsionForce(OpenMMEnergy openMMEnergy) {
68 TorsionTorsion[] torsionTorsions = openMMEnergy.getTorsionTorsions();
69 if (torsionTorsions == null || torsionTorsions.length < 1) {
70 destroy();
71 return;
72 }
73
74
75 int nTypes = 0;
76 LinkedHashMap<String, TorsionTorsionType> torTorTypes = new LinkedHashMap<>();
77
78 for (TorsionTorsion torsionTorsion : torsionTorsions) {
79 int ia = torsionTorsion.getAtom(0).getXyzIndex() - 1;
80 int ib = torsionTorsion.getAtom(1).getXyzIndex() - 1;
81 int ic = torsionTorsion.getAtom(2).getXyzIndex() - 1;
82 int id = torsionTorsion.getAtom(3).getXyzIndex() - 1;
83 int ie = torsionTorsion.getAtom(4).getXyzIndex() - 1;
84
85 TorsionTorsionType torsionTorsionType = torsionTorsion.torsionTorsionType;
86 String key = torsionTorsionType.getKey();
87
88
89 int gridIndex = 0;
90 if (torTorTypes.containsKey(key)) {
91
92
93 int index = 0;
94 for (String entry : torTorTypes.keySet()) {
95 if (entry.equalsIgnoreCase(key)) {
96 gridIndex = index;
97 break;
98 } else {
99 index++;
100 }
101 }
102 } else {
103
104 torTorTypes.put(key, torsionTorsionType);
105 gridIndex = nTypes;
106 nTypes++;
107 }
108
109 Atom atom = torsionTorsion.getChiralAtom();
110 int iChiral = -1;
111 if (atom != null) {
112 iChiral = atom.getXyzIndex() - 1;
113 }
114 addTorsionTorsion(ia, ib, ic, id, ie, iChiral, gridIndex);
115 }
116
117
118 DoubleArray values = new DoubleArray(6);
119 int gridIndex = 0;
120 for (String key : torTorTypes.keySet()) {
121 TorsionTorsionType torTorType = torTorTypes.get(key);
122 int nx = torTorType.nx;
123 int ny = torTorType.ny;
124 double[] tx = torTorType.tx;
125 double[] ty = torTorType.ty;
126 double[] f = torTorType.energy;
127 double[] dx = torTorType.dx;
128 double[] dy = torTorType.dy;
129 double[] dxy = torTorType.dxy;
130
131
132 DoubleArray3D grid3D = new DoubleArray3D(nx, ny, 6);
133 int xIndex = 0;
134 int yIndex = 0;
135 for (int j = 0; j < nx * ny; j++) {
136 int addIndex = 0;
137 values.set(addIndex++, tx[xIndex]);
138 values.set(addIndex++, ty[yIndex]);
139 values.set(addIndex++, OpenMM_KJPerKcal * f[j]);
140 values.set(addIndex++, OpenMM_KJPerKcal * dx[j]);
141 values.set(addIndex++, OpenMM_KJPerKcal * dy[j]);
142 values.set(addIndex, OpenMM_KJPerKcal * dxy[j]);
143 grid3D.set(yIndex, xIndex, values);
144 xIndex++;
145 if (xIndex == nx) {
146 xIndex = 0;
147 yIndex++;
148 }
149 }
150 setTorsionTorsionGrid(gridIndex++, grid3D.getPointer());
151 grid3D.destroy();
152 }
153 values.destroy();
154
155 int forceGroup = openMMEnergy.getMolecularAssembly().getForceField().getInteger("TORSION_TORSION_FORCE_GROUP", 0);
156 setForceGroup(forceGroup);
157 logger.info(format(" Torsion-Torsions: %10d", torsionTorsions.length));
158 logger.fine(format(" Force Group: %10d", forceGroup));
159 }
160
161
162
163
164
165
166
167 public static Force constructForce(OpenMMEnergy openMMEnergy) {
168 TorsionTorsion[] torsionTorsion = openMMEnergy.getTorsionTorsions();
169 if (torsionTorsion == null || torsionTorsion.length < 1) {
170 return null;
171 }
172 return new AmoebaTorsionTorsionForce(openMMEnergy);
173 }
174 }