View Javadoc
1   // ******************************************************************************
2   //
3   // Title:       Force Field X.
4   // Description: Force Field X - Software for Molecular Biophysics.
5   // Copyright:   Copyright (c) Michael J. Schnieders 2001-2025.
6   //
7   // This file is part of Force Field X.
8   //
9   // Force Field X is free software; you can redistribute it and/or modify it
10  // under the terms of the GNU General Public License version 3 as published by
11  // the Free Software Foundation.
12  //
13  // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16  // details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA 02111-1307 USA
21  //
22  // Linking this library statically or dynamically with other modules is making a
23  // combined work based on this library. Thus, the terms and conditions of the
24  // GNU General Public License cover the whole combination.
25  //
26  // As a special exception, the copyright holders of this library give you
27  // permission to link this library with independent modules to produce an
28  // executable, regardless of the license terms of these independent modules, and
29  // to copy and distribute the resulting executable under terms of your choice,
30  // provided that you also meet, for each linked independent module, the terms
31  // and conditions of the license of that module. An independent module is a
32  // module which is not derived from or based on this library. If you modify this
33  // library, you may extend this exception to your version of the library, but
34  // you are not obligated to do so. If you do not wish to do so, delete this
35  // exception statement from your version.
36  //
37  // ******************************************************************************
38  package ffx.potential.commands;
39  
40  import static org.apache.commons.math3.util.FastMath.floor;
41  import static org.apache.commons.math3.util.FastMath.random;
42  import static org.junit.Assert.assertEquals;
43  
44  import ffx.potential.ForceFieldEnergy;
45  import ffx.potential.commands.test.Gradient;
46  import ffx.potential.commands.test.LambdaGradient;
47  import ffx.potential.terms.AnglePotentialEnergy;
48  import ffx.potential.terms.BondPotentialEnergy;
49  import ffx.potential.terms.ImproperTorsionPotentialEnergy;
50  import ffx.potential.terms.TorsionPotentialEnergy;
51  import ffx.potential.utils.PotentialTest;
52  import java.util.Arrays;
53  import java.util.Collection;
54  import org.junit.Test;
55  import org.junit.runner.RunWith;
56  import org.junit.runners.Parameterized;
57  import org.junit.runners.Parameterized.Parameters;
58  
59  /** Test OPLS-AA energy and gradient. */
60  @RunWith(Parameterized.class)
61  public class OPLSAAEnergyTest extends PotentialTest {
62  
63    private final String info;
64    private final String filepath;
65    private final int nAtoms;
66    private final int nBonds;
67    private final int nAngles;
68    private final int nTorsions;
69    private final int nImproperTorsions;
70    private final int nVanDerWaals;
71    private final int nFixedCharge;
72    private final double bondEnergy;
73    private final double angleEnergy;
74    private final double torsionEnergy;
75    private final double improperTorsionEnergy;
76    private final double vanDerWaalsEnergy;
77    private final double fixedChargeEnergy;
78  
79    // The peptide coordinates under OPLS-AA and OPLS-AA/L result in a large gradient for some atoms,
80    // which necessitates a larger tolerance.
81    private final double tolerance = 1.0e-2;
82  
83    public OPLSAAEnergyTest(
84        String info,
85        String filename,
86        int nAtoms,
87        double bondEnergy,
88        int nBonds,
89        double angleEnergy,
90        int nAngles,
91        double torsionEnergy,
92        int nTorsions,
93        double improperTorsionEnergy,
94        int nImproperTorsions,
95        double vanDerWaalsEnergy,
96        int nVanDerWaals,
97        double fixedChargeEnergy,
98        int nFixedCharge) {
99  
100     this.info = info;
101     this.nAtoms = nAtoms;
102     this.bondEnergy = bondEnergy;
103     this.nBonds = nBonds;
104     this.angleEnergy = angleEnergy;
105     this.nAngles = nAngles;
106     this.torsionEnergy = torsionEnergy;
107     this.nTorsions = nTorsions;
108     this.improperTorsionEnergy = improperTorsionEnergy;
109     this.nImproperTorsions = nImproperTorsions;
110     this.vanDerWaalsEnergy = vanDerWaalsEnergy;
111     this.nVanDerWaals = nVanDerWaals;
112     this.fixedChargeEnergy = fixedChargeEnergy;
113     this.nFixedCharge = nFixedCharge;
114     this.filepath = getResourcePath(filename);
115   }
116 
117   @Parameters
118   public static Collection<Object[]> data() {
119     return Arrays.asList(
120         new Object[][] {
121             {
122                 "OPLS Acetanilide Benchmark",
123                 "acetanilide-oplsaa.xyz",
124                 19,
125                 0.45009773,
126                 19,
127                 1.99659439,
128                 30,
129                 3.12713717,
130                 38,
131                 0.03415131,
132                 12,
133                 -10.22874283,
134                 7293,
135                 -24.11087720,
136                 2229
137             },
138             {
139                 "OPLS-AA Peptide",
140                 "peptide-oplsaa.xyz",
141                 328,
142                 72.08575480,
143                 333,
144                 32.38121260,
145                 596,
146                 65.56283245,
147                 875,
148                 0.85331537,
149                 186,
150                 91224.14951970,
151                 40511,
152                 -665.41688158,
153                 52699
154             },
155             {
156                 "OPLS-AA/L Peptide",
157                 "peptide-oplsaal.xyz",
158                 328,
159                 39.69175722,
160                 333,
161                 41.54908436,
162                 596,
163                 41.53603210,
164                 875,
165                 0.92410847,
166                 97,
167                 112122.04255274,
168                 40511,
169                 -671.66812023,
170                 52699,
171             },
172             {
173                 "OPLS Ethylparaben Benchmark",
174                 "ethylparaben-oplsaa.xyz",
175                 44,
176                 1.23483793,
177                 44,
178                 1.17950432,
179                 70,
180                 0.58946840,
181                 88,
182                 0.01347012,
183                 22,
184                 -23.22505628,
185                 16759,
186                 -28.45972542,
187                 5029
188             },
189             {
190                 "OPLS Methylparaben Benchmark",
191                 "methylparaben-oplsaa.xyz",
192                 19,
193                 0.48582171,
194                 19,
195                 0.47331501,
196                 29,
197                 0.53855046,
198                 35,
199                 0.02598434,
200                 11,
201                 -8.71533364,
202                 7647,
203                 -16.384524645738537,
204                 2302
205             },
206             {
207                 "OPLS Paracetamol Benchmark",
208                 "paracetamol-oplsaa.xyz",
209                 20,
210                 0.63722563,
211                 20,
212                 2.63545869,
213                 31,
214                 3.01547224,
215                 40,
216                 0.06569712,
217                 10,
218                 -9.45895598,
219                 7831,
220                 -41.34298872,
221                 3334
222             },
223             {
224                 "OPLS Phenacetin Benchmark",
225                 "phenacetin-oplsaa.xyz",
226                 26,
227                 0.53495810,
228                 26,
229                 3.68523677,
230                 43,
231                 4.12682233,
232                 52,
233                 0.03932507,
234                 10,
235                 -14.31979877,
236                 10338,
237                 -31.561832525438113,
238                 3116
239             }
240         });
241   }
242 
243   @Test
244   public void testEnergy() {
245     logger.info(" Testing energy for " + info);
246 
247     // Set-up the input arguments for the Energy script.
248     String[] args = {filepath};
249     binding.setVariable("args", args);
250 
251     // Evaluate the script.
252     Energy energy = new Energy(binding).run();
253     potentialScript = energy;
254 
255     ForceFieldEnergy forceFieldEnergy = energy.getForceFieldEnergy();
256 
257     // Bond Energy
258     BondPotentialEnergy bondPotentialEnergy = forceFieldEnergy.getBondPotentialEnergy();
259     if (bondPotentialEnergy != null) {
260       assertEquals(info + " Bond Energy", bondEnergy, bondPotentialEnergy.getEnergy(), tolerance);
261       assertEquals(info + " Bond Count", nBonds, bondPotentialEnergy.getNumberOfBonds());
262     }
263     // Angle Energy
264     AnglePotentialEnergy anglePotentialEnergy = forceFieldEnergy.getAnglePotentialEnergy();
265     if (anglePotentialEnergy != null) {
266       assertEquals(info + " Angle Energy", angleEnergy, anglePotentialEnergy.getEnergy(), tolerance);
267       assertEquals(info + " Angle Count", nAngles, anglePotentialEnergy.getNumberOfAngles());
268     }
269     // Torsional Angle
270     TorsionPotentialEnergy torsionPotentialEnergy = forceFieldEnergy.getTorsionPotentialEnergy();
271     if (torsionPotentialEnergy != null) {
272       assertEquals(info + " Torsion Energy", torsionEnergy, torsionPotentialEnergy.getEnergy(), tolerance);
273       assertEquals(info + " Torsion Count", nTorsions, torsionPotentialEnergy.getNumberOfTorsions());
274     }
275     // Improper Torsional Angle
276     ImproperTorsionPotentialEnergy improperTorsionPotentialEnergy = forceFieldEnergy.getImproperTorsionPotentialEnergy();
277     if (improperTorsionPotentialEnergy != null) {
278       assertEquals(info + " Improper Torsion Energy", improperTorsionEnergy, improperTorsionPotentialEnergy.getEnergy(), tolerance);
279       assertEquals(info + " Improper Torsion Count", nImproperTorsions, improperTorsionPotentialEnergy.getNumberOfImproperTorsions());
280     }
281     // van Der Waals
282     assertEquals(info + " van Der Waals Energy", vanDerWaalsEnergy, forceFieldEnergy.getVanDerWaalsEnergy(), tolerance);
283     assertEquals(info + " van Der Waals Count", nVanDerWaals, forceFieldEnergy.getVanDerWaalsInteractions());
284     // Permanent Multipoles
285     assertEquals(info + " Fixed Charge Energy", fixedChargeEnergy, forceFieldEnergy.getPermanentMultipoleEnergy(), tolerance);
286     assertEquals(info + " Fixed Charge Count", nFixedCharge, forceFieldEnergy.getPermanentInteractions());
287   }
288 
289   @Test
290   public void testGradient() {
291     logger.info(" Testing Cartesian gradient(s) for " + info);
292 
293     // Set-up the input arguments for the Gradient script.
294     // Choose a random atom to test.
295     int atomID = (int) floor(random() * nAtoms) + 1;
296     double stepSize = 1.0e-5;
297     String[] args = {
298         "--ga", Integer.toString(atomID),
299         "--tol", Double.toString(tolerance),
300         "--dx", Double.toString(stepSize),
301         filepath
302     };
303     binding.setVariable("args", args);
304 
305     // Construct and evaluate the script.
306     Gradient gradient = new Gradient(binding).run();
307     potentialScript = gradient;
308 
309     assertEquals(info + " gradient failures: ", 0, gradient.nFailures);
310   }
311 
312   @Test
313   public void testLambdaGradient() {
314     logger.info(" Testing lambda gradient(s) for " + info);
315 
316     // Set-up the input arguments for the LambdaGradient script.
317     // Choose a random atom to test dEdX gradient.
318     int atomID = (int) floor(random() * nAtoms) + 1;
319     double stepSize = 1.0e-5;
320     String[] args = {
321         "--ga", Integer.toString(atomID),
322         "--dx", Double.toString(stepSize),
323         "--tol", Double.toString(tolerance),
324         "--ac", "ALL",
325         "-l", "0.5",
326         filepath
327     };
328     binding.setVariable("args", args);
329 
330     // Construct and evaluate the script.
331     LambdaGradient lambdaGradient = new LambdaGradient(binding).run();
332     potentialScript = lambdaGradient;
333 
334     assertEquals(info + " dEdL failures: ", 0, lambdaGradient.ndEdLFailures);
335     assertEquals(info + " d2EdL2 failures: ", 0, lambdaGradient.nd2EdL2Failures);
336     assertEquals(info + " dEdXdL failures: ", 0, lambdaGradient.ndEdXdLFailures);
337     assertEquals(info + " dEdX failures: ", 0, lambdaGradient.ndEdXFailures);
338   }
339 }