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.Atom;
45 import ffx.potential.bonded.StretchTorsion;
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_NmPerAngstrom;
52 import static java.lang.String.format;
53
54
55
56
57 public class StretchTorsionForce extends CustomCompoundBondForce {
58
59 private static final Logger logger = Logger.getLogger(StretchTorsionForce.class.getName());
60
61
62
63
64
65
66 public StretchTorsionForce(OpenMMEnergy openMMEnergy) {
67 super(4, StretchTorsion.stretchTorsionForm());
68 StretchTorsion[] stretchTorsions = openMMEnergy.getStretchTorsions();
69 if (stretchTorsions == null || stretchTorsions.length < 1) {
70 return;
71 }
72
73 addGlobalParameter("phi1", 0);
74 addGlobalParameter("phi2", Math.PI);
75 addGlobalParameter("phi3", 0);
76 for (int m = 1; m < 4; m++) {
77 for (int n = 1; n < 4; n++) {
78 addPerBondParameter(format("k%d%d", m, n));
79 }
80 }
81 for (int m = 1; m < 4; m++) {
82 addPerBondParameter(format("b%d", m));
83 }
84
85 final double unitConv = OpenMM_KJPerKcal / OpenMM_NmPerAngstrom;
86
87 for (StretchTorsion stretchTorsion : stretchTorsions) {
88 double[] constants = stretchTorsion.getConstants();
89 DoubleArray parameters = new DoubleArray(0);
90 for (int m = 0; m < 3; m++) {
91 for (int n = 0; n < 3; n++) {
92 int index = (3 * m) + n;
93 parameters.append(constants[index] * unitConv);
94 }
95 }
96 parameters.append(stretchTorsion.bondType1.distance * OpenMM_NmPerAngstrom);
97 parameters.append(stretchTorsion.bondType2.distance * OpenMM_NmPerAngstrom);
98 parameters.append(stretchTorsion.bondType3.distance * OpenMM_NmPerAngstrom);
99
100 IntArray particles = new IntArray(0);
101 Atom[] atoms = stretchTorsion.getAtomArray(true);
102 for (int i = 0; i < 4; i++) {
103 particles.append(atoms[i].getXyzIndex() - 1);
104 }
105
106 addBond(particles, parameters);
107 parameters.destroy();
108 particles.destroy();
109 }
110
111 int forceGroup = openMMEnergy.getMolecularAssembly().getForceField().getInteger("STRETCH_TORSION_FORCE_GROUP", 0);
112 setForceGroup(forceGroup);
113 logger.info(format(" Stretch-Torsions: %10d", stretchTorsions.length));
114 logger.fine(format(" Force Group: %10d", forceGroup));
115 }
116
117
118
119
120
121
122
123 public static Force constructForce(OpenMMEnergy openMMEnergy) {
124 StretchTorsion[] stretchTorsions = openMMEnergy.getStretchTorsions();
125 if (stretchTorsions == null || stretchTorsions.length < 1) {
126 return null;
127 }
128 return new StretchTorsionForce(openMMEnergy);
129 }
130 }