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.log(Level.INFO, format(" Stretch-Bends \t%6d\t\t%1d", stretchBends.length, forceGroup));
108 }
109
110
111
112
113
114
115
116 public static Force constructForce(OpenMMEnergy openMMEnergy) {
117 StretchBend[] stretchBends = openMMEnergy.getStretchBends();
118 if (stretchBends == null || stretchBends.length < 1) {
119 return null;
120 }
121 return new StretchBendForce(openMMEnergy);
122 }
123
124
125
126
127
128
129 public void updateForce(OpenMMEnergy openMMEnergy) {
130 StretchBend[] stretchBends = openMMEnergy.getStretchBends();
131 if (stretchBends == null || stretchBends.length < 1) {
132 return;
133 }
134
135 IntArray particles = new IntArray(0);
136 DoubleArray parameters = new DoubleArray(0);
137 int index = 0;
138 for (StretchBend stretchBend : stretchBends) {
139 int i1 = stretchBend.getAtom(0).getXyzIndex() - 1;
140 int i2 = stretchBend.getAtom(1).getXyzIndex() - 1;
141 int i3 = stretchBend.getAtom(2).getXyzIndex() - 1;
142 double r12 = stretchBend.bond0Eq * OpenMM_NmPerAngstrom;
143 double r23 = stretchBend.bond1Eq * OpenMM_NmPerAngstrom;
144 double theta0 = stretchBend.angleEq * OpenMM_RadiansPerDegree;
145 double k1 = stretchBend.force0 * OpenMM_KJPerKcal / OpenMM_NmPerAngstrom;
146 double k2 = stretchBend.force1 * OpenMM_KJPerKcal / OpenMM_NmPerAngstrom;
147 particles.append(i1);
148 particles.append(i2);
149 particles.append(i3);
150 parameters.append(r12);
151 parameters.append(r23);
152 parameters.append(theta0);
153 parameters.append(k1);
154 parameters.append(k2);
155 setBondParameters(index++, particles, parameters);
156 particles.resize(0);
157 parameters.resize(0);
158 }
159 particles.destroy();
160 parameters.destroy();
161
162 updateParametersInContext(openMMEnergy.getContext());
163 }
164 }