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.StretchBend;
45
46 import java.util.logging.Level;
47 import java.util.logging.Logger;
48
49 import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_KJPerKcal;
50 import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_NmPerAngstrom;
51 import static edu.uiowa.jopenmm.OpenMMAmoebaLibrary.OpenMM_RadiansPerDegree;
52 import static java.lang.String.format;
53
54
55
56
57 public class StretchBendForce extends CustomCompoundBondForce {
58
59 private static final Logger logger = Logger.getLogger(StretchBendForce.class.getName());
60
61
62
63
64
65
66 public StretchBendForce(OpenMMEnergy openMMEnergy) {
67 super(3, openMMEnergy.getStretchBendEnergyString());
68 StretchBend[] stretchBends = openMMEnergy.getStretchBends();
69 if (stretchBends == null || stretchBends.length < 1) {
70 return;
71 }
72 addPerBondParameter("r12");
73 addPerBondParameter("r23");
74 addPerBondParameter("theta0");
75 addPerBondParameter("k1");
76 addPerBondParameter("k2");
77 setName("AmoebaStretchBend");
78
79 IntArray particles = new IntArray(0);
80 DoubleArray parameters = new DoubleArray(0);
81 for (StretchBend stretchBend : stretchBends) {
82 int i1 = stretchBend.getAtom(0).getXyzIndex() - 1;
83 int i2 = stretchBend.getAtom(1).getXyzIndex() - 1;
84 int i3 = stretchBend.getAtom(2).getXyzIndex() - 1;
85 double r12 = stretchBend.bond0Eq * OpenMM_NmPerAngstrom;
86 double r23 = stretchBend.bond1Eq * OpenMM_NmPerAngstrom;
87 double theta0 = stretchBend.angleEq * OpenMM_RadiansPerDegree;
88 double k1 = stretchBend.force0 * OpenMM_KJPerKcal / OpenMM_NmPerAngstrom;
89 double k2 = stretchBend.force1 * OpenMM_KJPerKcal / OpenMM_NmPerAngstrom;
90 particles.append(i1);
91 particles.append(i2);
92 particles.append(i3);
93 parameters.append(r12);
94 parameters.append(r23);
95 parameters.append(theta0);
96 parameters.append(k1);
97 parameters.append(k2);
98 addBond(particles, parameters);
99 particles.resize(0);
100 parameters.resize(0);
101 }
102 particles.destroy();
103 parameters.destroy();
104
105 int forceGroup = openMMEnergy.getMolecularAssembly().getForceField().getInteger("STRETCH_BEND_FORCE_GROUP", 0);
106 setForceGroup(forceGroup);
107 logger.info(format(" Stretch-Bends: %10d", stretchBends.length));
108 logger.fine(format(" Force Group: %10d", forceGroup));
109 }
110
111
112
113
114
115
116
117 public static Force constructForce(OpenMMEnergy openMMEnergy) {
118 StretchBend[] stretchBends = openMMEnergy.getStretchBends();
119 if (stretchBends == null || stretchBends.length < 1) {
120 return null;
121 }
122 return new StretchBendForce(openMMEnergy);
123 }
124
125
126
127
128
129
130 public void updateForce(OpenMMEnergy openMMEnergy) {
131 StretchBend[] stretchBends = openMMEnergy.getStretchBends();
132 if (stretchBends == null || stretchBends.length < 1) {
133 return;
134 }
135
136 IntArray particles = new IntArray(0);
137 DoubleArray parameters = new DoubleArray(0);
138 int index = 0;
139 for (StretchBend stretchBend : stretchBends) {
140 int i1 = stretchBend.getAtom(0).getXyzIndex() - 1;
141 int i2 = stretchBend.getAtom(1).getXyzIndex() - 1;
142 int i3 = stretchBend.getAtom(2).getXyzIndex() - 1;
143 double r12 = stretchBend.bond0Eq * OpenMM_NmPerAngstrom;
144 double r23 = stretchBend.bond1Eq * OpenMM_NmPerAngstrom;
145 double theta0 = stretchBend.angleEq * OpenMM_RadiansPerDegree;
146 double k1 = stretchBend.force0 * OpenMM_KJPerKcal / OpenMM_NmPerAngstrom;
147 double k2 = stretchBend.force1 * OpenMM_KJPerKcal / OpenMM_NmPerAngstrom;
148 particles.append(i1);
149 particles.append(i2);
150 particles.append(i3);
151 parameters.append(r12);
152 parameters.append(r23);
153 parameters.append(theta0);
154 parameters.append(k1);
155 parameters.append(k2);
156 setBondParameters(index++, particles, parameters);
157 particles.resize(0);
158 parameters.resize(0);
159 }
160 particles.destroy();
161 parameters.destroy();
162
163 updateParametersInContext(openMMEnergy.getContext());
164 }
165 }