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.Force;
41 import ffx.openmm.HarmonicBondForce;
42 import ffx.potential.ForceFieldEnergy;
43 import ffx.potential.bonded.UreyBradley;
44 import ffx.potential.parameters.UreyBradleyType;
45 import ffx.potential.terms.UreyBradleyPotentialEnergy;
46
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 java.lang.String.format;
52
53
54
55
56 public class UreyBradleyForce extends HarmonicBondForce {
57
58 private static final Logger logger = Logger.getLogger(UreyBradleyForce.class.getName());
59
60
61
62
63
64
65 public UreyBradleyForce(UreyBradleyPotentialEnergy ureyBradleyPotentialEnergy) {
66 UreyBradley[] ureyBradleys = ureyBradleyPotentialEnergy.getUreyBradleyArray();
67 double kParameterConversion = OpenMM_KJPerKcal / (OpenMM_NmPerAngstrom * OpenMM_NmPerAngstrom);
68
69 for (UreyBradley ureyBradley : ureyBradleys) {
70 int i1 = ureyBradley.getAtom(0).getArrayIndex();
71 int i2 = ureyBradley.getAtom(2).getArrayIndex();
72 UreyBradleyType ureyBradleyType = ureyBradley.ureyBradleyType;
73 double length = ureyBradleyType.distance * OpenMM_NmPerAngstrom;
74
75
76 double k = 2.0 * ureyBradleyType.forceConstant * ureyBradleyType.ureyUnit * kParameterConversion;
77 addBond(i1, i2, length, k);
78 }
79
80 int forceGroup = ureyBradleyPotentialEnergy.getForceGroup();
81 setForceGroup(forceGroup);
82 logger.info(format(" Urey-Bradleys: %10d", ureyBradleys.length));
83 logger.fine(format(" Force Group: %10d", forceGroup));
84 }
85
86
87
88
89
90
91
92 public UreyBradleyForce(UreyBradleyPotentialEnergy ureyBradleyPotentialEnergy,
93 int topology, OpenMMDualTopologyEnergy openMMDualTopologyEnergy) {
94 UreyBradley[] ureyBradleys = ureyBradleyPotentialEnergy.getUreyBradleyArray();
95 double scale = openMMDualTopologyEnergy.getTopologyScale(topology);
96 double kParameterConversion = OpenMM_KJPerKcal / (OpenMM_NmPerAngstrom * OpenMM_NmPerAngstrom);
97
98 for (UreyBradley ureyBradley : ureyBradleys) {
99 int i1 = ureyBradley.getAtom(0).getArrayIndex();
100 int i2 = ureyBradley.getAtom(2).getArrayIndex();
101 UreyBradleyType ureyBradleyType = ureyBradley.ureyBradleyType;
102 double length = ureyBradleyType.distance * OpenMM_NmPerAngstrom;
103
104
105 double k = 2.0 * ureyBradleyType.forceConstant * ureyBradleyType.ureyUnit * kParameterConversion;
106
107 if (!ureyBradley.applyLambda()) {
108 k = k * scale;
109 }
110 i1 = openMMDualTopologyEnergy.mapToDualTopologyIndex(topology, i1);
111 i2 = openMMDualTopologyEnergy.mapToDualTopologyIndex(topology, i2);
112 addBond(i1, i2, length, k);
113 }
114
115 int forceGroup = ureyBradleyPotentialEnergy.getForceGroup();
116 setForceGroup(forceGroup);
117 logger.info(format(" Urey-Bradleys: %10d", ureyBradleys.length));
118 logger.fine(format(" Force Group: %10d", forceGroup));
119 }
120
121
122
123
124
125
126
127 public static Force constructForce(OpenMMEnergy openMMEnergy) {
128 UreyBradleyPotentialEnergy ureyBradleyPotentialEnergy = openMMEnergy.getUreyBradleyPotentialEnergy();
129 if (ureyBradleyPotentialEnergy == null) {
130 return null;
131 }
132 return new UreyBradleyForce(ureyBradleyPotentialEnergy);
133 }
134
135
136
137
138
139
140
141 public static Force constructForce(int topology, OpenMMDualTopologyEnergy openMMDualTopologyEnergy) {
142 ForceFieldEnergy forceFieldEnergy = openMMDualTopologyEnergy.getForceFieldEnergy(topology);
143 UreyBradleyPotentialEnergy ureyBradleyPotentialEnergy = forceFieldEnergy.getUreyBradleyPotentialEnergy();
144 if (ureyBradleyPotentialEnergy == null) {
145 return null;
146 }
147 return new UreyBradleyForce(ureyBradleyPotentialEnergy, topology, openMMDualTopologyEnergy);
148 }
149
150
151
152
153
154
155 public void updateForce(OpenMMEnergy openMMEnergy) {
156 UreyBradleyPotentialEnergy ureyBradleyPotentialEnergy = openMMEnergy.getUreyBradleyPotentialEnergy();
157 if (ureyBradleyPotentialEnergy == null) {
158 return;
159 }
160 UreyBradley[] ureyBradleys = ureyBradleyPotentialEnergy.getUreyBradleyArray();
161 double kParameterConversion = OpenMM_KJPerKcal / (OpenMM_NmPerAngstrom * OpenMM_NmPerAngstrom);
162
163 int index = 0;
164 for (UreyBradley ureyBradley : ureyBradleys) {
165 int i1 = ureyBradley.getAtom(0).getArrayIndex();
166 int i2 = ureyBradley.getAtom(2).getArrayIndex();
167 UreyBradleyType ureyBradleyType = ureyBradley.ureyBradleyType;
168 double length = ureyBradleyType.distance * OpenMM_NmPerAngstrom;
169
170
171 double k = 2.0 * ureyBradleyType.forceConstant * ureyBradleyType.ureyUnit * kParameterConversion;
172 setBondParameters(index++, i1, i2, length, k);
173 }
174
175 updateParametersInContext(openMMEnergy.getContext());
176 }
177
178
179
180
181
182
183
184 public void updateForce(int topology, OpenMMDualTopologyEnergy openMMDualTopologyEnergy) {
185 ForceFieldEnergy forceFieldEnergy = openMMDualTopologyEnergy.getForceFieldEnergy(topology);
186 UreyBradleyPotentialEnergy forceFieldEnergyUreyBradley =
187 forceFieldEnergy.getUreyBradleyPotentialEnergy();
188 if (forceFieldEnergyUreyBradley == null) {
189 return;
190 }
191 UreyBradley[] ureyBradleys = forceFieldEnergyUreyBradley.getUreyBradleyArray();
192 double scale = openMMDualTopologyEnergy.getTopologyScale(topology);
193 double kParameterConversion = OpenMM_KJPerKcal / (OpenMM_NmPerAngstrom * OpenMM_NmPerAngstrom);
194
195 int index = 0;
196 for (UreyBradley ureyBradley : ureyBradleys) {
197 int i1 = ureyBradley.getAtom(0).getArrayIndex();
198 int i2 = ureyBradley.getAtom(2).getArrayIndex();
199 UreyBradleyType ureyBradleyType = ureyBradley.ureyBradleyType;
200 double length = ureyBradleyType.distance * OpenMM_NmPerAngstrom;
201
202
203 double k = 2.0 * ureyBradleyType.forceConstant * ureyBradleyType.ureyUnit * kParameterConversion;
204
205 if (!ureyBradley.applyLambda()) {
206 k = k * scale;
207 }
208 i1 = openMMDualTopologyEnergy.mapToDualTopologyIndex(topology, i1);
209 i2 = openMMDualTopologyEnergy.mapToDualTopologyIndex(topology, i2);
210 setBondParameters(index++, i1, i2, length, k);
211 }
212
213 updateParametersInContext(openMMDualTopologyEnergy.getContext());
214 }
215
216 }