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.terms;
39
40 import ffx.potential.bonded.BondedTerm;
41 import ffx.potential.bonded.OutOfPlaneBend;
42 import ffx.potential.parameters.OutOfPlaneBendType;
43
44 import java.util.ArrayList;
45 import java.util.Collection;
46 import java.util.Collections;
47 import java.util.List;
48 import java.util.logging.Logger;
49 import static java.lang.String.format;
50 import static org.apache.commons.math3.util.FastMath.PI;
51
52
53
54
55 public class OutOfPlaneBendPotentialEnergy extends EnergyTerm {
56
57 private static final Logger logger = Logger.getLogger(OutOfPlaneBendPotentialEnergy.class.getName());
58
59
60
61
62
63 private final List<OutOfPlaneBend> outOfPlaneBends = new ArrayList<>();
64
65
66
67
68
69
70 public OutOfPlaneBendPotentialEnergy(String name) {
71 super(name);
72 }
73
74
75
76
77
78
79
80 public OutOfPlaneBendPotentialEnergy(String name, int forceGroup) {
81 super(name, forceGroup);
82 }
83
84
85
86
87
88
89
90
91 public OutOfPlaneBendPotentialEnergy(String name, int forceGroup, List<OutOfPlaneBend> outOfPlaneBends) {
92 super(name, forceGroup);
93 if (outOfPlaneBends != null) {
94 Collections.sort(outOfPlaneBends);
95 this.outOfPlaneBends.addAll(outOfPlaneBends);
96 logger.info(format(" Out-of-Plane Bends: %10d", getNumberOfOutOfPlaneBends()));
97 }
98 }
99
100
101
102
103 @Override
104 public int getNumberOfTerms() {
105 return getNumberOfOutOfPlaneBends();
106 }
107
108
109
110
111 @Override
112 public BondedTerm[] getBondedTermsArray() {
113 return getOutOfPlaneBendArray();
114 }
115
116
117
118
119
120
121
122 public OutOfPlaneBendPotentialEnergy(String name, Collection<OutOfPlaneBend> outOfPlaneBends) {
123 super(name);
124 if (outOfPlaneBends != null) {
125 this.outOfPlaneBends.addAll(outOfPlaneBends);
126 }
127 }
128
129
130
131
132
133
134
135 public boolean addOutOfPlaneBend(OutOfPlaneBend outOfPlaneBend) {
136 if (outOfPlaneBend == null) {
137 return false;
138 }
139 return outOfPlaneBends.add(outOfPlaneBend);
140 }
141
142
143
144
145
146
147
148 public boolean addOutOfPlaneBends(OutOfPlaneBend[] outOfPlaneBends) {
149 if (outOfPlaneBends == null) {
150 return false;
151 }
152 Collections.addAll(this.outOfPlaneBends, outOfPlaneBends);
153 return true;
154 }
155
156
157
158
159
160
161
162 public boolean addOutOfPlaneBends(List<OutOfPlaneBend> outOfPlaneBends) {
163 if (outOfPlaneBends == null) {
164 return false;
165 }
166 this.outOfPlaneBends.addAll(outOfPlaneBends);
167 return true;
168 }
169
170
171
172
173
174
175
176 public boolean removeOutOfPlaneBend(OutOfPlaneBend outOfPlaneBend) {
177 if (outOfPlaneBend == null) {
178 return false;
179 }
180 return outOfPlaneBends.remove(outOfPlaneBend);
181 }
182
183
184
185
186
187
188
189
190 public OutOfPlaneBend getOutOfPlaneBend(int index) {
191 return outOfPlaneBends.get(index);
192 }
193
194
195
196
197
198
199 public List<OutOfPlaneBend> getOutOfPlaneBends() {
200 return Collections.unmodifiableList(outOfPlaneBends);
201 }
202
203
204
205
206
207
208 public OutOfPlaneBend[] getOutOfPlaneBendArray() {
209 return outOfPlaneBends.toArray(new OutOfPlaneBend[0]);
210 }
211
212
213
214
215
216
217 public int getNumberOfOutOfPlaneBends() {
218 return outOfPlaneBends.size();
219 }
220
221
222
223
224
225
226 public String getOutOfPlaneEnergyString() {
227 OutOfPlaneBendType outOfPlaneBendType = outOfPlaneBends.getFirst().outOfPlaneBendType;
228 String energy = format("""
229 k*(theta^2 + %.15g*theta^3 + %.15g*theta^4 + %.15g*theta^5 + %.15g*theta^6);
230 theta = %.15g*pointangle(x2, y2, z2, x4, y4, z4, projx, projy, projz);
231 projx = x2-nx*dot;
232 projy = y2-ny*dot;
233 projz = z2-nz*dot;
234 dot = nx*(x2-x3) + ny*(y2-y3) + nz*(z2-z3);
235 nx = px/norm;
236 ny = py/norm;
237 nz = pz/norm;
238 norm = sqrt(px*px + py*py + pz*pz);
239 px = (d1y*d2z-d1z*d2y);
240 py = (d1z*d2x-d1x*d2z);
241 pz = (d1x*d2y-d1y*d2x);
242 d1x = x1-x4;
243 d1y = y1-y4;
244 d1z = z1-z4;
245 d2x = x3-x4;
246 d2y = y3-y4;
247 d2z = z3-z4
248 """,
249 outOfPlaneBendType.cubic, outOfPlaneBendType.quartic,
250 outOfPlaneBendType.pentic, outOfPlaneBendType.sextic, 180.0 / PI);
251 return energy;
252 }
253
254
255
256
257 @Override
258 public void log() {
259 if (getNumberOfOutOfPlaneBends() <= 0) {
260 return;
261 }
262 logger.info("\n Out-of-Plane Bend Interactions:");
263 for (OutOfPlaneBend outOfPlaneBend : getOutOfPlaneBends()) {
264 logger.info(" Out-of-Plane Bend \t" + outOfPlaneBend.toString());
265 }
266 }
267
268 @Override
269 public String toPDBString() {
270 if (getNumberOfOutOfPlaneBends() <= 0) {
271 return "";
272 }
273 return format("REMARK 3 %s %g (%d)\n", "OUT-OF-PLANE BEND : ", getEnergy(), getNumberOfOutOfPlaneBends());
274 }
275
276 @Override
277 public String toString() {
278 return format(" %s %20.8f %12d %12.3f\n", "Out-of-Plane Bend ",
279 getEnergy(), getNumberOfOutOfPlaneBends(), getTime());
280 }
281 }