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.groovy;
39  
40  import ffx.potential.ForceFieldEnergy;
41  import ffx.potential.groovy.test.Gradient;
42  import ffx.potential.groovy.test.LambdaGradient;
43  import ffx.potential.terms.AnglePotentialEnergy;
44  import ffx.potential.terms.AngleTorsionPotentialEnergy;
45  import ffx.potential.terms.BondPotentialEnergy;
46  import ffx.potential.terms.ImproperTorsionPotentialEnergy;
47  import ffx.potential.terms.OutOfPlaneBendPotentialEnergy;
48  import ffx.potential.terms.PiOrbitalTorsionPotentialEnergy;
49  import ffx.potential.terms.StretchBendPotentialEnergy;
50  import ffx.potential.terms.StretchTorsionPotentialEnergy;
51  import ffx.potential.terms.TorsionPotentialEnergy;
52  import ffx.potential.terms.TorsionTorsionPotentialEnergy;
53  import ffx.potential.terms.UreyBradleyPotentialEnergy;
54  import ffx.potential.utils.PotentialTest;
55  import org.junit.Test;
56  
57  import static org.apache.commons.math3.util.FastMath.floor;
58  import static org.apache.commons.math3.util.FastMath.random;
59  import static org.junit.Assert.assertEquals;
60  
61  /**
62   * Test the Energy script.
63   */
64  public class ParentEnergyTest extends PotentialTest {
65  
66    private final String info;
67    private final String filepath;
68    private final int nAtoms;
69    private final int nBonds;
70    private final int nAngles;
71    private final int nStretchBends;
72    private final int nUreyBradleys;
73    private final int nOutOfPlaneBends;
74    private final int nTorsions;
75    private final int nImproperTorsions;
76    private final int nPiOrbitalTorsions;
77    private final int nTorsionTorsions;
78    private final int nStretchTorsions;
79    private final int nAngleTorsions;
80    private final int nVanDerWaals;
81    private final int nPermanent;
82    private final int nPolar;
83    private final int nGK;
84    private final double bondEnergy;
85    private final double angleEnergy;
86    private final double stretchBendEnergy;
87    private final double ureyBradleyEnergy;
88    private final double outOfPlaneBendEnergy;
89    private final double torsionEnergy;
90    private final double improperTorsionEnergy;
91    private final double piOrbitalTorsionEnergy;
92    private final double torsionTorsionEnergy;
93    private final double stretchTorsionEnergy;
94    private final double angleTorsionEnergy;
95    private final double vanDerWaalsEnergy;
96    private final double permanentEnergy;
97    private final double polarizationEnergy;
98    private final double gkEnergy;
99    private final double totalEnergy;
100   private final boolean testOpenMM;
101   private final double tolerance = 1.0e-2;
102 
103   public ParentEnergyTest(String info, String filename, int nAtoms, double bondEnergy, int nBonds,
104                           double angleEnergy, int nAngles, double stretchBendEnergy, int nStretchBends,
105                           double ureyBradleyEnergy, int nUreyBradleys, double outOfPlaneBendEnergy,
106                           int nOutOfPlaneBends, double torsionEnergy, int nTorsions, double improperTorsionEnergy,
107                           int nImproperTorsions, double piOrbitalTorsionEnergy, int nPiOrbitalTorsions,
108                           double torsionTorsionEnergy, int nTorsionTorsions, double stretchTorsionEnergy,
109                           int nStretchTorsions, double angleTorsionEnergy, int nAngleTorsions, double vanDerWaalsEnergy,
110                           int nVanDerWaals, double permanentEnergy, int nPermanent, double polarizationEnergy,
111                           int nPolar, double gkEnergy, int nGK, boolean testOpenMM) {
112     this.info = info;
113     this.nAtoms = nAtoms;
114     this.bondEnergy = bondEnergy;
115     this.nBonds = nBonds;
116     this.angleEnergy = angleEnergy;
117     this.nAngles = nAngles;
118     this.stretchBendEnergy = stretchBendEnergy;
119     this.nStretchBends = nStretchBends;
120     this.ureyBradleyEnergy = ureyBradleyEnergy;
121     this.nUreyBradleys = nUreyBradleys;
122     this.outOfPlaneBendEnergy = outOfPlaneBendEnergy;
123     this.nOutOfPlaneBends = nOutOfPlaneBends;
124     this.torsionEnergy = torsionEnergy;
125     this.nTorsions = nTorsions;
126     this.improperTorsionEnergy = improperTorsionEnergy;
127     this.nImproperTorsions = nImproperTorsions;
128     this.piOrbitalTorsionEnergy = piOrbitalTorsionEnergy;
129     this.nPiOrbitalTorsions = nPiOrbitalTorsions;
130     this.torsionTorsionEnergy = torsionTorsionEnergy;
131     this.nTorsionTorsions = nTorsionTorsions;
132     this.stretchTorsionEnergy = stretchTorsionEnergy;
133     this.nStretchTorsions = nStretchTorsions;
134     this.angleTorsionEnergy = angleTorsionEnergy;
135     this.nAngleTorsions = nAngleTorsions;
136     this.vanDerWaalsEnergy = vanDerWaalsEnergy;
137     this.nVanDerWaals = nVanDerWaals;
138     this.permanentEnergy = permanentEnergy;
139     this.nPermanent = nPermanent;
140     this.polarizationEnergy = polarizationEnergy;
141     this.nPolar = nPolar;
142     this.gkEnergy = gkEnergy;
143     this.nGK = nGK;
144     this.testOpenMM = testOpenMM;
145 
146     filepath = getResourcePath(filename);
147     totalEnergy = bondEnergy + angleEnergy + stretchBendEnergy + ureyBradleyEnergy + outOfPlaneBendEnergy
148         + torsionEnergy + improperTorsionEnergy + piOrbitalTorsionEnergy + torsionTorsionEnergy + stretchTorsionEnergy
149         + angleTorsionEnergy + vanDerWaalsEnergy + permanentEnergy + polarizationEnergy + gkEnergy;
150   }
151 
152   @Test
153   public void testEnergy() {
154     if (nAtoms > 10000 && !ffxCI) {
155       return;
156     }
157     logger.info(" Testing energy for " + info);
158     String[] args = {filepath};
159     binding.setVariable("args", args);
160 
161     // Create and evaluate the script.
162     Energy energy = new Energy(binding).run();
163     potentialScript = energy;
164     ForceFieldEnergy forceFieldEnergy = energy.getForceFieldEnergy();
165 
166     // Bond Energy
167     BondPotentialEnergy bondPotentialEnergy = forceFieldEnergy.getBondPotentialEnergy();
168     if (bondPotentialEnergy != null) {
169       assertEquals(info + " Bond Energy", bondEnergy, bondPotentialEnergy.getEnergy(), tolerance);
170       assertEquals(info + " Bond Count", nBonds, bondPotentialEnergy.getNumberOfBonds());
171     }
172     // Angle Energy
173     AnglePotentialEnergy anglePotentialEnergy = forceFieldEnergy.getAnglePotentialEnergy();
174     if (anglePotentialEnergy != null) {
175       assertEquals(info + " Angle Energy", angleEnergy, anglePotentialEnergy.getEnergy(), tolerance);
176       assertEquals(info + " Angle Count", nAngles, anglePotentialEnergy.getNumberOfAngles());
177     }
178     // Stretch-Bend Energy
179     StretchBendPotentialEnergy stretchBendPotentialEnergy = forceFieldEnergy.getStretchBendPotentialEnergy();
180     if (stretchBendPotentialEnergy != null) {
181       assertEquals(info + " Stretch-Bend Energy", stretchBendEnergy, stretchBendPotentialEnergy.getEnergy(), tolerance);
182       assertEquals(info + " Stretch-Bend Count", nStretchBends, stretchBendPotentialEnergy.getNumberOfStretchBends());
183     }
184     // Urey-Bradley Energy
185     UreyBradleyPotentialEnergy ureyBradleyPotentialEnergy = forceFieldEnergy.getUreyBradleyPotentialEnergy();
186     if (ureyBradleyPotentialEnergy != null) {
187       assertEquals(info + " Urey-Bradley Energy", ureyBradleyEnergy, ureyBradleyPotentialEnergy.getEnergy(), tolerance);
188       assertEquals(info + " Urey-Bradley Count", nUreyBradleys, ureyBradleyPotentialEnergy.getNumberOfUreyBradleys());
189     }
190     // Out-of-Plane Bend
191     OutOfPlaneBendPotentialEnergy outOfPlaneBendPotentialEnergy = forceFieldEnergy.getOutOfPlaneBendPotentialEnergy();
192     if (outOfPlaneBendPotentialEnergy != null) {
193       assertEquals(info + " Out-of-Plane Bend Energy", outOfPlaneBendEnergy, outOfPlaneBendPotentialEnergy.getEnergy(), tolerance);
194       assertEquals(info + " Out-of-Plane Bend Count", nOutOfPlaneBends, outOfPlaneBendPotentialEnergy.getNumberOfOutOfPlaneBends());
195     }
196     // Torsional Angle
197     TorsionPotentialEnergy torsionPotentialEnergy = forceFieldEnergy.getTorsionPotentialEnergy();
198     if (torsionPotentialEnergy != null) {
199       assertEquals(info + " Torsion Energy", torsionEnergy, torsionPotentialEnergy.getEnergy(), tolerance);
200       assertEquals(info + " Torsion Count", nTorsions, torsionPotentialEnergy.getNumberOfTorsions());
201     }
202     // Improper Torsional Angle
203     ImproperTorsionPotentialEnergy improperTorsionPotentialEnergy = forceFieldEnergy.getImproperTorsionPotentialEnergy();
204     if (improperTorsionPotentialEnergy != null) {
205       assertEquals(info + " Improper Torsion Energy", improperTorsionEnergy, improperTorsionPotentialEnergy.getEnergy(), tolerance);
206       assertEquals(info + " Improper Torsion Count", nImproperTorsions, improperTorsionPotentialEnergy.getNumberOfImproperTorsions());
207     }
208     // Pi-Orbital Torsion
209     PiOrbitalTorsionPotentialEnergy piOrbitalTorsionPotentialEnergy = forceFieldEnergy.getPiOrbitalTorsionPotentialEnergy();
210     if (piOrbitalTorsionPotentialEnergy != null) {
211       assertEquals(info + " Pi-Orbital Torsion Energy", piOrbitalTorsionEnergy, piOrbitalTorsionPotentialEnergy.getEnergy(), tolerance);
212       assertEquals(info + " Pi-Orbital Torsion Count", nPiOrbitalTorsions, piOrbitalTorsionPotentialEnergy.getNumberOfPiOrbitalTorsions());
213     }
214     // Torsion-Torsion
215     TorsionTorsionPotentialEnergy torsionTorsionPotentialEnergy = forceFieldEnergy.getTorsionTorsionPotentialEnergy();
216     if (torsionTorsionPotentialEnergy != null) {
217       assertEquals(info + " Torsion-Torsion Energy", torsionTorsionEnergy, torsionTorsionPotentialEnergy.getEnergy(), tolerance);
218       assertEquals(info + " Torsion-Torsion Count", nTorsionTorsions, torsionTorsionPotentialEnergy.getNumberOfTorsionTorsions());
219     }
220     // Stretch-Torsion
221     StretchTorsionPotentialEnergy stretchTorsionPotentialEnergy = forceFieldEnergy.getStretchTorsionPotentialEnergy();
222     if (stretchTorsionPotentialEnergy != null) {
223       assertEquals(info + " Stretch-Torsion Energy", stretchTorsionEnergy, stretchTorsionPotentialEnergy.getEnergy(), tolerance);
224       assertEquals(info + " Stretch-Torsion Count", nStretchTorsions, stretchTorsionPotentialEnergy.getNumberOfStretchTorsions());
225     }
226     // Angle-Torsion
227     AngleTorsionPotentialEnergy angleTorsionPotentialEnergy = forceFieldEnergy.getAngleTorsionPotentialEnergy();
228     if (angleTorsionPotentialEnergy != null) {
229       assertEquals(info + " Angle-Torsion Energy", angleTorsionEnergy, angleTorsionPotentialEnergy.getEnergy(), tolerance);
230       assertEquals(info + " Angle-Torsion Count", nAngleTorsions, angleTorsionPotentialEnergy.getNumberOfAngleTorsions());
231     }
232     // van Der Waals
233     assertEquals(info + " van Der Waals Energy", vanDerWaalsEnergy, forceFieldEnergy.getVanDerWaalsEnergy(), tolerance);
234     assertEquals(info + " van Der Waals Count", nVanDerWaals, forceFieldEnergy.getVanDerWaalsInteractions());
235     // Permanent Multipoles
236     assertEquals(info + " Permanent Multipole Energy", permanentEnergy, forceFieldEnergy.getPermanentMultipoleEnergy(), tolerance);
237     assertEquals(info + " Permanent Multipole Count", nPermanent, forceFieldEnergy.getPermanentInteractions());
238     // Polarization Energy
239     assertEquals(info + " Polarization Energy", polarizationEnergy, forceFieldEnergy.getPolarizationEnergy(), tolerance);
240     assertEquals(info + " Polarization Count", nPolar, forceFieldEnergy.getPermanentInteractions());
241     // GK Energy
242     assertEquals(info + " Solvation", gkEnergy, forceFieldEnergy.getSolvationEnergy(), tolerance);
243     assertEquals(info + " Solvation Count", nGK, forceFieldEnergy.getSolvationInteractions());
244   }
245 
246   @Test
247   public void testGradient() {
248     if (!ffxCI) {
249       if (nAtoms > 5000) {
250         return;
251       } else if (nGK > 0 && nAtoms > 500) {
252         return;
253       }
254     }
255 
256 
257     logger.info(" Testing Cartesian gradient(s) for " + info);
258 
259     // Set up the input arguments for the Gradient script.
260     // Choose a random atom to test.
261     int atomID = (int) floor(random() * nAtoms) + 1;
262     double stepSize = 1.0e-5;
263     String[] args = {"--ga", Integer.toString(atomID),
264         "--dx", Double.toString(stepSize),
265         "--tol", Double.toString(tolerance),
266         filepath};
267     binding.setVariable("args", args);
268 
269     // Create and evaluate the script.
270     Gradient gradient = new Gradient(binding).run();
271     potentialScript = gradient;
272     assertEquals(info + " gradient failures: ", 0, gradient.nFailures);
273   }
274 
275   @Test
276   public void testLambdaGradient() {
277     if (!ffxCI) {
278       if (nAtoms > 5000) {
279         return;
280       } else if (nGK > 0 && nAtoms > 500) {
281         return;
282       }
283     }
284 
285     logger.info(" Testing lambda gradient(s) for " + info);
286 
287     // Set up the input arguments for the Lambda Gradient script.
288     // Choose a random atom to test dEdX gradient.
289     int atomID = (int) floor(random() * nAtoms) + 1;
290     double stepSize = 1.0e-5;
291     String[] args = {"--ga", Integer.toString(atomID),
292         "--dx", Double.toString(stepSize),
293         "--tol", Double.toString(tolerance),
294         "--ac", "ALL",
295         "-l", "0.9",
296         filepath};
297     binding.setVariable("args", args);
298 
299     // Create and evaluate the script.
300     LambdaGradient lambdaGradient = new LambdaGradient(binding).run();
301     potentialScript = lambdaGradient;
302     assertEquals(info + " dEdL failures: ", 0, lambdaGradient.ndEdLFailures);
303     assertEquals(info + " d2EdL2 failures: ", 0, lambdaGradient.nd2EdL2Failures);
304     assertEquals(info + " dEdXdL failures: ", 0, lambdaGradient.ndEdXdLFailures);
305     assertEquals(info + " dEdX failures: ", 0, lambdaGradient.ndEdXFailures);
306   }
307 
308   @Test
309   public void testOpenMMEnergy() {
310     if (!testOpenMM || !ffxOpenMM) {
311       return;
312     }
313     logger.info(" Testing OpenMM energy for " + info);
314 
315     // Set up the input arguments for the Energy script.
316     String[] args = {filepath};
317     binding.setVariable("args", args);
318     System.setProperty("platform", "OMM");
319 
320     // Construct and evaluate the script.
321     Energy energy = new Energy(binding).run();
322     potentialScript = energy;
323     double openMMTolerance = 0.5;
324     assertEquals(info + " OpenMM Energy", totalEnergy, energy.getEnergy(), openMMTolerance);
325   }
326 }