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.bonded;
39
40 import ffx.numerics.atomic.AtomicDoubleArray3D;
41 import ffx.potential.parameters.ForceField;
42 import ffx.potential.parameters.UreyBradleyType;
43
44 import java.io.Serial;
45 import java.util.logging.Logger;
46
47
48
49
50
51
52
53 public class UreyBradley extends BondedTerm {
54
55 @Serial
56 private static final long serialVersionUID = 1L;
57
58 private static final Logger logger = Logger.getLogger(UreyBradley.class.getName());
59
60
61
62
63 public final UreyBradleyType ureyBradleyType;
64
65
66
67 protected final Angle angle;
68
69
70
71 private double rigidScale = 1.0;
72
73
74
75
76
77
78
79 public UreyBradley(Angle a, UreyBradleyType ureyBradleyType) {
80 super();
81 angle = a;
82 bonds = a.bonds;
83 atoms = a.atoms;
84 this.ureyBradleyType = ureyBradleyType;
85 setID_Key(false);
86 }
87
88
89
90
91
92
93
94
95 public static UreyBradley ureyBradlyFactory(Angle angle, ForceField forceField) {
96 if (angle == null) {
97 return null;
98 }
99 UreyBradleyType ureyBradleyType = forceField.getUreyBradleyType(angle.angleType.getKey());
100 if (ureyBradleyType == null) {
101 return null;
102 }
103 return new UreyBradley(angle, ureyBradleyType);
104 }
105
106
107
108
109 @Override
110 public int compareTo(BondedTerm ub) {
111 if (!ub.getClass().isInstance(this)) {
112 return super.compareTo(ub);
113 }
114 return angle.compareTo(((UreyBradley) ub).angle);
115 }
116
117
118
119
120
121
122 @Override
123 public double energy(boolean gradient, int threadID, AtomicDoubleArray3D grad, AtomicDoubleArray3D lambdaGrad) {
124 value = 0.0;
125 energy = 0.0;
126
127 if (!getUse()) {
128 return energy;
129 }
130 var atomA = atoms[0];
131 var atomC = atoms[2];
132 var va = atomA.getXYZ();
133 var vc = atomC.getXYZ();
134 var vac = va.sub(vc);
135 value = vac.length();
136 var dv = value - ureyBradleyType.distance;
137 var dv2 = dv * dv;
138 energy = ureyBradleyType.ureyUnit * rigidScale * ureyBradleyType.forceConstant * dv2
139 * (1.0 + ureyBradleyType.cubic * dv + ureyBradleyType.quartic * dv2);
140 if (gradient) {
141 var deddt = 2.0 * ureyBradleyType.ureyUnit * rigidScale * ureyBradleyType.forceConstant * dv
142 * (1.0 + 1.5 * ureyBradleyType.cubic * dv + 2.0 * ureyBradleyType.quartic * dv2);
143 var de = 0.0;
144 if (value > 0.0) {
145 de = deddt / value;
146 }
147 var ia = atomA.getIndex() - 1;
148 var ic = atomC.getIndex() - 1;
149 grad.add(threadID, ia, vac.scaleI(de));
150 grad.sub(threadID, ic, vac);
151 }
152 return energy;
153 }
154
155
156
157
158 public void log() {
159 logger.info(
160 String.format(" %s %6d-%s %6d-%s %6.4f %6.4f %10.4f", "Urey-Bradley", atoms[0].getIndex(),
161 atoms[0].getAtomType().name, atoms[2].getIndex(), atoms[2].getAtomType().name,
162 ureyBradleyType.distance, value, energy));
163 }
164
165
166
167
168
169
170 public void setRigidScale(double rigidScale) {
171 this.rigidScale = rigidScale;
172 }
173 }