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.nonbonded;
39  
40  import edu.rit.pj.IntegerForLoop;
41  import edu.rit.pj.IntegerSchedule;
42  
43  import java.util.logging.Logger;
44  
45  /**
46   * Loop over a list of atoms and assign their density to a grid.
47   *
48   * @author Michael J. Schnieders
49   * @since 1.0
50   */
51  public abstract class SpatialDensityLoop extends IntegerForLoop {
52  
53    private static final Logger logger = Logger.getLogger(SpatialDensityLoop.class.getName());
54    private int nSymm;
55    private SpatialDensityRegion spatialDensityRegion;
56    private SpatialDensitySchedule spatialDensitySchedule;
57    private int octant = 0;
58  
59    /**
60     * Constructor for SpatialDensityLoop.
61     *
62     * @param region a {@link ffx.potential.nonbonded.SpatialDensityRegion} object.
63     * @param nSymm a int.
64     * @param atomsPerChunk an array of int.
65     */
66    public SpatialDensityLoop(SpatialDensityRegion region, int nSymm, int[] atomsPerChunk) {
67      this.spatialDensityRegion = region;
68      this.nSymm = nSymm;
69      this.spatialDensitySchedule =
70          new SpatialDensitySchedule(region.nThreads, region.nAtoms, atomsPerChunk, 0.97);
71      assert (nSymm <= region.nSymm);
72    }
73  
74    /**
75     * gridDensity
76     *
77     * @param iSymm a int.
78     * @param iAtom a int.
79     */
80    public abstract void gridDensity(int iSymm, int iAtom);
81  
82    /** {@inheritDoc} */
83    @Override
84    public void run(int lb, int ub) {
85      // Loop over work cells
86      for (int icell = lb; icell <= ub; icell++) {
87        int ia = spatialDensityRegion.actualA[icell];
88        int ib = spatialDensityRegion.actualB[icell];
89        int ic = spatialDensityRegion.actualC[icell];
90        switch (octant) {
91            // Case 0 -> In place.
92          case 0:
93            gridCell(ia, ib, ic);
94            break;
95            // Case 1: Step along the C-axis.
96          case 1:
97            gridCell(ia, ib, ic + 1);
98            break;
99            // Case 2 & 3: Step along the B-axis.
100         case 2:
101           gridCell(ia, ib + 1, ic);
102           break;
103         case 3:
104           gridCell(ia, ib + 1, ic + 1);
105           break;
106           // Case 4-7: Step along the A-axis.
107         case 4:
108           gridCell(ia + 1, ib, ic);
109           break;
110         case 5:
111           gridCell(ia + 1, ib, ic + 1);
112           break;
113         case 6:
114           gridCell(ia + 1, ib + 1, ic);
115           break;
116         case 7:
117           gridCell(ia + 1, ib + 1, ic + 1);
118           break;
119         default:
120           String message = "Programming error in PermanentDensityLoop.\n";
121           logger.severe(message);
122       }
123     }
124   }
125 
126   /** {@inheritDoc} */
127   @Override
128   public IntegerSchedule schedule() {
129     return spatialDensitySchedule;
130   }
131 
132   /**
133    * setNsymm
134    *
135    * @param nSymm a int.
136    */
137   public void setNsymm(int nSymm) {
138     this.nSymm = nSymm;
139     assert (nSymm <= spatialDensityRegion.nSymm);
140   }
141 
142   /**
143    * Setter for the field <code>octant</code>.
144    *
145    * @param octant a int.
146    * @return a {@link ffx.potential.nonbonded.SpatialDensityLoop} object.
147    */
148   public SpatialDensityLoop setOctant(int octant) {
149     this.octant = octant;
150     return this;
151   }
152 
153   /**
154    * setRegion.
155    *
156    * @param spatialDensityRegion a {@link ffx.potential.nonbonded.SpatialDensityRegion} object.
157    */
158   public void setRegion(SpatialDensityRegion spatialDensityRegion) {
159     this.spatialDensityRegion = spatialDensityRegion;
160     this.spatialDensitySchedule =
161         new SpatialDensitySchedule(
162             spatialDensityRegion.nThreads,
163             spatialDensityRegion.nAtoms,
164             spatialDensityRegion.actualCount,
165             0.97);
166   }
167 
168   private void gridCell(int ia, int ib, int ic) {
169     for (int iSymm = 0; iSymm < nSymm; iSymm++) {
170       final int[] pairList = spatialDensityRegion.cellList[iSymm];
171       final int index = spatialDensityRegion.index(ia, ib, ic);
172       final int start = spatialDensityRegion.cellStart[iSymm][index];
173       final int stop = start + spatialDensityRegion.cellCount[iSymm][index];
174       for (int i = start; i < stop; i++) {
175         int n = pairList[i];
176         gridDensity(iSymm, n);
177       }
178     }
179   }
180 }