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;
39
40 import static edu.uiowa.torchani.TorchANILibrary.ctorch;
41 import static ffx.utilities.Constants.HARTREE_TO_KCAL_PER_MOL;
42
43 import com.sun.jna.NativeLong;
44 import ffx.numerics.Potential;
45 import ffx.potential.bonded.Atom;
46 import ffx.potential.bonded.LambdaInterface;
47
48 import edu.uiowa.torchani.TorchANIUtils;
49 import ffx.potential.parameters.ForceField;
50 import java.util.logging.Logger;
51
52 public class ANIEnergy implements Potential, LambdaInterface {
53
54
55 private static final Logger logger = Logger.getLogger(ANIEnergy.class.getName());
56
57 private final int nAtoms;
58 private final Atom[] atoms;
59 private final NativeLong nAtomsLong;
60 private final int[] species;
61 private final double[] coordinates;
62 private final double[] grad;
63 private final String pathToANI;
64 private double lambda = 1.0;
65 private double energy;
66 private final MolecularAssembly molecularAssembly;
67
68 private STATE state = STATE.FAST;
69
70 public ANIEnergy(MolecularAssembly molecularAssembly) {
71 TorchANIUtils.init();
72 System.out.println(" ANI Dir: " + TorchANIUtils.getLibDirectory());
73
74 atoms = molecularAssembly.getAtomArray();
75 nAtoms = atoms.length;
76 nAtomsLong = new NativeLong(nAtoms);
77 species = new int[nAtoms];
78 coordinates = new double[3 * nAtoms];
79 grad = new double[3 * nAtoms];
80 int index = 0;
81 for (Atom atom : atoms) {
82 species[index] = atom.getAtomicNumber();
83 index++;
84 }
85
86 this.molecularAssembly = molecularAssembly;
87
88 ForceField forceField = molecularAssembly.getForceField();
89 pathToANI = forceField.getString("ANI_PATH", "ANI2x.pt");
90 }
91
92
93
94
95
96
97
98
99 public double energy(boolean gradient, boolean print) {
100 getCoordinates(coordinates);
101 if (gradient) {
102 energyAndGradient(coordinates, grad);
103 for (int i = 0; i < nAtoms; i++) {
104 Atom ai = atoms[i];
105 int index = 3 * i;
106 ai.addToXYZGradient(grad[index], grad[index + 1], grad[index + 2]);
107 }
108 } else {
109 energy(coordinates);
110 }
111 return energy;
112 }
113
114 @Override
115 public double energy(double[] x) {
116 energy = ctorch(pathToANI, nAtomsLong, species, x, grad) * HARTREE_TO_KCAL_PER_MOL;
117 return energy;
118 }
119
120 @Override
121 public double energyAndGradient(double[] x, double[] g) {
122 energy = ctorch(pathToANI, nAtomsLong, species, x, g) * HARTREE_TO_KCAL_PER_MOL;
123 for (int i = 0; i < grad.length; i++) {
124 grad[i] = g[i] * HARTREE_TO_KCAL_PER_MOL;
125 }
126 return energy;
127 }
128
129 @Override
130 public double[] getAcceleration(double[] acceleration) {
131 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
132 return forceFieldEnergy.getAcceleration(acceleration);
133 }
134
135 @Override
136 public double[] getCoordinates(double[] parameters) {
137 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
138 return forceFieldEnergy.getCoordinates(parameters);
139 }
140
141 @Override
142 public STATE getEnergyTermState() {
143 return state;
144 }
145
146 @Override
147 public void setEnergyTermState(STATE state) {
148 this.state = state;
149 }
150
151 @Override
152 public double[] getMass() {
153 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
154 return forceFieldEnergy.getMass();
155 }
156
157 @Override
158 public int getNumberOfVariables() {
159 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
160 return forceFieldEnergy.getNumberOfVariables();
161 }
162
163 @Override
164 public double[] getPreviousAcceleration(double[] previousAcceleration) {
165 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
166 return forceFieldEnergy.getPreviousAcceleration(previousAcceleration);
167 }
168
169 @Override
170 public double[] getScaling() {
171 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
172 return forceFieldEnergy.getScaling();
173 }
174
175 @Override
176 public void setScaling(double[] scaling) {
177 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
178 forceFieldEnergy.setScaling(scaling);
179 }
180
181 @Override
182 public double getTotalEnergy() {
183 return energy;
184 }
185
186 @Override
187 public VARIABLE_TYPE[] getVariableTypes() {
188 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
189 return forceFieldEnergy.getVariableTypes();
190 }
191
192 @Override
193 public double[] getVelocity(double[] velocity) {
194 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
195 return forceFieldEnergy.getVelocity(velocity);
196 }
197
198 @Override
199 public void setAcceleration(double[] acceleration) {
200 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
201 forceFieldEnergy.setAcceleration(acceleration);
202 }
203
204 @Override
205 public void setPreviousAcceleration(double[] previousAcceleration) {
206 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
207 forceFieldEnergy.setPreviousAcceleration(previousAcceleration);
208 }
209
210 @Override
211 public void setVelocity(double[] velocity) {
212 ForceFieldEnergy forceFieldEnergy = molecularAssembly.getPotentialEnergy();
213 forceFieldEnergy.setVelocity(velocity);
214 }
215
216 @Override
217 public double getLambda() {
218 return lambda;
219 }
220
221 @Override
222 public void setLambda(double lambda) {
223 this.lambda = lambda;
224 }
225
226 @Override
227 public double getd2EdL2() {
228 return 0;
229 }
230
231 @Override
232 public double getdEdL() {
233 return energy;
234 }
235
236 @Override
237 public void getdEdXdL(double[] gradient) {
238 System.arraycopy(this.grad, 0, gradient, 0, gradient.length);
239 }
240
241 }