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.terms;
39  
40  import edu.rit.pj.reduction.SharedDouble;
41  import ffx.potential.bonded.BondedTerm;
42  
43  import java.util.logging.Logger;
44  
45  import static org.apache.commons.math3.util.FastMath.sqrt;
46  
47  /**
48   * Base class for potential energy terms used by ForceFieldEnergy.
49   * <p>
50   * This abstract class holds minimal, common metadata shared by energy terms:
51   * a human-readable name and an integer force-group identifier. Specific energy
52   * terms (bonded, nonbonded, restraints, etc.) should extend this class.
53   */
54  public abstract class EnergyTerm {
55  
56    private static final Logger logger = Logger.getLogger(EnergyTerm.class.getName());
57  
58    /**
59     * Optional name for this energy term (for reporting/logging).
60     */
61    protected String name;
62  
63    /**
64     * Integer force group this term belongs to. Defaults to 0.
65     */
66    protected int forceGroup = 0;
67  
68    /**
69     * Total potential energy for this term.
70     */
71    protected SharedDouble energy = new SharedDouble();
72  
73    /**
74     * Shared double for RMSD calculations.
75     */
76    private final SharedDouble sharedRMSD = new SharedDouble();
77  
78    /**
79     * The time taken to compute the energy for this term in nanoseconds.
80     */
81    private long computeTime = 0L;
82  
83    /**
84     * Create an unnamed EnergyTerm with default force group 0.
85     */
86    protected EnergyTerm() {
87    }
88  
89    /**
90     * Create a named EnergyTerm with default force group 0.
91     *
92     * @param name Name for this energy term.
93     */
94    protected EnergyTerm(String name) {
95      this.name = name;
96    }
97  
98    /**
99     * Create a named EnergyTerm with a specified force group.
100    *
101    * @param name       Name for this energy term.
102    * @param forceGroup Integer force group identifier.
103    */
104   protected EnergyTerm(String name, int forceGroup) {
105     this.name = name;
106     this.forceGroup = forceGroup;
107   }
108 
109   /**
110    * Get the number of BondedTerms in this term.
111    *
112    * @return The number of BondedTerms.
113    */
114   abstract public int getNumberOfTerms();
115 
116   /**
117    * Get an array of BondedTerms in this term.
118    *
119    * @return Array of BondedTerms.
120    */
121   abstract public BondedTerm[] getBondedTermsArray();
122 
123   /**
124    * Log the details of this energy term.
125    */
126   abstract public void log();
127 
128   /**
129    * Get a string representation of this energy term.
130    *
131    * @return A string representation of the energy term.
132    */
133   abstract public String toString();
134 
135   /**
136    * Get a PDB-style REMARK representation of this energy term.
137    * @return A PDB REMARK string for this energy term.
138    */
139   abstract public String toPDBString();
140 
141   /**
142    * Get the current force group identifier.
143    *
144    * @return force group as an int
145    */
146   public int getForceGroup() {
147     return forceGroup;
148   }
149 
150   /**
151    * Set the force group identifier.
152    *
153    * @param forceGroup integer force group
154    */
155   public void setForceGroup(int forceGroup) {
156     this.forceGroup = forceGroup;
157   }
158 
159   /**
160    * Get the name of this energy term.
161    *
162    * @return name (may be null)
163    */
164   public String getName() {
165     return name;
166   }
167 
168   /**
169    * Set the name of this energy term.
170    *
171    * @param name A human-readable name
172    */
173   public void setName(String name) {
174     this.name = name;
175   }
176 
177   /**
178    * Get the total potential energy of this term.
179    *
180    * @return Energy value as a double.
181    */
182   public double getEnergy() {
183     return energy.get();
184   }
185 
186   /**
187    * Set the total potential energy of this term.
188    *
189    * @param e Energy value to set.
190    */
191   protected void setEnergy(double e) {
192     energy.set(e);
193   }
194 
195   /**
196    * Add energy to the total energy for this term and return the new total.
197    *
198    * @param e Energy value to add to the total.
199    * @return The new total energy after adding the provided energy.
200    */
201   protected double addAndGetEnergy(double e) {
202     return energy.addAndGet(e);
203   }
204 
205   /**
206    * Set the RMSD accumulator value for this term.
207    *
208    * @param rmsd RMSD value to set for this term.
209    */
210   protected void setRMSD(double rmsd) {
211     sharedRMSD.set(rmsd);
212   }
213 
214   /**
215    * Get the RMSD for this term.
216    */
217   public double getRMSD() {
218     return sqrt(sharedRMSD.get() / getNumberOfTerms());
219   }
220 
221   /**
222    * Add RMSD to the shared RMSD and return the new total.
223    *
224    * @param rmsd RMSD value to add to the shared RMSD.
225    * @return The new total RMSD after adding the provided value.
226    */
227   protected double addAndGetRMSD(double rmsd) {
228     return sharedRMSD.addAndGet(rmsd);
229   }
230 
231   /**
232    * Set the starting time for the energy computation.
233    */
234   protected void startTime() {
235     computeTime = -System.nanoTime();
236   }
237 
238   /**
239    * Stop the timer for the energy computation.
240    */
241   public void stopTime() {
242     computeTime += System.nanoTime();
243   }
244 
245   /**
246    * Get the time taken to compute the energy for this term in seconds.
247    *
248    * @return The time in seconds.
249    */
250   public double getTime() {
251     return computeTime * 1.0e-9;
252   }
253 
254 
255 }