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-2024.
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.utils.PotentialTest;
44  import org.junit.Test;
45  
46  import java.io.File;
47  
48  import static org.apache.commons.math3.util.FastMath.floor;
49  import static org.apache.commons.math3.util.FastMath.random;
50  import static org.junit.Assert.assertEquals;
51  
52  /**
53   * Test the Energy script.
54   */
55  public class ParentEnergyTest extends PotentialTest {
56  
57    private final String info;
58    private final String filename;
59    private final String filepath;
60    private final int nAtoms;
61    private final int nBonds;
62    private final int nAngles;
63    private final int nStretchBends;
64    private final int nUreyBradleys;
65    private final int nOutOfPlaneBends;
66    private final int nTorsions;
67    private final int nImproperTorsions;
68    private final int nPiOrbitalTorsions;
69    private final int nTorsionTorsions;
70    private final int nStretchTorsions;
71    private final int nAngleTorsions;
72    private final int nVanDerWaals;
73    private final int nPermanent;
74    private final int nPolar;
75    private final int nGK;
76    private final double bondEnergy;
77    private final double angleEnergy;
78    private final double stretchBendEnergy;
79    private final double ureyBradleyEnergy;
80    private final double outOfPlaneBendEnergy;
81    private final double torsionEnergy;
82    private final double improperTorsionEnergy;
83    private final double piOrbitalTorsionEnergy;
84    private final double torsionTorsionEnergy;
85    private final double stretchTorsionEnergy;
86    private final double angleTorsionEnergy;
87    private final double vanDerWaalsEnergy;
88    private final double permanentEnergy;
89    private final double polarizationEnergy;
90    private final double gkEnergy;
91    private final double totalEnergy;
92    private final boolean testOpenMM;
93    private final double tolerance = 1.0e-2;
94  
95    public ParentEnergyTest(String info, String filename, int nAtoms, double bondEnergy, int nBonds,
96                            double angleEnergy, int nAngles, double stretchBendEnergy, int nStretchBends,
97                            double ureyBradleyEnergy, int nUreyBradleys, double outOfPlaneBendEnergy,
98                            int nOutOfPlaneBends, double torsionEnergy, int nTorsions, double improperTorsionEnergy,
99                            int nImproperTorsions, double piOrbitalTorsionEnergy, int nPiOrbitalTorsions,
100                           double torsionTorsionEnergy, int nTorsionTorsions, double stretchTorsionEnergy,
101                           int nStretchTorsions, double angleTorsionEnergy, int nAngleTorsions, double vanDerWaalsEnergy,
102                           int nVanDerWaals, double permanentEnergy, int nPermanent, double polarizationEnergy,
103                           int nPolar, double gkEnergy, int nGK, boolean testOpenMM) {
104     this.filename = filename;
105     this.info = info;
106     this.nAtoms = nAtoms;
107     this.bondEnergy = bondEnergy;
108     this.nBonds = nBonds;
109     this.angleEnergy = angleEnergy;
110     this.nAngles = nAngles;
111     this.stretchBendEnergy = stretchBendEnergy;
112     this.nStretchBends = nStretchBends;
113     this.ureyBradleyEnergy = ureyBradleyEnergy;
114     this.nUreyBradleys = nUreyBradleys;
115     this.outOfPlaneBendEnergy = outOfPlaneBendEnergy;
116     this.nOutOfPlaneBends = nOutOfPlaneBends;
117     this.torsionEnergy = torsionEnergy;
118     this.nTorsions = nTorsions;
119     this.improperTorsionEnergy = improperTorsionEnergy;
120     this.nImproperTorsions = nImproperTorsions;
121     this.piOrbitalTorsionEnergy = piOrbitalTorsionEnergy;
122     this.nPiOrbitalTorsions = nPiOrbitalTorsions;
123     this.torsionTorsionEnergy = torsionTorsionEnergy;
124     this.nTorsionTorsions = nTorsionTorsions;
125     this.stretchTorsionEnergy = stretchTorsionEnergy;
126     this.nStretchTorsions = nStretchTorsions;
127     this.angleTorsionEnergy = angleTorsionEnergy;
128     this.nAngleTorsions = nAngleTorsions;
129     this.vanDerWaalsEnergy = vanDerWaalsEnergy;
130     this.nVanDerWaals = nVanDerWaals;
131     this.permanentEnergy = permanentEnergy;
132     this.nPermanent = nPermanent;
133     this.polarizationEnergy = polarizationEnergy;
134     this.nPolar = nPolar;
135     this.gkEnergy = gkEnergy;
136     this.nGK = nGK;
137     this.testOpenMM = testOpenMM;
138 
139     filepath = getResourcePath(filename);
140     totalEnergy = bondEnergy + angleEnergy + stretchBendEnergy + ureyBradleyEnergy + outOfPlaneBendEnergy
141         + torsionEnergy + improperTorsionEnergy + piOrbitalTorsionEnergy + torsionTorsionEnergy + stretchTorsionEnergy
142         + angleTorsionEnergy + vanDerWaalsEnergy + permanentEnergy + polarizationEnergy + gkEnergy;
143   }
144 
145   @Test
146   public void testEnergy() {
147     if (nAtoms > 10000 && !ffxCI) {
148       return;
149     }
150     logger.info(" Testing energy for " + info);
151     String[] args = {filepath};
152     binding.setVariable("args", args);
153 
154     // Create and evaluate the script.
155     Energy energy = new Energy(binding).run();
156     potentialScript = energy;
157     ForceFieldEnergy forceFieldEnergy = energy.forceFieldEnergy;
158 
159     // Bond Energy
160     assertEquals(info + " Bond Energy", bondEnergy, forceFieldEnergy.getBondEnergy(), tolerance);
161     assertEquals(info + " Bond Count", nBonds, forceFieldEnergy.getNumberofBonds());
162     // Angle Energy
163     assertEquals(info + " Angle Energy", angleEnergy, forceFieldEnergy.getAngleEnergy(), tolerance);
164     assertEquals(info + " Angle Count", nAngles, forceFieldEnergy.getNumberofAngles());
165     // Stretch-Bend Energy
166     assertEquals(info + " Stretch-Bend Energy", stretchBendEnergy, forceFieldEnergy.getStrenchBendEnergy(), tolerance);
167     assertEquals(info + " Stretch-Bend Count", nStretchBends, forceFieldEnergy.getNumberofStretchBends());
168     // Urey-Bradley Energy
169     assertEquals(info + " Urey-Bradley Energy", ureyBradleyEnergy, forceFieldEnergy.getUreyBradleyEnergy(), tolerance);
170     assertEquals(info + " Urey-Bradley Count", nUreyBradleys, forceFieldEnergy.getNumberofUreyBradleys());
171     // Out-of-Plane Bend
172     assertEquals(info + " Out-of-Plane Bend Energy", outOfPlaneBendEnergy, forceFieldEnergy.getOutOfPlaneBendEnergy(), tolerance);
173     assertEquals(info + " Out-of-Plane Bend Count", nOutOfPlaneBends, forceFieldEnergy.getNumberofOutOfPlaneBends());
174     // Torsional Angle
175     assertEquals(info + " Torsion Energy", torsionEnergy, forceFieldEnergy.getTorsionEnergy(), tolerance);
176     assertEquals(info + " Torsion Count", nTorsions, forceFieldEnergy.getNumberofTorsions());
177     // Improper Torsional Angle
178     assertEquals(info + " Improper Torsion Energy", improperTorsionEnergy, forceFieldEnergy.getImproperTorsionEnergy(), tolerance);
179     assertEquals(info + " Improper Torsion Count", nImproperTorsions, forceFieldEnergy.getNumberofImproperTorsions());
180     // Pi-Orbital Torsion
181     assertEquals(info + " Pi-OrbitalTorsion Energy", piOrbitalTorsionEnergy, forceFieldEnergy.getPiOrbitalTorsionEnergy(), tolerance);
182     assertEquals(info + " Pi-OrbitalTorsion Count", nPiOrbitalTorsions, forceFieldEnergy.getNumberofPiOrbitalTorsions());
183     // Torsion-Torsion
184     assertEquals(info + " Torsion-Torsion Energy", torsionTorsionEnergy, forceFieldEnergy.getTorsionTorsionEnergy(), tolerance);
185     assertEquals(info + " Torsion-Torsion Count", nTorsionTorsions, forceFieldEnergy.getNumberofTorsionTorsions());
186     // Stretch-Torsion
187     assertEquals(info + " Stretch-Torsion Energy", stretchTorsionEnergy, forceFieldEnergy.getStretchTorsionEnergy(), tolerance);
188     assertEquals(info + " Stretch-Torsion Count", nStretchTorsions, forceFieldEnergy.getNumberofStretchTorsions());
189     // Angle-Torsion
190     assertEquals(info + " Angle-Torsion Energy", angleTorsionEnergy, forceFieldEnergy.getAngleTorsionEnergy(), tolerance);
191     assertEquals(info + " Angle-Torsion Count", nAngleTorsions, forceFieldEnergy.getNumberofAngleTorsions());
192     // van Der Waals
193     assertEquals(info + " van Der Waals Energy", vanDerWaalsEnergy, forceFieldEnergy.getVanDerWaalsEnergy(), tolerance);
194     assertEquals(info + " van Der Waals Count", nVanDerWaals, forceFieldEnergy.getVanDerWaalsInteractions());
195     // Permanent Multipoles
196     assertEquals(info + " Permanent Multipole Energy", permanentEnergy, forceFieldEnergy.getPermanentMultipoleEnergy(), tolerance);
197     assertEquals(info + " Permanent Multipole Count", nPermanent, forceFieldEnergy.getPermanentInteractions());
198     // Polarization Energy
199     assertEquals(info + " Polarization Energy", polarizationEnergy, forceFieldEnergy.getPolarizationEnergy(), tolerance);
200     assertEquals(info + " Polarization Count", nPolar, forceFieldEnergy.getPermanentInteractions());
201     // GK Energy
202     assertEquals(info + " Solvation", gkEnergy, forceFieldEnergy.getSolvationEnergy(), tolerance);
203     assertEquals(info + " Solvation Count", nGK, forceFieldEnergy.getSolvationInteractions());
204   }
205 
206   @Test
207   public void testGradient() {
208     if (!ffxCI) {
209       if (nAtoms > 5000) {
210         return;
211       } else if (nGK > 0 && nAtoms > 500) {
212         return;
213       }
214     }
215 
216 
217     logger.info(" Testing Cartesian gradient(s) for " + info);
218 
219     // Set up the input arguments for the Gradient script.
220     // Choose a random atom to test.
221     int atomID = (int) floor(random() * nAtoms) + 1;
222     double stepSize = 1.0e-5;
223     String[] args = {"--ga", Integer.toString(atomID),
224         "--dx", Double.toString(stepSize),
225         "--tol", Double.toString(tolerance),
226         filepath};
227     binding.setVariable("args", args);
228 
229     // Create and evaluate the script.
230     Gradient gradient = new Gradient(binding).run();
231     potentialScript = gradient;
232     assertEquals(info + " gradient failures: ", 0, gradient.nFailures);
233   }
234 
235   @Test
236   public void testLambdaGradient() {
237     if (!ffxCI) {
238       if (nAtoms > 5000) {
239         return;
240       } else if (nGK > 0 && nAtoms > 500) {
241         return;
242       }
243     }
244 
245     logger.info(" Testing lambda gradient(s) for " + info);
246 
247     // Set up the input arguments for the Lambda Gradient script.
248     // Choose a random atom to test dEdX gradient.
249     int atomID = (int) floor(random() * nAtoms) + 1;
250     double stepSize = 1.0e-5;
251     String[] args = {"--ga", Integer.toString(atomID),
252         "--dx", Double.toString(stepSize),
253         "--tol", Double.toString(tolerance),
254         "--ac", "ALL",
255         "-l", "0.9",
256         filepath};
257     binding.setVariable("args", args);
258 
259     // Create and evaluate the script.
260     LambdaGradient lambdaGradient = new LambdaGradient(binding).run();
261     potentialScript = lambdaGradient;
262     assertEquals(info + " dEdL failures: ", 0, lambdaGradient.ndEdLFailures);
263     assertEquals(info + " d2EdL2 failures: ", 0, lambdaGradient.nd2EdL2Failures);
264     assertEquals(info + " dEdXdL failures: ", 0, lambdaGradient.ndEdXdLFailures);
265     assertEquals(info + " dEdX failures: ", 0, lambdaGradient.ndEdXFailures);
266   }
267 
268   @Test
269   public void testOpenMMEnergy() {
270     if (!testOpenMM || !ffxOpenMM) {
271       return;
272     }
273     logger.info(" Testing OpenMM energy for " + info);
274 
275     // Set up the input arguments for the Energy script.
276     String[] args = {filepath};
277     binding.setVariable("args", args);
278     System.setProperty("platform", "OMM");
279 
280     // Construct and evaluate the script.
281     Energy energy = new Energy(binding).run();
282     potentialScript = energy;
283     double openMMTolerance = 0.5;
284     assertEquals(info + " OpenMM Energy", totalEnergy, energy.energy, openMMTolerance);
285   }
286 }